Skip to content

Commit

Permalink
Merge pull request #212 from WilliamDenniss/pr196
Browse files Browse the repository at this point in the history
UICoordinator refactor.
  • Loading branch information
WilliamDenniss committed Mar 8, 2018
2 parents 5d321b8 + cb5670e commit a100a7b
Show file tree
Hide file tree
Showing 31 changed files with 465 additions and 300 deletions.
110 changes: 70 additions & 40 deletions AppAuth.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions Source/AppAuth.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@
*/

#import "OIDAuthState.h"
#import "OIDAuthorizationFlowSession.h"
#import "OIDAuthStateChangeDelegate.h"
#import "OIDAuthStateErrorDelegate.h"
#import "OIDAuthorizationRequest.h"
#import "OIDAuthorizationResponse.h"
#import "OIDAuthorizationService.h"
#import "OIDAuthorizationUICoordinator.h"
#import "OIDError.h"
#import "OIDErrorUtilities.h"
#import "OIDExternalUserAgent.h"
#import "OIDExternalUserAgentSession.h"
#import "OIDGrantTypes.h"
#import "OIDRegistrationRequest.h"
#import "OIDRegistrationResponse.h"
Expand All @@ -43,12 +45,12 @@
#elif TARGET_OS_IOS
#import "OIDAuthState+IOS.h"
#import "OIDAuthorizationService+IOS.h"
#import "OIDAuthorizationUICoordinatorCustomBrowser.h"
#import "OIDAuthorizationUICoordinatorIOS.h"
#import "OIDExternalUserAgentIOS.h"
#import "OIDExternalUserAgentIOSCustomBrowser.h"
#elif TARGET_OS_MAC
#import "OIDAuthState+Mac.h"
#import "OIDAuthorizationService+Mac.h"
#import "OIDAuthorizationUICoordinatorMac.h"
#import "OIDExternalUserAgentMac.h"
#import "OIDRedirectHTTPHandler.h"
#else
#error "Platform Undefined"
Expand Down
8 changes: 4 additions & 4 deletions Source/Framework/AppAuth.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ FOUNDATION_EXPORT const unsigned char AppAuthVersionString[];
#import <AppAuth/OIDAuthorizationRequest.h>
#import <AppAuth/OIDAuthorizationResponse.h>
#import <AppAuth/OIDAuthorizationService.h>
#import <AppAuth/OIDAuthorizationUICoordinator.h>
#import <AppAuth/OIDExternalUserAgent.h>
#import <AppAuth/OIDError.h>
#import <AppAuth/OIDErrorUtilities.h>
#import <AppAuth/OIDGrantTypes.h>
Expand All @@ -50,12 +50,12 @@ FOUNDATION_EXPORT const unsigned char AppAuthVersionString[];
#elif TARGET_OS_IOS
#import <AppAuth/OIDAuthState+IOS.h>
#import <AppAuth/OIDAuthorizationService+IOS.h>
#import <AppAuth/OIDAuthorizationUICoordinatorCustomBrowser.h>
#import <AppAuth/OIDAuthorizationUICoordinatorIOS.h>
#import <AppAuth/OIDExternalUserAgentIOS.h>
#import <AppAuth/OIDExternalUserAgentIOSCustomBrowser.h>
#elif TARGET_OS_MAC
#import <AppAuth/OIDAuthState+Mac.h>
#import <AppAuth/OIDAuthorizationService+Mac.h>
#import <AppAuth/OIDAuthorizationUICoordinatorMac.h>
#import <AppAuth/OIDExternalUserAgentMac.h>
#import <AppAuth/OIDRedirectHTTPHandler.h>
#else
#error "Platform Undefined"
Expand Down
16 changes: 8 additions & 8 deletions Source/OIDAuthState.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
@class OIDTokenResponse;
@class OIDTokenRequest;
@protocol OIDAuthorizationFlowSession;
@protocol OIDAuthorizationUICoordinator;
@protocol OIDAuthStateChangeDelegate;
@protocol OIDAuthStateErrorDelegate;
@protocol OIDExternalUserAgent;
@protocol OIDExternalUserAgentSession;

