netreconlab / Parse-Swift

The original (OG) Swift SDK for Parse Platform (iOS, macOS, watchOS, tvOS, visionOS, Linux, Android, Windows). This repo is maintained by Parse-Swift's original developer and all new features and bug fixes will occur here.
https://swiftpackageindex.com/netreconlab/Parse-Swift/documentation
Apache License 2.0
62 stars 7 forks source link

feat: Add loginAs method to impersonate users #79

Closed cbaker6 closed 1 year ago

cbaker6 commented 1 year ago

New Pull Request Checklist

Issue Description

The Swift SDK currently doesn't support the server loginAs endpoint to allow impersonating a user.

Approach

/**
     Logs in a `ParseUser` *asynchronously* with a given `objectId` allowing the impersonation of a User.
     On success, this saves the logged in `ParseUser`with this session to the keychain, so you can retrieve
     the currently logged in user using *current*.

     - parameter objectId: The objectId of the user to login.
     - parameter options: A set of header options sent to the server. Defaults to an empty set.
     - parameter callbackQueue: The queue to return to after completion. Default
     value of .main.
     - parameter completion: The block to execute when completed.
     It should have the following argument signature: `(Result<Self, ParseError>)`.
     - important: The Parse Keychain currently only supports one(1) user at a time. This means
     if you use `loginAs()`, the current logged in user will be replaced. If you would like to revert
     back to the previous user, you should capture the `sesionToken` of the previous user before
     calling `loginAs()`. When you are ready to revert, 1) `logout()`, then `become()` with
     the sessionToken.
     - note: Calling this endpoint does not invoke session triggers such as beforeLogin and
     afterLogin. This action will always succeed if the supplied user exists in the database, regardless
     of whether the user is currently locked out.
     - note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
     desires a different policy, it should be inserted in `options`.
     - requires: `.usePrimaryKey` has to be available. It is recommended to only
     use the primary key in server-side applications where the key is kept secure and not
     exposed to the public.
    */
    public static func loginAs(objectId: String,
                               options: API.Options = [],
                               callbackQueue: DispatchQueue = .main,
                               completion: @escaping (Result<Self, ParseError>) -> Void)

/**
     Logs in a `ParseUser` *asynchronously* with a given `objectId` allowing the impersonation of a User.
     On success, this saves the logged in `ParseUser`with this session to the keychain, so you can retrieve
     the currently logged in user using *current*.

     - parameter objectId: The objectId of the user to login.
     - parameter options: A set of header options sent to the server. Defaults to an empty set.
     - returns: Returns the logged in `ParseUser`.
     - throws: An error of type `ParseError`.
     - important: The Parse Keychain currently only supports one(1) user at a time. This means
     if you use `loginAs()`, the current logged in user will be replaced. If you would like to revert
     back to the previous user, you should capture the `sesionToken` of the previous user before
     calling `loginAs()`. When you are ready to revert, 1) `logout()`, then `become()` with
     the sessionToken.
     - note: Calling this endpoint does not invoke session triggers such as beforeLogin and
     afterLogin. This action will always succeed if the supplied user exists in the database, regardless
     of whether the user is currently locked out.
     - note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
     desires a different policy, it should be inserted in `options`.
     - requires: `.usePrimaryKey` has to be available. It is recommended to only
     use the primary key in server-side applications where the key is kept secure and not
     exposed to the public.
    */
    @discardableResult static func loginAs(objectId: String,
                                           options: API.Options = []) async throws -> Self

/**
     Logs in a `ParseUser` *asynchronously* with a given `objectId` allowing the impersonation of a User.
     On success, this saves the logged in `ParseUser`with this session to the keychain, so you can retrieve
     the currently logged in user using *current*.

     - parameter objectId: The objectId of the user to login.
     - parameter options: A set of header options sent to the server. Defaults to an empty set.
     - returns: A publisher that eventually produces a single value and then finishes or fails.
     - important: The Parse Keychain currently only supports one(1) user at a time. This means
     if you use `loginAs()`, the current logged in user will be replaced. If you would like to revert
     back to the previous user, you should capture the `sesionToken` of the previous user before
     calling `loginAs()`. When you are ready to revert, 1) `logout()`, then `become()` with
     the sessionToken.
     - note: Calling this endpoint does not invoke session triggers such as beforeLogin and
     afterLogin. This action will always succeed if the supplied user exists in the database, regardless
     of whether the user is currently locked out.
     - note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
     desires a different policy, it should be inserted in `options`.
     - requires: `.usePrimaryKey` has to be available. It is recommended to only
     use the primary key in server-side applications where the key is kept secure and not
     exposed to the public.
    */
    static func loginAsPublisher(objectId: String,
                                 options: API.Options = []) -> Future<Self, ParseError>

TODOs before merging

codecov[bot] commented 1 year ago

Codecov Report

Merging #79 (267e055) into main (b373225) will increase coverage by 0.02%. The diff coverage is 97.07%.

@@            Coverage Diff             @@
##             main      #79      +/-   ##
==========================================
+ Coverage   90.53%   90.55%   +0.02%     
==========================================
  Files         169      169              
  Lines       15052    15101      +49     
==========================================
+ Hits        13627    13675      +48     
- Misses       1425     1426       +1     
Impacted Files Coverage Δ
Sources/ParseSwift/Objects/ParseUser.swift 91.03% <92.30%> (+0.24%) :arrow_up:
Sources/ParseSwift/API/API+Command+async.swift 100.00% <100.00%> (ø)
...ParseSwift/API/API+NonParseBodyCommand+async.swift 100.00% <100.00%> (ø)
Sources/ParseSwift/API/API.swift 99.41% <100.00%> (+<0.01%) :arrow_up:
Sources/ParseSwift/Objects/ParseInstallation.swift 88.31% <100.00%> (ø)
Sources/ParseSwift/Objects/ParseObject.swift 90.95% <100.00%> (ø)
Sources/ParseSwift/Objects/ParseUser+async.swift 94.40% <100.00%> (+0.11%) :arrow_up:
Sources/ParseSwift/Objects/ParseUser+combine.swift 96.05% <100.00%> (+0.13%) :arrow_up:
Sources/ParseSwift/Protocols/ParseCloudable.swift 100.00% <100.00%> (ø)
Sources/ParseSwift/Protocols/ParseConfig.swift 100.00% <100.00%> (ø)
... and 10 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.