source/UberCore/Authentication/Tokens/TokenManager.swift (65 lines of code) (raw):
//
// TokenManager.swift
// UberRides
//
// Copyright © 2015 Uber Technologies, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation
/// Manager class for saving and deleting AccessTokens. Allows you to manage tokens based on token identifier & keychain access group
@objc(UBSDKTokenManager) public class TokenManager: NSObject {
@objc public static let tokenManagerDidSaveTokenNotification = "TokenManagerDidSaveTokenNotification"
@objc public static let tokenManagerDidDeleteTokenNotification = "TokenManagerDidDeleteTokenNotification"
private static let keychainWrapper = KeychainWrapper()
//MARK: Get
/**
Gets the AccessToken for the given tokenIdentifier and accessGroup.
- parameter identifier: The token identifier string to use
- parameter accessGroup: The keychain access group to use
- returns: An AccessToken, or nil if one wasn't found
*/
@objc public static func fetchToken(identifier: String, accessGroup: String) -> AccessToken? {
keychainWrapper.setAccessGroup(accessGroup)
guard let token = keychainWrapper.getObjectForKey(identifier) as? AccessToken else {
return nil
}
return token
}
/**
Gets the AccessToken for the given tokenIdentifier.
Uses the default value for keychain access group, as defined by your Configuration.
- parameter tokenIdentifier: The token identifier string to use
- returns: An AccessToken, or nil if one wasn't found
*/
@objc public static func fetchToken(identifier: String) -> AccessToken? {
return self.fetchToken(identifier: identifier,
accessGroup: Configuration.shared.defaultKeychainAccessGroup)
}
/**
Gets the AccessToken using the default tokenIdentifier and accessGroup.
These values are the defined in your Configuration
- returns: An AccessToken, or nil if one wasn't found
*/
@objc public static func fetchToken() -> AccessToken? {
return self.fetchToken(identifier: Configuration.shared.defaultAccessTokenIdentifier,
accessGroup: Configuration.shared.defaultKeychainAccessGroup)
}
//MARK: Save
/**
Saves the given AccessToken using the provided tokenIdentifier and acessGroup.If no values
are supplied, it uses the defaults defined in your Configuration.
Access Token is saved syncronously
- parameter accessToken: The AccessToken to save
- parameter tokenIdentifier: The token identifier string to use (defaults to Configuration.shared.defaultAccessTokenIdentifier)
- parameter accessGroup: The keychain access group to use (defaults to Configuration.shared.defaultKeychainAccessGroup)
- returns: true if the accessToken was saved successfully, false otherwise
*/
@discardableResult @objc public static func save(accessToken: AccessToken, tokenIdentifier: String, accessGroup: String) -> Bool {
keychainWrapper.setAccessGroup(accessGroup)
let success = keychainWrapper.setObject(accessToken, key: tokenIdentifier)
if success {
NotificationCenter.default.post(name: Notification.Name(rawValue: tokenManagerDidSaveTokenNotification), object: self)
}
return success
}
/**
Saves the given AccessToken using the provided tokenIdentifier.
Uses the default keychain access group defined by your Configuration.
Access Token is saved syncronously
- parameter accessToken: The AccessToken to save
- parameter tokenIdentifier: The token identifier string to use
- returns: true if the accessToken was saved successfully, false otherwise
*/
@discardableResult @objc public static func save(accessToken: AccessToken, tokenIdentifier: String) -> Bool {
return self.save(accessToken: accessToken, tokenIdentifier: tokenIdentifier, accessGroup: Configuration.shared.defaultKeychainAccessGroup)
}
/**
Saves the given AccessToken.
Uses the default access token identifier & keychain access group defined by your
Configuration.
Access Token is saved syncronously
- parameter accessToken: The AccessToken to save
- returns: true if the accessToken was saved successfully, false otherwise
*/
@discardableResult @objc public static func save(accessToken: AccessToken) -> Bool {
return self.save(accessToken: accessToken, tokenIdentifier: Configuration.shared.defaultAccessTokenIdentifier, accessGroup: Configuration.shared.defaultKeychainAccessGroup)
}
//MARK: Delete
/**
Deletes the AccessToken for the givent tokenIdentifier and accessGroup. If no values
are supplied, it uses the defaults defined in your Configuration.
- parameter tokenIdentifier: The token identifier string to use (defaults to Configuration.shared.defaultAccessTokenIdentifier)
- parameter accessGroup: The keychain access group to use (defaults to Configuration.shared.defaultKeychainAccessGroup)
- returns: true if the token was deleted, false otherwise
*/
@discardableResult @objc public static func deleteToken(identifier: String, accessGroup: String) -> Bool {
keychainWrapper.setAccessGroup(accessGroup)
deleteCookies()
let success = keychainWrapper.deleteObjectForKey(identifier)
if success {
NotificationCenter.default.post(name: Notification.Name(rawValue: tokenManagerDidDeleteTokenNotification), object: self)
}
return success
}
/**
Deletes the AccessToken for the given tokenIdentifier.
Uses the default keychain access group defined in your Configuration.
- parameter tokenIdentifier: The token identifier string to use
- returns: true if the token was deleted, false otherwise
*/
@discardableResult @objc public static func deleteToken(identifier: String) -> Bool {
return self.deleteToken(identifier: identifier, accessGroup: Configuration.shared.defaultKeychainAccessGroup)
}
/**
Deletes an AccessToken.
Uses the default token identifier defined in your Configuration.
Uses the default keychain access group defined in your Configuration.
- returns: true if the token was deleted, false otherwise
*/
@discardableResult @objc public static func deleteToken() -> Bool {
return self.deleteToken(identifier: Configuration.shared.defaultAccessTokenIdentifier, accessGroup: Configuration.shared.defaultKeychainAccessGroup)
}
// MARK: Private Interface
private static func deleteCookies() {
Configuration.shared.resetProcessPool()
var urlsToClear = [URL]()
if let loginURL = URL(string: OAuth.regionHost) {
urlsToClear.append(loginURL)
}
let sharedCookieStorage = HTTPCookieStorage.shared
for url in urlsToClear {
if let cookies = sharedCookieStorage.cookies(for: url) {
for cookie in cookies {
sharedCookieStorage.deleteCookie(cookie)
}
}
}
}
}