-
Notifications
You must be signed in to change notification settings - Fork 192
Expand file tree
/
Copy pathAuthenticationClientMobileSyncImpl.swift
More file actions
166 lines (139 loc) · 5.62 KB
/
AuthenticationClientMobileSyncImpl.swift
File metadata and controls
166 lines (139 loc) · 5.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import Foundation
import UIKit
#if QURAN_SYNC
import KMPNativeCoroutinesAsync
import MobileSync
import VLogging
#endif
public final actor AuthenticationClientMobileSyncImpl: AuthenticationClient {
#if QURAN_SYNC
public init(session: MobileSyncSession) {
self.session = session
}
public init(configurations: AuthenticationClientConfiguration) {
session = MobileSyncSession(configurations: configurations)
}
// MARK: Public
public var authenticationState: AuthenticationState {
guard let authService = session.authService else {
return .notAuthenticated
}
return authService.isLoggedIn() ? .authenticated : .notAuthenticated
}
public func login(on _: UIViewController) async throws {
guard let authService = session.authService else {
throw AuthenticationClientError.clientIsNotAuthenticated(nil)
}
do {
_ = try await asyncFunction(for: authService.login())
} catch {
logger.error("Failed to login via mobile sync: \(error)")
throw AuthenticationClientError.errorAuthenticating(error)
}
}
public func restoreState() async throws -> AuthenticationState {
guard let authService = session.authService else {
return .notAuthenticated
}
do {
_ = try await session.continuePendingLoginIfNeeded()
_ = try await asyncFunction(for: authService.refreshAccessTokenIfNeeded())
return authenticationState
} catch {
logger.error("Failed to restore mobile sync auth state: \(error)")
throw AuthenticationClientError.clientIsNotAuthenticated(error)
}
}
public func logout() async throws {
guard let authService = session.authService else {
return
}
do {
_ = try await asyncFunction(for: authService.logout())
} catch {
logger.error("Failed to logout via mobile sync: \(error)")
throw AuthenticationClientError.errorAuthenticating(error)
}
}
public func authenticate(request: URLRequest) async throws -> URLRequest {
let headers = try await getAuthenticationHeaders()
var request = request
for (field, value) in headers {
request.setValue(value, forHTTPHeaderField: field)
}
return request
}
public func getAuthenticationHeaders() async throws -> [String: String] {
guard let authService = session.authService else {
throw AuthenticationClientError.clientIsNotAuthenticated(nil)
}
do {
return try await withCheckedThrowingContinuation { continuation in
authService.getAuthHeaders { headers, error in
if let error {
continuation.resume(throwing: AuthenticationClientError.clientIsNotAuthenticated(error))
} else {
continuation.resume(returning: headers ?? [:])
}
}
}
} catch let error as AuthenticationClientError {
throw error
} catch {
throw AuthenticationClientError.clientIsNotAuthenticated(error)
}
}
// MARK: Private
private let session: MobileSyncSession
#else
public init(session: MobileSyncSession) {
if let configurations = session.configurations {
fallback = AuthenticationClientImpl(configurations: configurations)
} else {
fallback = nil
}
}
public init(configurations: AuthenticationClientConfiguration) {
fallback = AuthenticationClientImpl(configurations: configurations)
}
public var authenticationState: AuthenticationState {
get async {
guard let fallback else {
return .notAuthenticated
}
return await fallback.authenticationState
}
}
public func login(on viewController: UIViewController) async throws {
guard let fallback else {
throw AuthenticationClientError.clientIsNotAuthenticated(nil)
}
try await fallback.login(on: viewController)
}
public func restoreState() async throws -> AuthenticationState {
guard let fallback else {
return .notAuthenticated
}
return try await fallback.restoreState()
}
public func logout() async throws {
guard let fallback else {
return
}
try await fallback.logout()
}
public func authenticate(request: URLRequest) async throws -> URLRequest {
guard let fallback else {
throw AuthenticationClientError.clientIsNotAuthenticated(nil)
}
return try await fallback.authenticate(request: request)
}
public func getAuthenticationHeaders() async throws -> [String: String] {
guard let fallback else {
throw AuthenticationClientError.clientIsNotAuthenticated(nil)
}
return try await fallback.getAuthenticationHeaders()
}
private let fallback: AuthenticationClientImpl?
#endif
}