diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2022-05-17 15:03:15 +0200 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2022-05-17 15:23:43 +0200 |
| commit | 261e1c16ac17deab50446ac0397c330e2adc3b0c (patch) | |
| tree | 40d81e291c8382a7c9435c39853feff40ec1d3d6 | |
| parent | 10b11bb22f66c303bca1b213705fff96170823a1 (diff) | |
| download | mullvadvpn-261e1c16ac17deab50446ac0397c330e2adc3b0c.tar.xz mullvadvpn-261e1c16ac17deab50446ac0397c330e2adc3b0c.zip | |
REST: add authorization provider
| -rw-r--r-- | ios/MullvadVPN/REST/RESTAccountsProxy.swift | 15 | ||||
| -rw-r--r-- | ios/MullvadVPN/REST/RESTAuthorization.swift | 42 | ||||
| -rw-r--r-- | ios/MullvadVPN/REST/RESTDevicesProxy.swift | 75 | ||||
| -rw-r--r-- | ios/MullvadVPN/REST/RESTNetworkOperation.swift | 21 | ||||
| -rw-r--r-- | ios/MullvadVPN/REST/RESTRequestHandler.swift | 37 |
5 files changed, 84 insertions, 106 deletions
diff --git a/ios/MullvadVPN/REST/RESTAccountsProxy.swift b/ios/MullvadVPN/REST/RESTAccountsProxy.swift index 977511926a..e9c44f0f63 100644 --- a/ios/MullvadVPN/REST/RESTAccountsProxy.swift +++ b/ios/MullvadVPN/REST/RESTAccountsProxy.swift @@ -66,17 +66,10 @@ extension REST { return requestBuilder.getRequest() }, - requestAuthorization: { completion in - return self.configuration.accessTokenManager - .getAccessToken( - accountNumber: accountNumber, - retryStrategy: retryStrategy - ) { operationCompletion in - completion(operationCompletion.map { tokenData in - return .accessToken(tokenData.accessToken) - }) - } - } + authorizationProvider: createAuthorizationProvider( + accountNumber: accountNumber, + retryStrategy: .default + ) ) let responseHandler = REST.defaultResponseHandler( diff --git a/ios/MullvadVPN/REST/RESTAuthorization.swift b/ios/MullvadVPN/REST/RESTAuthorization.swift index b9a701b1ac..864cdb83a6 100644 --- a/ios/MullvadVPN/REST/RESTAuthorization.swift +++ b/ios/MullvadVPN/REST/RESTAuthorization.swift @@ -8,9 +8,51 @@ import Foundation +protocol RESTAuthorizationProvider { + typealias Completion = OperationCompletion<REST.Authorization, REST.Error> + + func getAuthorization(completion: @escaping (Completion) -> Void) -> Cancellable +} + extension REST { enum Authorization { case accountNumber(String) case accessToken(String) } + + struct AccessTokenProvider: RESTAuthorizationProvider { + private let accessTokenManager: AccessTokenManager + private let accountNumber: String + private let retryStrategy: REST.RetryStrategy + + init(accessTokenManager: AccessTokenManager, accountNumber: String, retryStrategy: REST.RetryStrategy) { + self.accessTokenManager = accessTokenManager + self.accountNumber = accountNumber + self.retryStrategy = retryStrategy + } + + func getAuthorization(completion: @escaping (Completion) -> Void) -> Cancellable { + return accessTokenManager.getAccessToken( + accountNumber: accountNumber, + retryStrategy: retryStrategy + ) { operationCompletion in + completion(operationCompletion.map { tokenData in + return .accessToken(tokenData.accessToken) + }) + } + } + } +} + +extension REST.Proxy where ConfigurationType == REST.AuthProxyConfiguration { + func createAuthorizationProvider( + accountNumber: String, + retryStrategy: REST.RetryStrategy + ) -> RESTAuthorizationProvider { + return REST.AccessTokenProvider( + accessTokenManager: configuration.accessTokenManager, + accountNumber: accountNumber, + retryStrategy: retryStrategy + ) + } } diff --git a/ios/MullvadVPN/REST/RESTDevicesProxy.swift b/ios/MullvadVPN/REST/RESTDevicesProxy.swift index 0b8a4bc91c..5a1fa115fd 100644 --- a/ios/MullvadVPN/REST/RESTDevicesProxy.swift +++ b/ios/MullvadVPN/REST/RESTDevicesProxy.swift @@ -53,17 +53,10 @@ extension REST { return requestBuilder.getRequest() }, - requestAuthorization: { completion in - return self.configuration.accessTokenManager - .getAccessToken( - accountNumber: accountNumber, - retryStrategy: retryStrategy - ) { operationCompletion in - completion(operationCompletion.map { tokenData in - return .accessToken(tokenData.accessToken) - }) - } - } + authorizationProvider: createAuthorizationProvider( + accountNumber: accountNumber, + retryStrategy: .default + ) ) let responseHandler = AnyResponseHandler { response, data -> ResponseHandlerResult<Device?> in @@ -116,17 +109,10 @@ extension REST { return requestBuilder.getRequest() }, - requestAuthorization: { completion in - return self.configuration.accessTokenManager - .getAccessToken( - accountNumber: accountNumber, - retryStrategy: retryStrategy - ) { operationCompletion in - completion(operationCompletion.map { tokenData in - return .accessToken(tokenData.accessToken) - }) - } - } + authorizationProvider: createAuthorizationProvider( + accountNumber: accountNumber, + retryStrategy: .default + ) ) let responseHandler = REST.defaultResponseHandler( @@ -166,17 +152,10 @@ extension REST { return requestBuilder.getRequest() }, - requestAuthorization: { completion in - return self.configuration.accessTokenManager - .getAccessToken( - accountNumber: accountNumber, - retryStrategy: retryStrategy - ) { operationCompletion in - completion(operationCompletion.map { tokenData in - return .accessToken(tokenData.accessToken) - }) - } - } + authorizationProvider: createAuthorizationProvider( + accountNumber: accountNumber, + retryStrategy: .default + ) ) let responseHandler = REST.defaultResponseHandler( @@ -224,17 +203,10 @@ extension REST { return requestBuilder.getRequest() }, - requestAuthorization: { completion in - return self.configuration.accessTokenManager - .getAccessToken( - accountNumber: accountNumber, - retryStrategy: retryStrategy - ) { operationCompletion in - completion(operationCompletion.map { tokenData in - return .accessToken(tokenData.accessToken) - }) - } - } + authorizationProvider: createAuthorizationProvider( + accountNumber: accountNumber, + retryStrategy: .default + ) ) let responseHandler = AnyResponseHandler { response, data -> ResponseHandlerResult<Bool> in @@ -302,17 +274,10 @@ extension REST { return urlRequest }, - requestAuthorization: { completion in - return self.configuration.accessTokenManager - .getAccessToken( - accountNumber: accountNumber, - retryStrategy: retryStrategy - ) { operationCompletion in - completion(operationCompletion.map { tokenData in - return .accessToken(tokenData.accessToken) - }) - } - } + authorizationProvider: createAuthorizationProvider( + accountNumber: accountNumber, + retryStrategy: .default + ) ) let responseHandler = REST.defaultResponseHandler( diff --git a/ios/MullvadVPN/REST/RESTNetworkOperation.swift b/ios/MullvadVPN/REST/RESTNetworkOperation.swift index f32f86316f..14b441fca9 100644 --- a/ios/MullvadVPN/REST/RESTNetworkOperation.swift +++ b/ios/MullvadVPN/REST/RESTNetworkOperation.swift @@ -81,10 +81,15 @@ extension REST { return } - let authorizationResult = requestHandler.requestAuthorization { completion in - self.dispatchQueue.async { - assert(self.requiresAuthorization, "Illegal use of completion handler.") + guard let authorizationProvider = requestHandler.authorizationProvider else { + requiresAuthorization = false + didReceiveAuthorization(nil) + return + } + requiresAuthorization = true + authorizationTask = authorizationProvider.getAuthorization { completion in + self.dispatchQueue.async { switch completion { case .success(let authorization): self.didReceiveAuthorization(authorization) @@ -97,16 +102,6 @@ extension REST { } } } - - switch authorizationResult { - case .pending(let task): - requiresAuthorization = true - authorizationTask = task - - case .noRequirement: - requiresAuthorization = false - didReceiveAuthorization(nil) - } } private func didReceiveAuthorization(_ authorization: REST.Authorization?) { diff --git a/ios/MullvadVPN/REST/RESTRequestHandler.swift b/ios/MullvadVPN/REST/RESTRequestHandler.swift index 2ab65bb8b1..6d690d19e7 100644 --- a/ios/MullvadVPN/REST/RESTRequestHandler.swift +++ b/ios/MullvadVPN/REST/RESTRequestHandler.swift @@ -9,50 +9,40 @@ import Foundation protocol RESTRequestHandler { - typealias AuthorizationCompletion = (OperationCompletion<REST.Authorization, REST.Error>) -> Void + func createURLRequest( + endpoint: AnyIPEndpoint, + authorization: REST.Authorization? + ) throws -> REST.Request - func createURLRequest(endpoint: AnyIPEndpoint, authorization: REST.Authorization?) throws -> REST.Request - func requestAuthorization(completion: @escaping AuthorizationCompletion) -> REST.AuthorizationResult + var authorizationProvider: RESTAuthorizationProvider? { get } } extension REST { - struct Request { var urlRequest: URLRequest var pathTemplate: URLPathTemplate } - enum AuthorizationResult { - /// There is no requirement for authorizing this request. - case noRequirement - - /// Authorization request is initiated. - /// Associated value contains a handle that can be used to cancel - /// the request. - case pending(Cancellable) - } - final class AnyRequestHandler: RESTRequestHandler { private let _createURLRequest: (AnyIPEndpoint, REST.Authorization?) throws -> REST.Request - private let _requestAuthorization: ((@escaping AuthorizationCompletion) -> AuthorizationResult)? + + let authorizationProvider: RESTAuthorizationProvider? init(createURLRequest: @escaping (AnyIPEndpoint) throws -> REST.Request) { _createURLRequest = { endpoint, authorization in return try createURLRequest(endpoint) } - _requestAuthorization = nil + authorizationProvider = nil } init( createURLRequest: @escaping (AnyIPEndpoint, REST.Authorization) throws -> REST.Request, - requestAuthorization: @escaping (@escaping AuthorizationCompletion) -> Cancellable + authorizationProvider: RESTAuthorizationProvider ) { _createURLRequest = { endpoint, authorization in return try createURLRequest(endpoint, authorization!) } - _requestAuthorization = { completion in - return .pending(requestAuthorization(completion)) - } + self.authorizationProvider = authorizationProvider } func createURLRequest( @@ -61,12 +51,5 @@ extension REST { ) throws -> REST.Request { return try _createURLRequest(endpoint, authorization) } - - func requestAuthorization( - completion: @escaping (OperationCompletion<REST.Authorization, REST.Error>) -> Void - ) -> REST.AuthorizationResult { - return _requestAuthorization?(completion) ?? .noRequirement - } } - } |