NS_ASSUME_NONNULL_BEGIN

Expand Down Expand Up @@ -142,16 +143,15 @@ typedef void (^OIDAuthStateAuthorizationCallback)(OIDAuthState *_Nullable authSt
/*! @brief Convenience method to create a @c OIDAuthState by presenting an authorization request
and performing the authorization code exchange in the case of code flow requests.
@param authorizationRequest The authorization request to present.
@param UICoordinator Generic authorization UI coordinator that can present an authorization
request.
@param UICoordinator A external user agent that can present an external user-agent request.
@param callback The method called when the request has completed or failed.
@return A @c OIDAuthorizationFlowSession instance which will terminate when it
receives a @c OIDAuthorizationFlowSession.cancel message, or after processing a
@c OIDAuthorizationFlowSession.resumeAuthorizationFlowWithURL: message.
@return A @c OIDExternalUserAgentSession instance which will terminate when it
receives a @c OIDExternalUserAgentSession.cancel message, or after processing a
@c OIDExternalUserAgentSession.resumeExternalUserAgentFlowWithURL: message.
*/
+ (id<OIDAuthorizationFlowSession>)
+ (id<OIDExternalUserAgentSession, OIDAuthorizationFlowSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
UICoordinator:(id<OIDAuthorizationUICoordinator>)UICoordinator
UICoordinator:(id<OIDExternalUserAgent>)externalUserAgent
callback:(OIDAuthStateAuthorizationCallback)callback;

/*! @internal
Expand Down
12 changes: 6 additions & 6 deletions Source/OIDAuthState.m
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,14 @@ @implementation OIDAuthState

#pragma mark - Convenience initializers

+ (id<OIDAuthorizationFlowSession>)
+ (id<OIDExternalUserAgentSession, OIDAuthorizationFlowSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
UICoordinator:(id<OIDAuthorizationUICoordinator>)UICoordinator
UICoordinator:(id<OIDExternalUserAgent>)externalUserAgent
callback:(OIDAuthStateAuthorizationCallback)callback {
// presents the authorization request
id<OIDAuthorizationFlowSession> authFlowSession = [OIDAuthorizationService
id<OIDExternalUserAgentSession, OIDAuthorizationFlowSession> authFlowSession = [OIDAuthorizationService
presentAuthorizationRequest:authorizationRequest
UICoordinator:UICoordinator
UICoordinator:externalUserAgent
callback:^(OIDAuthorizationResponse *_Nullable authorizationResponse,
NSError *_Nullable authorizationError) {
// inspects response and processes further if needed (e.g. authorization
Expand Down Expand Up @@ -157,15 +157,15 @@ - (nonnull instancetype)init
OID_UNAVAILABLE_USE_INITIALIZER(@selector(initWithAuthorizationResponse:tokenResponse:));

/*! @brief Creates an auth state from an authorization response.
@param response The authorization response.
@param authorizationResponse The authorization response.
*/
- (instancetype)initWithAuthorizationResponse:(OIDAuthorizationResponse *)authorizationResponse {
return [self initWithAuthorizationResponse:authorizationResponse tokenResponse:nil];
}


/*! @brief Designated initializer.
@param response The authorization response.
@param authorizationResponse The authorization response.
@discussion Creates an auth state from an authorization response and token response.
*/
- (instancetype)initWithAuthorizationResponse:(OIDAuthorizationResponse *)authorizationResponse
Expand Down
42 changes: 42 additions & 0 deletions Source/OIDAuthorizationFlowSession.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*! @file OIDAuthorizationRequest.h
@brief AppAuth iOS SDK
@copyright
Copyright 2015 Google Inc. All Rights Reserved.
@copydetails
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/*! @brief Represents an in-flight authorization flow session.
*/
@protocol OIDAuthorizationFlowSession <NSObject>

/*! @brief Clients should call this method with the result of the authorization code flow if it
becomes available.
@param URL The redirect URL invoked by the authorization server.
@discussion When the URL represented a valid authorization response, implementations
should clean up any left-over UI state from the authorization, for example by
closing the \SFSafariViewController or looback HTTP listener if those were used.
The completion block of the pending authorization request should then be invoked.
@remarks Has no effect if called more than once, or after a @c cancel message was received.
@return YES if the passed URL matches the expected redirect URL and was consumed, NO otherwise.
*/
- (BOOL)resumeAuthorizationFlowWithURL:(NSURL *)URL;

/*! @brief @c OIDExternalUserAgent implementations should call this method when the
authorization flow failed with a non-OAuth error.
@param error The error that is the reason for the failure of this authorization flow.
@remarks Has no effect if called more than once, or after a @c cancel message was received.
*/
- (void)failAuthorizationFlowWithError:(NSError *)error;

@end
3 changes: 2 additions & 1 deletion Source/OIDAuthorizationRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

// These files only declare string constants useful for constructing a @c OIDAuthorizationRequest,
// so they are imported here for convenience.
#import "OIDExternalUserAgentRequest.h"
#import "OIDResponseTypes.h"
#import "OIDScopes.h"

Expand All @@ -37,7 +38,7 @@ extern NSString *const OIDOAuthorizationRequestCodeChallengeMethodS256;
@see https://tools.ietf.org/html/rfc6749#section-4
@see https://tools.ietf.org/html/rfc6749#section-4.1.1
*/
@interface OIDAuthorizationRequest : NSObject <NSCopying, NSSecureCoding> {
@interface OIDAuthorizationRequest : NSObject <NSCopying, NSSecureCoding, OIDExternalUserAgentRequest> {
// property variables
OIDServiceConfiguration *_configuration;
NSString *_responseType;
Expand Down
10 changes: 10 additions & 0 deletions Source/OIDAuthorizationRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,14 @@ - (NSURL *)authorizationRequestURL {
return [query URLByReplacingQueryInURL:_configuration.authorizationEndpoint];
}

#pragma mark - OIDExternalUserAgentRequest

- (NSURL *)externalUserAgentRequestURL {
return [self authorizationRequestURL];
}

- (NSString *)redirectScheme {
return [[self redirectURL] scheme];
}

@end
47 changes: 7 additions & 40 deletions Source/OIDAuthorizationService.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
@class OIDTokenRequest;
@class OIDTokenResponse;
@protocol OIDAuthorizationFlowSession;
@protocol OIDAuthorizationUICoordinator;
@protocol OIDExternalUserAgent;
@protocol OIDExternalUserAgentSession;

NS_ASSUME_NONNULL_BEGIN

Expand Down Expand Up @@ -115,13 +116,13 @@ typedef void (^OIDRegistrationCompletion)(OIDRegistrationResponse *_Nullable reg
@param UICoordinator Generic authorization UI coordinator that can present an authorization
request.
@param callback The method called when the request has completed or failed.
@return A @c OIDAuthorizationFlowSession instance which will terminate when it
receives a @c OIDAuthorizationFlowSession.cancel message, or after processing a
@c OIDAuthorizationFlowSession.resumeAuthorizationFlowWithURL: message.
@return A @c OIDExternalUserAgentSession instance which will terminate when it
receives a @c OIDExternalUserAgentSession.cancel message, or after processing a
@c OIDExternalUserAgentSession.resumeExternalUserAgentFlowWithURL: message.
*/
+ (id<OIDAuthorizationFlowSession>)
+ (id<OIDExternalUserAgentSession, OIDAuthorizationFlowSession>)
presentAuthorizationRequest:(OIDAuthorizationRequest *)request
UICoordinator:(id<OIDAuthorizationUICoordinator>)UICoordinator
UICoordinator:(id<OIDExternalUserAgent>)externalUserAgent
callback:(OIDAuthorizationCallback)callback;

/*! @brief Performs a token request.
Expand All @@ -139,38 +140,4 @@ typedef void (^OIDRegistrationCompletion)(OIDRegistrationResponse *_Nullable reg

@end

/*! @brief Represents an in-flight authorization flow session.
*/
@protocol OIDAuthorizationFlowSession <NSObject>

/*! @brief Cancels the code flow session, invoking the request's callback with a cancelled error.
@remarks Has no effect if called more than once, or after a
@c OIDAuthorizationFlowSession.resumeAuthorizationFlowWithURL: message was received. Will
cause an error with code: @c ::OIDErrorCodeProgramCanceledAuthorizationFlow to be passed to
the @c callback block passed to
@c OIDAuthorizationService.presentAuthorizationRequest:presentingViewController:callback:
*/
- (void)cancel;

/*! @brief Clients should call this method with the result of the authorization code flow if it
becomes available.
@param URL The redirect URL invoked by the authorization server.
@discussion When the URL represented a valid authorization response, implementations
should clean up any left-over UI state from the authorization, for example by
closing the \SFSafariViewController or looback HTTP listener if those were used.
The completion block of the pending authorization request should then be invoked.
@remarks Has no effect if called more than once, or after a @c cancel message was received.
@return YES if the passed URL matches the expected redirect URL and was consumed, NO otherwise.
*/
- (BOOL)resumeAuthorizationFlowWithURL:(NSURL *)URL;

/*! @brief @c OIDAuthorizationUICoordinator or clients should call this method when the
authorization flow failed with a non-OAuth error.
@param error The error that is the reason for the failure of this authorization flow.
@remarks Has no effect if called more than once, or after a @c cancel message was received.
*/
- (void)failAuthorizationFlowWithError:(NSError *)error;

@end

NS_ASSUME_NONNULL_END
52 changes: 30 additions & 22 deletions Source/OIDAuthorizationService.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@

#import "OIDAuthorizationRequest.h"
#import "OIDAuthorizationResponse.h"
#import "OIDAuthorizationUICoordinator.h"
#import "OIDDefines.h"
#import "OIDErrorUtilities.h"
#import "OIDAuthorizationFlowSession.h"
#import "OIDExternalUserAgent.h"
#import "OIDExternalUserAgentSession.h"
#import "OIDRegistrationRequest.h"
#import "OIDRegistrationResponse.h"
#import "OIDServiceConfiguration.h"
Expand All @@ -40,10 +42,10 @@

NS_ASSUME_NONNULL_BEGIN

@interface OIDAuthorizationFlowSessionImplementation : NSObject<OIDAuthorizationFlowSession> {
@interface OIDAuthorizationFlowSessionImplementation : NSObject<OIDExternalUserAgentSession, OIDAuthorizationFlowSession> {
// private variables
OIDAuthorizationRequest *_request;
id<OIDAuthorizationUICoordinator> _UICoordinator;
id<OIDExternalUserAgent> _UICoordinator;
OIDAuthorizationCallback _pendingauthorizationFlowCallback;
}

Expand All @@ -64,12 +66,12 @@ - (instancetype)initWithRequest:(OIDAuthorizationRequest *)request {
return self;
}

- (void)presentAuthorizationWithCoordinator:(id<OIDAuthorizationUICoordinator>)UICoordinator
- (void)presentAuthorizationWithCoordinator:(id<OIDExternalUserAgent>)UICoordinator
callback:(OIDAuthorizationCallback)authorizationFlowCallback {
_UICoordinator = UICoordinator;
_pendingauthorizationFlowCallback = authorizationFlowCallback;
BOOL authorizationFlowStarted =
[_UICoordinator presentAuthorizationRequest:_request session:self];
[_UICoordinator presentExternalUserAgentRequest:_request session:self];
if (!authorizationFlowStarted) {
NSError *safariError = [OIDErrorUtilities errorWithCode:OIDErrorCodeSafariOpenError
underlyingError:nil
Expand All @@ -79,14 +81,13 @@ - (void)presentAuthorizationWithCoordinator:(id<OIDAuthorizationUICoordinator>)U
}

- (void)cancel {
[_UICoordinator dismissAuthorizationAnimated:YES
completion:^{
NSError *error = [OIDErrorUtilities
errorWithCode:OIDErrorCodeUserCanceledAuthorizationFlow
underlyingError:nil
description:nil];
[self didFinishWithResponse:nil error:error];
}];
[_UICoordinator dismissExternalUserAgentAnimated:YES completion:^{
NSError *error = [OIDErrorUtilities
errorWithCode:OIDErrorCodeUserCanceledAuthorizationFlow
underlyingError:nil
description:nil];
[self didFinishWithResponse:nil error:error];
}];
}

- (BOOL)shouldHandleURL:(NSURL *)URL {
Expand All @@ -101,7 +102,7 @@ - (BOOL)shouldHandleURL:(NSURL *)URL {
OIDIsEqualIncludingNil(standardizedURL.path, standardizedRedirectURL.path);
}

- (BOOL)resumeAuthorizationFlowWithURL:(NSURL *)URL {
- (BOOL)resumeExternalUserAgentFlowWithURL:(NSURL *)URL {
// rejects URLs that don't match redirect (these may be completely unrelated to the authorization)
if (![self shouldHandleURL:URL]) {
return NO;
Expand Down Expand Up @@ -145,15 +146,14 @@ - (BOOL)resumeAuthorizationFlowWithURL:(NSURL *)URL {
}
}

[_UICoordinator dismissAuthorizationAnimated:YES
completion:^{
[self didFinishWithResponse:response error:error];
}];
[_UICoordinator dismissExternalUserAgentAnimated:YES completion:^{
[self didFinishWithResponse:response error:error];
}];

return YES;
}

- (void)failAuthorizationFlowWithError:(NSError *)error {
- (void)failExternalUserAgentFlowWithError:(NSError *)error {
[self didFinishWithResponse:nil error:error];
}

Expand All @@ -171,6 +171,14 @@ - (void)didFinishWithResponse:(nullable OIDAuthorizationResponse *)response
}
}

- (void)failAuthorizationFlowWithError:(NSError *)error {
[self failExternalUserAgentFlowWithError:error];
}

- (BOOL)resumeAuthorizationFlowWithURL:(NSURL *)URL {
return [self resumeExternalUserAgentFlowWithURL:URL];
}

@end

@implementation OIDAuthorizationService
Expand Down Expand Up @@ -245,13 +253,13 @@ + (void)discoverServiceConfigurationForDiscoveryURL:(NSURL *)discoveryURL

#pragma mark - Authorization Endpoint

+ (id<OIDAuthorizationFlowSession>)
+ (id<OIDExternalUserAgentSession, OIDAuthorizationFlowSession>)
presentAuthorizationRequest:(OIDAuthorizationRequest *)request
UICoordinator:(id<OIDAuthorizationUICoordinator>)UICoordinator
UICoordinator:(id<OIDExternalUserAgent>)externalUserAgent
callback:(OIDAuthorizationCallback)callback {
OIDAuthorizationFlowSessionImplementation *flowSession =
[[OIDAuthorizationFlowSessionImplementation alloc] initWithRequest:request];
[flowSession presentAuthorizationWithCoordinator:UICoordinator callback:callback];
[flowSession presentAuthorizationWithCoordinator:externalUserAgent callback:callback];
return flowSession;
}

Expand Down
Loading

0 comments on commit a100a7b

Please sign in to comment.