AuthExchange.swift 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Copyright 2022 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. import FirebaseCore
  15. @objc(FIRAuthExchangeDelegate) public protocol AuthExchangeDelegate {
  16. /**
  17. * This method is invoked whenever a new Auth Exchange token is needed. Developers should implement this method to request a
  18. * new token from an identity provider and then exchange it for a new Auth Exchange token.
  19. */
  20. @objc(refreshTokenForAuthExchange:completion:)
  21. func refreshToken(authExchange: AuthExchange,
  22. completion: @escaping (AuthExchangeToken?, Error?) -> Void)
  23. }
  24. @objc(FIRAuthExchange) public class AuthExchange: NSObject, AuthExchangeInterop {
  25. // MARK: - Public APIs
  26. /** The delegate object used to request a new Auth Exchange token when the current one has expired. */
  27. @objc public var authExchangeDelegate: AuthExchangeDelegate?
  28. /** Creates an `AuthExchange` instance, initialized with the default `FirebaseApp`. */
  29. @objc public static func authExchange() -> AuthExchange {
  30. return authExchange(app: FirebaseApp.app()!)
  31. }
  32. /** Creates an `AuthExchange` instance, initialized with the provided `FirebaseApp`. */
  33. @objc(authExchangeWithApp:) public static func authExchange(app: FirebaseApp) -> AuthExchange {
  34. // TODO: Integrate with ComponentProvider.
  35. let instance = self.init()
  36. instanceDictionary[app.name] = instance
  37. return instance
  38. }
  39. /**
  40. * Returns the current Auth Exchange token if valid and fetches a new one from the backend otherwise. If `forceRefresh` is true,
  41. * then a new token is fetched regardless of the validity of the stored token.
  42. *
  43. * In order for a new token to be successfully fetched, an `AuthExchangeDelegate` must be registered.
  44. */
  45. @available(iOS 13, tvOS 13, macOS 10.15, watchOS 6, *)
  46. public func getToken(forceRefresh: Bool) async throws -> AuthExchangeToken? {
  47. // TODO: Implement methods.
  48. return authExchangeToken
  49. }
  50. /** See `getToken(forceRefresh:)`. */
  51. @objc(getTokenForcingRefresh:completion:)
  52. public func getToken(forceRefresh: Bool,
  53. completion: @escaping (AuthExchangeToken?, Error?) -> Void) {
  54. // TODO: Implement methods.
  55. completion(authExchangeToken, nil)
  56. }
  57. /** Clears the stored Auth Exchange token and delegate, if one is set. */
  58. @available(iOS 13, tvOS 13, macOS 10.15, watchOS 6, *)
  59. public func clearState() async throws {
  60. // TODO: Implement methods.
  61. }
  62. /** See `clearState()`. */
  63. @objc(clearStateWithCompletion:)
  64. public func clearState(completion: (Error?) -> Void) {
  65. // TODO: Implement methods.
  66. }
  67. /**
  68. * Exchanges a custom token for an `AuthExchangeToken` and updates the `AuthExchange` instance with the
  69. * `AuthExchangeToken`.
  70. */
  71. @available(iOS 13, tvOS 13, macOS 10.15, watchOS 6, *)
  72. public func updateWith(customToken: String) async throws -> AuthExchangeResult {
  73. // TODO: Replace this test function with real implementation.
  74. let token = AuthExchangeToken(token: "token", expirationDate: Date())
  75. let result = AuthExchangeResult(
  76. authExchangeToken: token
  77. )
  78. return result
  79. }
  80. /** See `updateWith(customToken:)`. */
  81. @objc public func updateWith(customToken: String,
  82. completion: @escaping (AuthExchangeResult?, Error?) -> Void) {
  83. // TODO: Replace this test function with real implementation.
  84. let token = AuthExchangeToken(token: "token", expirationDate: Date())
  85. let result = AuthExchangeResult(
  86. authExchangeToken: token
  87. )
  88. completion(result, nil)
  89. }
  90. /**
  91. * Exchanges a Firebase Installations token for an `AuthExchangeToken` and updates the `AuthExchange` instance with the
  92. * `AuthExchangeToken`.
  93. */
  94. @available(iOS 13, tvOS 13, macOS 10.15, watchOS 6, *)
  95. public func updateWithInstallationsToken() async throws -> AuthExchangeResult {
  96. // TODO: Replace this test function with real implementation.
  97. let token = AuthExchangeToken(token: "token", expirationDate: Date())
  98. let result = AuthExchangeResult(
  99. authExchangeToken: token
  100. )
  101. return result
  102. }
  103. /** See `updateWithInstallationsToken()`. */
  104. @objc(updateWithInstallationsTokenWithCompletion:)
  105. public func updateWithInstallationsToken(completion: @escaping (AuthExchangeResult?, Error?)
  106. -> Void) {
  107. // TODO: Replace this test function with real implementation.
  108. let token = AuthExchangeToken(token: "token", expirationDate: Date())
  109. let result = AuthExchangeResult(
  110. authExchangeToken: token
  111. )
  112. completion(result, nil)
  113. }
  114. /**
  115. * Exchanges an OIDC token for an `AuthExchangeToken` and updates the `AuthExchange` instance with the
  116. * `AuthExchangeToken`.
  117. */
  118. @available(iOS 13, tvOS 13, macOS 10.15, watchOS 6, *)
  119. public func updateWith(OIDCToken: String) async throws -> AuthExchangeResult {
  120. // TODO: Replace this test function with real implementation.
  121. let token = AuthExchangeToken(token: "token", expirationDate: Date())
  122. let result = AuthExchangeResult(
  123. authExchangeToken: token
  124. )
  125. return result
  126. }
  127. /** See `updateWith(OIDCToken:)`. */
  128. @objc public func updateWith(OIDCToken: String,
  129. completion: @escaping (AuthExchangeResult?, Error?) -> Void) {
  130. // TODO: Replace this test function with real implementation.
  131. let token = AuthExchangeToken(token: "token", expirationDate: Date())
  132. let result = AuthExchangeResult(
  133. authExchangeToken: token
  134. )
  135. completion(result, nil)
  136. }
  137. // MARK: - Internal APIs
  138. // TODO: Integrate with ComponentProvider.
  139. private static var instanceDictionary: [String: AuthExchange] = [:]
  140. // TODO: Integrate with ComponentProvider.
  141. override public required init() {
  142. authExchangeDelegate = nil
  143. }
  144. /** The cached Auth Exchange token */
  145. var authExchangeToken: AuthExchangeToken?
  146. // TODO: Replace this test function with real implementation.
  147. /** This is a test funciton to trigger delegate call */
  148. public func tryDelegate() {
  149. let returnToAuthExchangeHandler: (AuthExchangeToken?, Error?) -> Void = {
  150. token, error in
  151. self.authExchangeToken = token
  152. print("[delegate] token: \(String(describing: token?.token))")
  153. // Auth exchange can do sth with this token
  154. }
  155. authExchangeDelegate?.refreshToken(authExchange: self, completion: returnToAuthExchangeHandler)
  156. }
  157. // MARK: - Interop APIs
  158. @available(iOS 13, tvOS 13, macOS 10.15, watchOS 6, *)
  159. public func getTokenInternal(forceRefresh: Bool) async throws -> String {
  160. // TODO: Implement interop methods.
  161. return "Unimplemented"
  162. }
  163. public func getTokenInternal(forceRefresh: Bool,
  164. completion: @escaping (String?, Error?) -> Void) {
  165. // TODO: Implement interop methods.
  166. }
  167. }