Skip to content

Commit 38b0458

Browse files
committed
Rewrite handleRedirectURL and handleRedirectURL functions to async
1 parent 9ac5e35 commit 38b0458

File tree

7 files changed

+56
-32
lines changed

7 files changed

+56
-32
lines changed

Sources/Base/OAuth2Base.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ open class OAuth2Base: OAuth2Securable {
102102

103103
/// The receiver's id token.
104104
open var idToken: String? {
105-
get { return clientConfig.idToken }
105+
get { return clientConfig.idToken }
106106
set { clientConfig.idToken = newValue }
107107
}
108108

@@ -157,6 +157,7 @@ open class OAuth2Base: OAuth2Securable {
157157
*/
158158
public final var internalAfterAuthorizeOrFail: ((_ wasFailure: Bool, _ error: OAuth2Error?) -> Void)?
159159

160+
final var doAuthorizeContinuation: CheckedContinuation<OAuth2JSON, any Error>?
160161

161162
/**
162163
Designated initializer.
@@ -258,7 +259,8 @@ open class OAuth2Base: OAuth2Securable {
258259

259260
- parameter redirect: The redirect URL returned by the server that you want to handle
260261
*/
261-
open func handleRedirectURL(_ redirect: URL) throws {
262+
@discardableResult
263+
open func handleRedirectURL(_ redirect: URL) async throws -> OAuth2JSON {
262264
throw OAuth2Error.generic("Abstract class use")
263265
}
264266

@@ -279,6 +281,10 @@ open class OAuth2Base: OAuth2Securable {
279281
self.internalAfterAuthorizeOrFail?(false, nil)
280282
self.afterAuthorizeOrFail?(parameters, nil)
281283
}
284+
285+
// Finish `doAuthorize` call
286+
self.doAuthorizeContinuation?.resume(returning: parameters)
287+
self.doAuthorizeContinuation = nil
282288
}
283289

284290
/**
@@ -302,6 +308,10 @@ open class OAuth2Base: OAuth2Securable {
302308
self.internalAfterAuthorizeOrFail?(true, finalError)
303309
self.afterAuthorizeOrFail?(nil, finalError)
304310
}
311+
312+
// Finish `doAuthorize` call
313+
self.doAuthorizeContinuation?.resume(throwing: error ?? OAuth2Error.requestCancelled)
314+
self.doAuthorizeContinuation = nil
305315
}
306316

307317
/**

Sources/Flows/OAuth2.swift

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,21 @@ open class OAuth2: OAuth2Base {
186186
- parameter params: Optional key/value pairs to pass during authorization
187187
*/
188188
open func doAuthorize(params: OAuth2StringDict? = nil) async throws -> OAuth2JSON? {
189-
if authConfig.authorizeEmbedded {
190-
try await doAuthorizeEmbedded(with: authConfig, params: params)
191-
}
192-
else {
193-
try doOpenAuthorizeURLInBrowser(params: params)
189+
return try await withCheckedThrowingContinuation { continuation in
190+
Task {
191+
do {
192+
if authConfig.authorizeEmbedded {
193+
try await doAuthorizeEmbedded(with: authConfig, params: params)
194+
}
195+
else {
196+
try doOpenAuthorizeURLInBrowser(params: params)
197+
}
198+
self.doAuthorizeContinuation = continuation
199+
} catch {
200+
continuation.resume(throwing: error)
201+
}
202+
}
194203
}
195-
196-
return nil // TODO
197204
}
198205

199206
/**
@@ -229,7 +236,7 @@ open class OAuth2: OAuth2Base {
229236
Method that creates the OAuth2AuthRequest instance used to create the authorize URL
230237

231238
- parameter redirect: The redirect URI string to supply. If it is nil, the first value of the settings' `redirect_uris` entries is
232-
used. Must be present in the end!
239+
used. Must be present in the end!
233240
- parameter scope: The scope to request
234241
- parameter params: Any additional parameters as dictionary with string keys and values that will be added to the query part
235242
- returns: OAuth2AuthRequest to be used to call to the authorize endpoint
@@ -279,7 +286,7 @@ open class OAuth2: OAuth2Base {
279286
Convenience method to be overridden by and used from subclasses.
280287

281288
- parameter redirect: The redirect URI string to supply. If it is nil, the first value of the settings' `redirect_uris` entries is
282-
used. Must be present in the end!
289+
used. Must be present in the end!
283290
- parameter scope: The scope to request
284291
- parameter params: Any additional parameters as dictionary with string keys and values that will be added to the query part
285292
- returns: NSURL to be used to start the OAuth dance

Sources/Flows/OAuth2CodeGrant.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,15 @@ open class OAuth2CodeGrant: OAuth2 {
7777
/**
7878
Extracts the code from the redirect URL and exchanges it for a token.
7979
*/
80-
override open func handleRedirectURL(_ redirect: URL) {
80+
override open func handleRedirectURL(_ redirect: URL) async throws -> OAuth2JSON {
8181
logger?.debug("OAuth2", msg: "Handling redirect URL \(redirect.description)")
8282
do {
8383
let code = try validateRedirectURL(redirect)
84-
Task {
85-
await exchangeCodeForToken(code)
86-
}
84+
return try await exchangeCodeForToken(code)
8785
}
88-
catch let error {
86+
catch {
8987
didFail(with: error.asOAuth2Error)
88+
throw error
9089
}
9190
}
9291

@@ -95,7 +94,7 @@ open class OAuth2CodeGrant: OAuth2 {
9594

9695
Uses `accessTokenRequest(params:)` to create the request, which you can subclass to change implementation specifics.
9796
*/
98-
public func exchangeCodeForToken(_ code: String) async {
97+
public func exchangeCodeForToken(_ code: String) async throws -> OAuth2JSON {
9998
do {
10099
guard !code.isEmpty else {
101100
throw OAuth2Error.prerequisiteFailed("I don't have a code to exchange, let the user authorize first")
@@ -112,8 +111,10 @@ open class OAuth2CodeGrant: OAuth2 {
112111
}
113112
self.logger?.debug("OAuth2", msg: "Did exchange code for access [\(nil != self.clientConfig.accessToken)] and refresh [\(nil != self.clientConfig.refreshToken)] tokens")
114113
self.didAuthorize(withParameters: params)
114+
return params
115115
} catch {
116116
didFail(with: error.asOAuth2Error)
117+
throw error
117118
}
118119
}
119120

Sources/Flows/OAuth2ImplicitGrant.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ open class OAuth2ImplicitGrant: OAuth2 {
3838
return OAuth2ResponseTypes.token
3939
}
4040

41-
override open func handleRedirectURL(_ redirect: URL) {
41+
override open func handleRedirectURL(_ redirect: URL) async throws -> OAuth2JSON {
4242
logger?.debug("OAuth2", msg: "Handling redirect URL \(redirect.description)")
4343
do {
4444
// token should be in the URL fragment
@@ -51,9 +51,11 @@ open class OAuth2ImplicitGrant: OAuth2 {
5151
let dict = try parseAccessTokenResponse(params: params)
5252
logger?.debug("OAuth2", msg: "Successfully extracted access token")
5353
didAuthorize(withParameters: dict)
54+
return dict
5455
}
55-
catch let error {
56+
catch {
5657
didFail(with: error.asOAuth2Error)
58+
throw error
5759
}
5860
}
5961

Sources/iOS/OAuth2Authorizer+iOS.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,13 @@ open class OAuth2Authorizer: OAuth2AuthorizerUI {
152152
}
153153
let completionHandler: (URL?, Error?) -> Void = { url, error in
154154
if let url = url {
155-
do {
156-
try self.oauth2.handleRedirectURL(url as URL)
157-
}
158-
catch let err {
159-
self.oauth2.logger?.warn("OAuth2", msg: "Cannot intercept redirect URL: \(err)")
155+
Task {
156+
do {
157+
try await self.oauth2.handleRedirectURL(url as URL)
158+
}
159+
catch {
160+
self.oauth2.logger?.warn("OAuth2", msg: "Cannot intercept redirect URL: \(error)")
161+
}
160162
}
161163
} else {
162164
if let authenticationSessionError = error as? ASWebAuthenticationSessionError {

Sources/macOS/OAuth2Authorizer+macOS.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,12 @@ open class OAuth2Authorizer: OAuth2AuthorizerUI {
131131

132132
let completionHandler: (URL?, Error?) -> Void = { url, error in
133133
if let url {
134-
do {
135-
try self.oauth2.handleRedirectURL(url)
136-
} catch let err {
137-
self.oauth2.logger?.warn("OAuth2", msg: "Cannot intercept redirect URL: \(err)")
134+
Task {
135+
do {
136+
try await self.oauth2.handleRedirectURL(url)
137+
} catch let err {
138+
self.oauth2.logger?.warn("OAuth2", msg: "Cannot intercept redirect URL: \(err)")
139+
}
138140
}
139141
} else {
140142
if let authenticationSessionError = error as? ASWebAuthenticationSessionError {
@@ -220,7 +222,7 @@ open class OAuth2Authorizer: OAuth2AuthorizerUI {
220222

221223
controller.onIntercept = { url in
222224
do {
223-
try self.oauth2.handleRedirectURL(url)
225+
try await self.oauth2.handleRedirectURL(url)
224226
return true
225227
}
226228
catch let error {

Sources/macOS/OAuth2WebViewController+macOS.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public class OAuth2WebViewController: NSViewController, WKNavigationDelegate, NS
8484
/// Closure called when the web view gets asked to load the redirect URL, specified in `interceptURLString`. Return a Bool indicating
8585
/// that you've intercepted the URL.
8686
@OAuth2Actor
87-
public var onIntercept: ((URL) -> Bool)?
87+
public var onIntercept: ((URL) async -> Bool)?
8888

8989
/// Called when the web view is about to be dismissed manually.
9090
@OAuth2Actor
@@ -264,7 +264,7 @@ public class OAuth2WebViewController: NSViewController, WKNavigationDelegate, NS
264264
if let url = request.url, url.scheme == interceptComponents?.scheme && url.host == interceptComponents?.host {
265265
let haveComponents = URLComponents(url: url, resolvingAgainstBaseURL: true)
266266
if let hp = haveComponents?.path, let ip = interceptComponents?.path, hp == ip || ("/" == hp + ip) {
267-
if onIntercept(url) {
267+
if await onIntercept(url) {
268268
return .cancel
269269
}
270270
else {
@@ -285,7 +285,7 @@ public class OAuth2WebViewController: NSViewController, WKNavigationDelegate, NS
285285
oauth?.logger?.debug("OAuth2", msg: "Creating redirect URL from document.title")
286286
let qry = title.replacingOccurrences(of: "Success ", with: "")
287287
if let url = URL(string: "http://localhost/?\(qry)") {
288-
_ = onIntercept?(url)
288+
_ = await onIntercept?(url)
289289
return
290290
}
291291

0 commit comments

Comments
 (0)