Skip to content

Commit

Permalink
refactor: Remove duplicated InfomaniakTokenable
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilippeWeidmann committed Aug 19, 2024
1 parent 07db99c commit 229d602
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 96 deletions.
65 changes: 1 addition & 64 deletions Sources/InfomaniakLogin/InfomaniakLogin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,27 +81,6 @@ public protocol InfomaniakLoginable {
#endif
}

/// Something that can handle tokens
public protocol InfomaniakTokenable {
/// Get an api token async (callback on background thread)
func getApiTokenUsing(code: String, codeVerifier: String, completion: @Sendable @escaping (Result<ApiToken, Error>) -> Void)

/// Get an api token
func apiTokenUsing(code: String, codeVerifier: String) async throws -> ApiToken

/// Refresh api token async (callback on background thread)
func refreshToken(token: ApiToken, completion: @Sendable @escaping (Result<ApiToken, Error>) -> Void)

/// Refresh api token
func refreshToken(token: ApiToken) async throws -> ApiToken

/// Delete an api token async
func deleteApiToken(token: ApiToken, completion: @Sendable @escaping (Result<Void, Error>) -> Void)

/// Delete an api token
func deleteApiToken(token: ApiToken) async throws
}

@MainActor
class PresentationContext: NSObject, ASWebAuthenticationPresentationContextProviding {
private let anchor: ASPresentationAnchor
Expand All @@ -114,7 +93,7 @@ class PresentationContext: NSObject, ASWebAuthenticationPresentationContextProvi
}
}

public class InfomaniakLogin: InfomaniakLoginable, InfomaniakTokenable {
public class InfomaniakLogin: InfomaniakLoginable {
let networkLogin: InfomaniakNetworkLoginable

public let config: Config
Expand Down Expand Up @@ -196,48 +175,6 @@ public class InfomaniakLogin: InfomaniakLoginable, InfomaniakTokenable {
}
}

// MARK: - InfomaniakTokenable

public func getApiTokenUsing(
code: String,
codeVerifier: String,
completion: @Sendable @escaping (Result<ApiToken, Error>) -> Void
) {
networkLogin.getApiTokenUsing(code: code, codeVerifier: codeVerifier, completion: completion)
}

public func apiTokenUsing(code: String, codeVerifier: String) async throws -> ApiToken {
return try await withCheckedThrowingContinuation { continuation in
getApiTokenUsing(code: code, codeVerifier: codeVerifier) { result in
continuation.resume(with: result)
}
}
}

public func refreshToken(token: ApiToken, completion: @Sendable @escaping (Result<ApiToken, Error>) -> Void) {
networkLogin.refreshToken(token: token, completion: completion)
}

public func refreshToken(token: ApiToken) async throws -> ApiToken {
return try await withCheckedThrowingContinuation { continuation in
refreshToken(token: token) { result in
continuation.resume(with: result)
}
}
}

public func deleteApiToken(token: ApiToken, completion: @Sendable @escaping (Result<Void, Error>) -> Void) {
networkLogin.deleteApiToken(token: token, completion: completion)
}

public func deleteApiToken(token: ApiToken) async throws {
return try await withCheckedThrowingContinuation { continuation in
deleteApiToken(token: token) { result in
continuation.resume(with: result)
}
}
}

// MARK: - Internal

static func checkResponse(url: URL, onSuccess: (String) -> Void, onFailure: (InfomaniakLoginError) -> Void) -> Bool {
Expand Down
33 changes: 33 additions & 0 deletions Sources/InfomaniakLogin/Networking/InfomaniakNetworkLogin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,20 @@ public protocol InfomaniakNetworkLoginable {
/// Get an api token async (callback on background thread)
func getApiTokenUsing(code: String, codeVerifier: String, completion: @Sendable @escaping (Result<ApiToken, Error>) -> Void)

/// Get an api token
func apiTokenUsing(code: String, codeVerifier: String) async throws -> ApiToken

/// Refresh api token async (callback on background thread)
func refreshToken(token: ApiToken, completion: @Sendable @escaping (Result<ApiToken, Error>) -> Void)

/// Refresh api token
func refreshToken(token: ApiToken) async throws -> ApiToken

/// Delete an api token async
func deleteApiToken(token: ApiToken, completion: @Sendable @escaping (Result<Void, Error>) -> Void)

/// Delete an api token
func deleteApiToken(token: ApiToken) async throws
}

public class InfomaniakNetworkLogin: InfomaniakNetworkLoginable {
Expand All @@ -39,6 +48,14 @@ public class InfomaniakNetworkLogin: InfomaniakNetworkLoginable {
tokenApiURL = config.loginURL.appendingPathComponent("token")
}

public func apiTokenUsing(code: String, codeVerifier: String) async throws -> ApiToken {
return try await withCheckedThrowingContinuation { continuation in
getApiTokenUsing(code: code, codeVerifier: codeVerifier) { result in
continuation.resume(with: result)
}
}
}

public func getApiTokenUsing(code: String,
codeVerifier: String,
completion: @Sendable @escaping (Result<ApiToken, Error>) -> Void) {
Expand All @@ -58,6 +75,14 @@ public class InfomaniakNetworkLogin: InfomaniakNetworkLoginable {
getApiToken(request: request, completion: completion)
}

public func refreshToken(token: ApiToken) async throws -> ApiToken {
return try await withCheckedThrowingContinuation { continuation in
refreshToken(token: token) { result in
continuation.resume(with: result)
}
}
}

public func refreshToken(token: ApiToken, completion: @Sendable @escaping (Result<ApiToken, Error>) -> Void) {
guard let refreshToken = token.refreshToken else {
completion(.failure(InfomaniakLoginError.noRefreshToken))
Expand All @@ -83,6 +108,14 @@ public class InfomaniakNetworkLogin: InfomaniakNetworkLoginable {
getApiToken(request: request, completion: completion)
}

public func deleteApiToken(token: ApiToken) async throws {
return try await withCheckedThrowingContinuation { continuation in
deleteApiToken(token: token) { result in
continuation.resume(with: result)
}
}
}

public func deleteApiToken(token: ApiToken, completion: @Sendable @escaping (Result<Void, Error>) -> Void) {
var request = URLRequest(url: tokenApiURL)
request.addValue("Bearer \(token.accessToken)", forHTTPHeaderField: "Authorization")
Expand Down
17 changes: 7 additions & 10 deletions login-Example/login-Example/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}

func setupDI() {
let clientId = "9473D73C-C20F-4971-9E10-D957C563FA68"
let redirectUri = "com.infomaniak.drive://oauth2redirect"
let config = InfomaniakLogin.Config(clientId: clientId, redirectURI: redirectUri, accessType: .none)
/// The `InfomaniakLoginable` interface hides the concrete type `InfomaniakLogin`
SimpleResolver.sharedResolver.store(factory: Factory(type: InfomaniakLoginable.self) { _, _ in
let clientId = "9473D73C-C20F-4971-9E10-D957C563FA68"
let redirectUri = "com.infomaniak.drive://oauth2redirect"
let login = InfomaniakLogin(config: .init(clientId: clientId, redirectURI: redirectUri, accessType: .none))
return login
return InfomaniakLogin(config: config)
})

/// Chained resolution, the `InfomaniakTokenable` interface uses the `InfomaniakLogin` object as well
SimpleResolver.sharedResolver.store(factory: Factory(type: InfomaniakTokenable.self) { _, resolver in
return try resolver.resolve(type: InfomaniakLoginable.self,
forCustomTypeIdentifier: nil,
factoryParameters: nil,
resolver: resolver)
/// The `InfomaniakNetworkLoginable` interface hides the concrete type `InfomaniakNetworkLogin`
SimpleResolver.sharedResolver.store(factory: Factory(type: InfomaniakNetworkLoginable.self) { _, resolver in
return InfomaniakNetworkLogin(config: config)
})
}
}
41 changes: 19 additions & 22 deletions login-Example/login-Example/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import UIKit

class ViewController: UIViewController, InfomaniakLoginDelegate, DeleteAccountDelegate {
@LazyInjectService var loginService: InfomaniakLoginable
@LazyInjectService var tokenService: InfomaniakTokenable
@LazyInjectService var tokenService: InfomaniakNetworkLoginable

func didCompleteDeleteAccount() {
showAlert(title: "Account deleted", message: nil)
Expand All @@ -35,7 +35,7 @@ class ViewController: UIViewController, InfomaniakLoginDelegate, DeleteAccountDe
showAlert(title: "Login Failed", message: error.localizedDescription)
}

func didCompleteLoginWith(code: String, verifier: String) {
func didCompleteLoginWith(code: String, verifier: String) {
tokenService.getApiTokenUsing(code: code, codeVerifier: verifier) { result in
var title: String?
var description: String?
Expand Down Expand Up @@ -121,22 +121,20 @@ class ViewController: UIViewController, InfomaniakLoginDelegate, DeleteAccountDe

@IBAction func refreshTokenConvert(_ sender: Any) {
SimpleResolver.sharedResolver.removeAll()

let clientId = "9473D73C-C20F-4971-9E10-D957C563FA68"
let redirectUri = "com.infomaniak.drive://oauth2redirect"
let config = InfomaniakLogin.Config(clientId: clientId, redirectURI: redirectUri, accessType: .offline)
// Init with non infinite refresh token
SimpleResolver.sharedResolver.store(factory: Factory(type: InfomaniakLoginable.self) { _, _ in
let clientId = "9473D73C-C20F-4971-9E10-D957C563FA68"
let redirectUri = "com.infomaniak.drive://oauth2redirect"
let login = InfomaniakLogin(config: .init(clientId: clientId, redirectURI: redirectUri, accessType: .offline))
return login
return InfomaniakLogin(config: config)
})
SimpleResolver.sharedResolver.store(factory: Factory(type: InfomaniakTokenable.self) { _, resolver in
return try resolver.resolve(type: InfomaniakLoginable.self,
forCustomTypeIdentifier: nil,
factoryParameters: nil,
resolver: resolver)
SimpleResolver.sharedResolver.store(factory: Factory(type: InfomaniakNetworkLoginable.self) { _, resolver in
return InfomaniakNetworkLogin(config: config)
})

@InjectService var loginService: InfomaniakLoginable
@InjectService var tokenService: InfomaniakTokenable
@InjectService var tokenService: InfomaniakNetworkLoginable

loginService.asWebAuthenticationLoginFrom(anchor: .init(),
useEphemeralSession: false,
Expand Down Expand Up @@ -170,22 +168,21 @@ class ViewController: UIViewController, InfomaniakLoginDelegate, DeleteAccountDe

nonisolated func testSwapRefreshToken(apiToken: ApiToken) {
SimpleResolver.sharedResolver.removeAll()

let clientId = "9473D73C-C20F-4971-9E10-D957C563FA68"
let redirectUri = "com.infomaniak.drive://oauth2redirect"
let config = InfomaniakLogin.Config(clientId: clientId, redirectURI: redirectUri, accessType: .none)

// Init with infinite refresh token
SimpleResolver.sharedResolver.store(factory: Factory(type: InfomaniakLoginable.self) { _, _ in
let clientId = "9473D73C-C20F-4971-9E10-D957C563FA68"
let redirectUri = "com.infomaniak.drive://oauth2redirect"
let login = InfomaniakLogin(config: .init(clientId: clientId, redirectURI: redirectUri, accessType: .none))
return login
return InfomaniakLogin(config: config)
})
SimpleResolver.sharedResolver.store(factory: Factory(type: InfomaniakTokenable.self) { _, resolver in
return try resolver.resolve(type: InfomaniakLoginable.self,
forCustomTypeIdentifier: nil,
factoryParameters: nil,
resolver: resolver)
SimpleResolver.sharedResolver.store(factory: Factory(type: InfomaniakNetworkLoginable.self) { _, resolver in
return InfomaniakNetworkLogin(config: config)
})

@InjectService var loginService: InfomaniakLoginable
@InjectService var tokenService: InfomaniakTokenable
@InjectService var tokenService: InfomaniakNetworkLoginable

tokenService.refreshToken(token: apiToken) { result in
var title: String?
Expand Down

0 comments on commit 229d602

Please sign in to comment.