From e7d72efdcbc1dbd5ca6b154b685cc198b7b0ff2c Mon Sep 17 00:00:00 2001 From: Hernan Zalazar Date: Thu, 7 May 2015 12:47:00 -0300 Subject: [PATCH 1/7] Avoid using APIClient singleton in IdP authenticators. --- Lock/Podfile.lock | 2 +- Pod/Classes/Core/A0APIClientProvider.h | 34 +++++++++++++ .../Private/NSObject+A0APIClientProvider.h | 32 +++++++++++++ .../Private/NSObject+A0APIClientProvider.m | 32 +++++++++++++ Pod/Classes/Provider/A0BaseAuthenticator.h | 34 +++++++++++++ Pod/Classes/Provider/A0BaseAuthenticator.m | 48 +++++++++++++++++++ Pod/Classes/Provider/A0WebAuthenticator.h | 4 +- Pod/Classes/Provider/A0WebAuthenticator.m | 4 +- .../Facebook/A0FacebookAuthenticator.h | 5 +- .../Facebook/A0FacebookAuthenticator.m | 11 +++-- .../GooglePlus/A0GooglePlusAuthenticator.h | 4 +- .../GooglePlus/A0GooglePlusAuthenticator.m | 4 +- .../Provider/Twitter/A0TwitterAuthenticator.h | 4 +- .../Provider/Twitter/A0TwitterAuthenticator.m | 3 +- 14 files changed, 205 insertions(+), 16 deletions(-) create mode 100644 Pod/Classes/Core/A0APIClientProvider.h create mode 100644 Pod/Classes/Core/Private/NSObject+A0APIClientProvider.h create mode 100644 Pod/Classes/Core/Private/NSObject+A0APIClientProvider.m create mode 100644 Pod/Classes/Provider/A0BaseAuthenticator.h create mode 100644 Pod/Classes/Provider/A0BaseAuthenticator.m diff --git a/Lock/Podfile.lock b/Lock/Podfile.lock index b47fb557b..b26bed328 100644 --- a/Lock/Podfile.lock +++ b/Lock/Podfile.lock @@ -203,4 +203,4 @@ SPEC CHECKSUMS: TouchIDAuth: f63596baf1c23d85211ab7a3b4bea794d73f3e36 TWReverseAuth: d2deef3521fa6bee32eabab67f114c2c4a53d4f5 -COCOAPODS: 0.37.0 +COCOAPODS: 0.37.1 diff --git a/Pod/Classes/Core/A0APIClientProvider.h b/Pod/Classes/Core/A0APIClientProvider.h new file mode 100644 index 000000000..19b73a63a --- /dev/null +++ b/Pod/Classes/Core/A0APIClientProvider.h @@ -0,0 +1,34 @@ + +// A0APIClientProvider.h +// +// Copyright (c) 2014 Auth0 (http://auth0.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +@class A0APIClient; + +@protocol A0APIClientProvider + +@required + +- (A0APIClient *)apiClient; + +@end diff --git a/Pod/Classes/Core/Private/NSObject+A0APIClientProvider.h b/Pod/Classes/Core/Private/NSObject+A0APIClientProvider.h new file mode 100644 index 000000000..129ef3e99 --- /dev/null +++ b/Pod/Classes/Core/Private/NSObject+A0APIClientProvider.h @@ -0,0 +1,32 @@ +// NSObject+A0APIClientProvider.h +// +// Copyright (c) 2015 Auth0 (http://auth0.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import +#import "A0APIClientProvider.h" + +@class A0APIClient; + +@interface NSObject (A0APIClientProvider) + +- (A0APIClient *)a0_apiClientFromProvider:(id)provider; + +@end diff --git a/Pod/Classes/Core/Private/NSObject+A0APIClientProvider.m b/Pod/Classes/Core/Private/NSObject+A0APIClientProvider.m new file mode 100644 index 000000000..0148405a3 --- /dev/null +++ b/Pod/Classes/Core/Private/NSObject+A0APIClientProvider.m @@ -0,0 +1,32 @@ +// NSObject+A0APIClientProvider.m +// +// Copyright (c) 2015 Auth0 (http://auth0.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "NSObject+A0APIClientProvider.h" +#import "A0APIClient.h" + +@implementation NSObject (A0APIClientProvider) + +- (A0APIClient *)a0_apiClientFromProvider:(id)provider { + return [provider apiClient] ?: [A0APIClient sharedClient]; +} + +@end diff --git a/Pod/Classes/Provider/A0BaseAuthenticator.h b/Pod/Classes/Provider/A0BaseAuthenticator.h new file mode 100644 index 000000000..22cc5875d --- /dev/null +++ b/Pod/Classes/Provider/A0BaseAuthenticator.h @@ -0,0 +1,34 @@ +// A0BaseAuthenticator.h +// +// Copyright (c) 2015 Auth0 (http://auth0.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import +#import "A0APIClientProvider.h" +#import "A0AuthenticationProvider.h" + +@interface A0BaseAuthenticator : NSObject + +/** + * Object that will yield a configured Auth0 Auth API client. + */ +@property (weak, nonatomic) id clientProvider; + +@end diff --git a/Pod/Classes/Provider/A0BaseAuthenticator.m b/Pod/Classes/Provider/A0BaseAuthenticator.m new file mode 100644 index 000000000..388734013 --- /dev/null +++ b/Pod/Classes/Provider/A0BaseAuthenticator.m @@ -0,0 +1,48 @@ +// A0BaseAuthenticator.m +// +// Copyright (c) 2015 Auth0 (http://auth0.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "A0BaseAuthenticator.h" + +@implementation A0BaseAuthenticator + +- (NSString *)identifier { + [self raiseNotImplementedException]; + return nil; +} + +- (BOOL)handleURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication { + [self raiseNotImplementedException]; + return false; +} + +- (void)authenticateWithParameters:(A0AuthParameters *)parameters success:(void (^)(A0UserProfile *, A0Token *))success failure:(void (^)(NSError *))failure { + [self raiseNotImplementedException]; +} + +- (void)clearSessions { + [self raiseNotImplementedException]; +} + +- (void)raiseNotImplementedException { + [NSException raise:NSInternalInconsistencyException format:@"Method %s is not implemented", __PRETTY_FUNCTION__]; +} +@end diff --git a/Pod/Classes/Provider/A0WebAuthenticator.h b/Pod/Classes/Provider/A0WebAuthenticator.h index d69731a8d..437c44385 100644 --- a/Pod/Classes/Provider/A0WebAuthenticator.h +++ b/Pod/Classes/Provider/A0WebAuthenticator.h @@ -21,11 +21,11 @@ // THE SOFTWARE. #import -#import "A0AuthenticationProvider.h" +#import "A0BaseAuthenticator.h" @class A0Strategy, A0Application; -@interface A0WebAuthenticator : NSObject +@interface A0WebAuthenticator : A0BaseAuthenticator + (instancetype)newWebAuthenticationForStrategy:(A0Strategy *)strategy ofApplication:(A0Application *)application; diff --git a/Pod/Classes/Provider/A0WebAuthenticator.m b/Pod/Classes/Provider/A0WebAuthenticator.m index 7b2ed4c07..39668e1fb 100644 --- a/Pod/Classes/Provider/A0WebAuthenticator.m +++ b/Pod/Classes/Provider/A0WebAuthenticator.m @@ -32,6 +32,7 @@ #import "A0AuthParameters.h" #import +#import "NSObject+A0APIClientProvider.h" @interface A0WebAuthenticator () @@ -109,7 +110,8 @@ - (BOOL)handleURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication { A0Token *token = [self.authentication tokenFromURL:url error:&error]; if (token) { void(^success)(A0UserProfile *, A0Token *) = self.successBlock; - [[A0APIClient sharedClient] fetchUserProfileWithIdToken:token.idToken success:^(A0UserProfile *profile) { + A0APIClient *client = [self a0_apiClientFromProvider:self.clientProvider]; + [client fetchUserProfileWithIdToken:token.idToken success:^(A0UserProfile *profile) { if (success) { success(profile, token); } diff --git a/Pod/Classes/Provider/Facebook/A0FacebookAuthenticator.h b/Pod/Classes/Provider/Facebook/A0FacebookAuthenticator.h index 19bf961d5..e423dc250 100644 --- a/Pod/Classes/Provider/Facebook/A0FacebookAuthenticator.h +++ b/Pod/Classes/Provider/Facebook/A0FacebookAuthenticator.h @@ -21,12 +21,13 @@ // THE SOFTWARE. #import -#import "A0AuthenticationProvider.h" +#import "A0BaseAuthenticator.h" /** * `A0FacebookAuthentication` performs Facebook authentication of a user using Facebook iOS SDK. */ -@interface A0FacebookAuthenticator : NSObject +@interface A0FacebookAuthenticator : A0BaseAuthenticator + /** * Creates a new instance diff --git a/Pod/Classes/Provider/Facebook/A0FacebookAuthenticator.m b/Pod/Classes/Provider/Facebook/A0FacebookAuthenticator.m index 4dbd01140..e3e0bdc2b 100644 --- a/Pod/Classes/Provider/Facebook/A0FacebookAuthenticator.m +++ b/Pod/Classes/Provider/Facebook/A0FacebookAuthenticator.m @@ -21,15 +21,17 @@ // THE SOFTWARE. #import "A0FacebookAuthenticator.h" + +#import +#import + #import "A0Errors.h" #import "A0Strategy.h" #import "A0Application.h" #import "A0APIClient.h" #import "A0IdentityProviderCredentials.h" #import "A0AuthParameters.h" - -#import -#import +#import "NSObject+A0APIClientProvider.h" @interface A0FacebookAuthenticator () @property (strong, nonatomic) NSArray *permissions; @@ -130,11 +132,12 @@ - (NSArray *)permissionsFromParameters:(A0AuthParameters *)parameters { A0LogDebug(@"Facebook Permissions %@", permissions); return permissions; } + - (void)executeAuthenticationWithCredentials:(A0IdentityProviderCredentials *)credentials parameters:(A0AuthParameters *)parameters success:(void(^)(A0UserProfile *, A0Token *))success failure:(void(^)(NSError *))failure { - A0APIClient *client = [A0APIClient sharedClient]; + A0APIClient *client = [self a0_apiClientFromProvider:self.clientProvider]; [client authenticateWithSocialConnectionName:self.identifier credentials:credentials parameters:parameters diff --git a/Pod/Classes/Provider/GooglePlus/A0GooglePlusAuthenticator.h b/Pod/Classes/Provider/GooglePlus/A0GooglePlusAuthenticator.h index 1a1eee377..42d4dee13 100644 --- a/Pod/Classes/Provider/GooglePlus/A0GooglePlusAuthenticator.h +++ b/Pod/Classes/Provider/GooglePlus/A0GooglePlusAuthenticator.h @@ -21,12 +21,12 @@ // THE SOFTWARE. #import -#import "A0AuthenticationProvider.h" +#import "A0BaseAuthenticator.h" /** * `A0GooglePlusAuthenticator` performs Google+ authentication using Google's official SDK. */ -@interface A0GooglePlusAuthenticator : NSObject +@interface A0GooglePlusAuthenticator : A0BaseAuthenticator /** * Creates a new authenticator with default scopes (login and email) and a clientId. diff --git a/Pod/Classes/Provider/GooglePlus/A0GooglePlusAuthenticator.m b/Pod/Classes/Provider/GooglePlus/A0GooglePlusAuthenticator.m index b7a7bc764..a91059969 100644 --- a/Pod/Classes/Provider/GooglePlus/A0GooglePlusAuthenticator.m +++ b/Pod/Classes/Provider/GooglePlus/A0GooglePlusAuthenticator.m @@ -28,6 +28,7 @@ #import "A0IdentityProviderCredentials.h" #import "A0Errors.h" #import "A0AuthParameters.h" +#import "NSObject+A0APIClientProvider.h" @interface A0GooglePlusAuthenticator () @property (copy, nonatomic) void (^successBlock)(A0UserProfile *, A0Token *); @@ -113,7 +114,8 @@ - (void)finishedWithAuth:(GTMOAuth2Authentication *)auth error:(NSError *)error } else { A0LogVerbose(@"Authenticated with Google+"); A0IdentityProviderCredentials *credentials = [[A0IdentityProviderCredentials alloc] initWithAccessToken:auth.accessToken]; - [[A0APIClient sharedClient] authenticateWithSocialConnectionName:A0StrategyNameGooglePlus + A0APIClient *client = [self a0_apiClientFromProvider:self.clientProvider]; + [client authenticateWithSocialConnectionName:A0StrategyNameGooglePlus credentials:credentials parameters:self.parameters success:self.successBlock diff --git a/Pod/Classes/Provider/Twitter/A0TwitterAuthenticator.h b/Pod/Classes/Provider/Twitter/A0TwitterAuthenticator.h index e77b42077..59b303093 100644 --- a/Pod/Classes/Provider/Twitter/A0TwitterAuthenticator.h +++ b/Pod/Classes/Provider/Twitter/A0TwitterAuthenticator.h @@ -21,12 +21,12 @@ // THE SOFTWARE. #import -#import "A0AuthenticationProvider.h" +#import "A0BaseAuthenticator.h" /** * `A0TwitterAuthentication` handles the authentication using Twitter as an indentity provider. In order to obtain a valid token to send to Auth0 API, it uses reverse authentication with the user's login information obtained form iOS Twitter integration or from OAuth Web Flow performed in Safari */ -@interface A0TwitterAuthenticator : NSObject +@interface A0TwitterAuthenticator : A0BaseAuthenticator /** * Returns a new instance with your Twitter's app key & secret. Also sepcifies the callback used to go back from Safari after Oauth Web Flow. diff --git a/Pod/Classes/Provider/Twitter/A0TwitterAuthenticator.m b/Pod/Classes/Provider/Twitter/A0TwitterAuthenticator.m index be643d181..9f7f82033 100644 --- a/Pod/Classes/Provider/Twitter/A0TwitterAuthenticator.m +++ b/Pod/Classes/Provider/Twitter/A0TwitterAuthenticator.m @@ -26,6 +26,7 @@ #import "A0APIClient.h" #import "A0Application.h" #import "A0IdentityProviderCredentials.h" +#import "NSObject+A0APIClientProvider.h" #import #import @@ -296,7 +297,7 @@ + (NSDictionary *)payloadFromResponseData:(NSData *)responseData error:(NSError #pragma mark - Block handling - (void)executeSuccessWithCredentials:(A0IdentityProviderCredentials *)credentials parameters:(A0AuthParameters *)parameters { - A0APIClient *client = [A0APIClient sharedClient]; + A0APIClient *client = [self a0_apiClientFromProvider:self.clientProvider]; [client authenticateWithSocialConnectionName:self.identifier credentials:credentials parameters:parameters From e6840ebd6bcbb29442233ac3b35f83afa5517542 Mon Sep 17 00:00:00 2001 From: Hernan Zalazar Date: Thu, 7 May 2015 17:16:41 -0300 Subject: [PATCH 2/7] Create class A0Lock Only added methods to initialize it from scalar values or NSBundle --- Lock/Lock.xcodeproj/project.pbxproj | 4 + Lock/Tests/A0LockSpec.m | 159 ++++++++++++++++++++++++++++ Pod/Classes/Core/A0Lock.h | 98 +++++++++++++++++ Pod/Classes/Core/A0Lock.m | 92 ++++++++++++++++ 4 files changed, 353 insertions(+) create mode 100644 Lock/Tests/A0LockSpec.m create mode 100644 Pod/Classes/Core/A0Lock.h create mode 100644 Pod/Classes/Core/A0Lock.m diff --git a/Lock/Lock.xcodeproj/project.pbxproj b/Lock/Lock.xcodeproj/project.pbxproj index 06daf7c38..a0fd72584 100644 --- a/Lock/Lock.xcodeproj/project.pbxproj +++ b/Lock/Lock.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 5F1DA1AB1A7BE0E000E7BA6D /* A0LockConfigurationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F1DA1AA1A7BE0E000E7BA6D /* A0LockConfigurationSpec.m */; }; 5F1DA1AD1A7C093500E7BA6D /* AppInfo.json in Resources */ = {isa = PBXBuildFile; fileRef = 5F1DA1AC1A7C093500E7BA6D /* AppInfo.json */; }; 5F22B5D619E84C28002A730A /* A0FilteredConnectionDomainMatcherSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F22B5D519E84C28002A730A /* A0FilteredConnectionDomainMatcherSpec.m */; }; + 5F22E6ED1AFBC6E80037859D /* A0LockSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F22E6EC1AFBC6E80037859D /* A0LockSpec.m */; }; 5F3237351A7A858E00B58994 /* A0AnnotatedRequestSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F3237341A7A858E00B58994 /* A0AnnotatedRequestSerializer.m */; }; 5F35161619B8CBA500574C11 /* A0UserIdentitySpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F35161519B8CBA500574C11 /* A0UserIdentitySpec.m */; }; 5F3A9C561A0D16FF00154DF2 /* Crashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F3A9C541A0D16FF00154DF2 /* Crashlytics.framework */; }; @@ -86,6 +87,7 @@ 5F1DA1AA1A7BE0E000E7BA6D /* A0LockConfigurationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = A0LockConfigurationSpec.m; sourceTree = ""; }; 5F1DA1AC1A7C093500E7BA6D /* AppInfo.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = AppInfo.json; path = ../AppInfo.json; sourceTree = ""; }; 5F22B5D519E84C28002A730A /* A0FilteredConnectionDomainMatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = A0FilteredConnectionDomainMatcherSpec.m; sourceTree = ""; }; + 5F22E6EC1AFBC6E80037859D /* A0LockSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = A0LockSpec.m; sourceTree = ""; }; 5F3237331A7A858E00B58994 /* A0AnnotatedRequestSerializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = A0AnnotatedRequestSerializer.h; path = Utils/A0AnnotatedRequestSerializer.h; sourceTree = ""; }; 5F3237341A7A858E00B58994 /* A0AnnotatedRequestSerializer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = A0AnnotatedRequestSerializer.m; path = Utils/A0AnnotatedRequestSerializer.m; sourceTree = ""; }; 5F35161519B8CBA500574C11 /* A0UserIdentitySpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = A0UserIdentitySpec.m; sourceTree = ""; }; @@ -315,6 +317,7 @@ 5FEDA4B71A1E5DC8009B1C2F /* A0PasswordValidatorSpec.m */, 5FEDA4BC1A1E60F3009B1C2F /* A0ConfirmPasswordValidatorSpec.m */, 5FEDA4C11A1E7589009B1C2F /* A0CredentialsValidatorSpec.m */, + 5F22E6EC1AFBC6E80037859D /* A0LockSpec.m */, ); path = Tests; sourceTree = ""; @@ -563,6 +566,7 @@ 5FC45F8D1AE5942400427E31 /* A0HTTPStubber.m in Sources */, 5F12365C19675EA9006CE0D2 /* A0ApplicationSpec.m in Sources */, 5F7112E519D5C18B001971BE /* A0AuthParametersSpec.m in Sources */, + 5F22E6ED1AFBC6E80037859D /* A0LockSpec.m in Sources */, 5FEDA4BD1A1E60F3009B1C2F /* A0ConfirmPasswordValidatorSpec.m in Sources */, 5F35161619B8CBA500574C11 /* A0UserIdentitySpec.m in Sources */, 5F3237351A7A858E00B58994 /* A0AnnotatedRequestSerializer.m in Sources */, diff --git a/Lock/Tests/A0LockSpec.m b/Lock/Tests/A0LockSpec.m new file mode 100644 index 000000000..f23a0be4b --- /dev/null +++ b/Lock/Tests/A0LockSpec.m @@ -0,0 +1,159 @@ +// A0LockSpec.m +// +// Copyright (c) 2015 Auth0 (http://auth0.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "Specta.h" +#import "A0Lock.h" + +#define kClientId @"1234567890" +#define kDomain @"samples.auth0.com" +#define kEUDomain @"samples.eu.auth0.com" +#define kConfigurationDomain @"myconfig.mydomain.com" + +@interface A0Lock (Testing) +- (instancetype)initWithBundleInfo:(NSDictionary *)info; +@end + + +SpecBegin(A0Lock) + +describe(@"A0Lock", ^{ + + __block A0Lock *lock; + + describe(@"initialization", ^{ + + sharedExamplesFor(@"valid Lock", ^(NSDictionary *data) { + + __block A0Lock *lock; + beforeEach(^{ + lock = data[@"lock"]; + }); + + specify(@"domain URL", ^{ + expect([[lock domainURL] absoluteString]).to.equal(data[@"domain"]); + }); + + specify(@"configuration URL", ^{ + expect([[lock configurationURL] absoluteString]).to.equal(data[@"configurationDomain"]); + }); + + specify(@"client Id", ^{ + expect([lock clientId]).to.equal(data[@"clientId"]); + }); + + }); + + itShouldBehaveLike(@"valid Lock", @{ + @"lock": [A0Lock newLockWithClientId:kClientId domain:kDomain], + @"domain": @"https://samples.auth0.com", + @"configurationDomain": [NSString stringWithFormat:@"https://cdn.auth0.com/client/%@.js", kClientId], + @"clientId": kClientId, + }); + + itShouldBehaveLike(@"valid Lock", @{ + @"lock": [A0Lock newLockWithClientId:kClientId domain:kEUDomain], + @"domain": @"https://samples.eu.auth0.com", + @"configurationDomain": [NSString stringWithFormat:@"https://cdn.eu.auth0.com/client/%@.js", kClientId], + @"clientId": kClientId, + }); + + itShouldBehaveLike(@"valid Lock", @{ + @"lock": [A0Lock newLockWithClientId:kClientId domain:@"https://overmind.auth0.com"], + @"domain": @"https://overmind.auth0.com", + @"configurationDomain": [NSString stringWithFormat:@"https://cdn.auth0.com/client/%@.js", kClientId], + @"clientId": kClientId, + }); + + itShouldBehaveLike(@"valid Lock", @{ + @"lock": [A0Lock newLockWithClientId:kClientId domain:@"https://overmind.eu.auth0.com"], + @"domain": @"https://overmind.eu.auth0.com", + @"configurationDomain": [NSString stringWithFormat:@"https://cdn.eu.auth0.com/client/%@.js", kClientId], + @"clientId": kClientId, + }); + + itShouldBehaveLike(@"valid Lock", @{ + @"lock": [A0Lock newLockWithClientId:kClientId domain:kDomain configurationDomain:kConfigurationDomain], + @"domain": @"https://samples.auth0.com", + @"configurationDomain": [NSString stringWithFormat:@"https://%@/client/%@.js", kConfigurationDomain, kClientId], + @"clientId": kClientId, + }); + itShouldBehaveLike(@"valid Lock", @{ + @"lock": [A0Lock newLockWithClientId:kClientId domain:kDomain configurationDomain:@"https://somewhere.far.beyond"], + @"domain": @"https://samples.auth0.com", + @"configurationDomain": [NSString stringWithFormat:@"https://somewhere.far.beyond/client/%@.js", kClientId], + @"clientId": kClientId, + }); + + + itShouldBehaveLike(@"valid Lock", @{ + @"lock": [A0Lock newLockWithClientId:kClientId domain:kDomain configurationDomain:@"https://somewhere.far.beyond"], + @"domain": @"https://samples.auth0.com", + @"configurationDomain": [NSString stringWithFormat:@"https://somewhere.far.beyond/client/%@.js", kClientId], + @"clientId": kClientId, + }); + + itShouldBehaveLike(@"valid Lock", @{ + @"lock": [[A0Lock alloc] initWithBundleInfo:@{ + @"Auth0ClientId": kClientId, + @"Auth0Tenant": @"samples", + }], + @"domain": @"https://samples.auth0.com", + @"configurationDomain": [NSString stringWithFormat:@"https://cdn.auth0.com/client/%@.js", kClientId], + @"clientId": kClientId, + }); + + itShouldBehaveLike(@"valid Lock", @{ + @"lock": [[A0Lock alloc] initWithBundleInfo:@{ + @"Auth0ClientId": kClientId, + @"Auth0Domain": kDomain, + }], + @"domain": @"https://samples.auth0.com", + @"configurationDomain": [NSString stringWithFormat:@"https://cdn.auth0.com/client/%@.js", kClientId], + @"clientId": kClientId, + }); + + itShouldBehaveLike(@"valid Lock", @{ + @"lock": [[A0Lock alloc] initWithBundleInfo:@{ + @"Auth0ClientId": kClientId, + @"Auth0Domain": kEUDomain, + }], + @"domain": @"https://samples.eu.auth0.com", + @"configurationDomain": [NSString stringWithFormat:@"https://cdn.eu.auth0.com/client/%@.js", kClientId], + @"clientId": kClientId, + }); + + itShouldBehaveLike(@"valid Lock", @{ + @"lock": [[A0Lock alloc] initWithBundleInfo:@{ + @"Auth0ClientId": kClientId, + @"Auth0Domain": kEUDomain, + @"Auth0ConfigurationDomain": kConfigurationDomain + }], + @"domain": @"https://samples.eu.auth0.com", + @"configurationDomain": [NSString stringWithFormat:@"https://%@/client/%@.js", kConfigurationDomain, kClientId], + @"clientId": kClientId, + }); + + }); + +}); + +SpecEnd diff --git a/Pod/Classes/Core/A0Lock.h b/Pod/Classes/Core/A0Lock.h new file mode 100644 index 000000000..663b57d6e --- /dev/null +++ b/Pod/Classes/Core/A0Lock.h @@ -0,0 +1,98 @@ +// A0Lock.h +// +// Copyright (c) 2015 Auth0 (http://auth0.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +/** + * Main interface with Auth0 Lock for iOS. + */ +@interface A0Lock : NSObject + +/** + * Auth0 account's client identifier + */ +@property (strong, readonly, nonatomic) NSString *clientId; +/** + * Auth0 account's domain URL + */ +@property (strong, readonly, nonatomic) NSURL *domainURL; +/** + * Auth0 account's application info URL. By default is Auth0 CDN (EU or US). + */ +@property (strong, readonly, nonatomic) NSURL *configurationURL; + +/** + * Initialise a new instance with values from NSBundle + * + * @return an instance of A0Lock + */ +- (instancetype)init; + +/** + * Initialise a new instance with a clientId and domain + * + * @param clientId account clientId + * @param domain account domain, it can be a full URL or just the domain name e.g.: samples.auth0.com. + * + * @return an instance of A0Lock + */ +- (instancetype)initWithClientId:(NSString *)clientId + domain:(NSString *)domain; + +/** + * Initialise a new instance with a clientId and domain + * + * @param clientId account clientId + * @param domain account domain, it can be a full URL or just the domain name e.g.: samples.auth0.com. + * @param configurationDomain domain where the account configuration can be obtained. By default https://cdn.auth0.com for US or https://cdn.eu.auth0.com for EU + * + * @return an instance of A0Lock + */ +- (instancetype)initWithClientId:(NSString *)clientId + domain:(NSString *)domain + configurationDomain:(NSString *)configurationDomain; + +/** + * Creates a new instance of Lock with a clientId and domain + * + * @param clientId account client identifier + * @param domain account domain + * + * @return a new instance + */ ++ (instancetype)newLockWithClientId:(NSString *)clientId + domain:(NSString *)domain; + +/** + * Creates a new instance of Lock with a clientId, domain and configuration domain. + * + * @param clientId account client identifier + * @param domain account domain + * @param configurationDomain domain where the account configuration can be obtained. By default https://cdn.auth0.com for US or https://cdn.eu.auth0.com for EU + * + * @return <#return value description#> + */ ++ (instancetype)newLockWithClientId:(NSString *)clientId + domain:(NSString *)domain + configurationDomain:(NSString *)configurationDomain; + +@end diff --git a/Pod/Classes/Core/A0Lock.m b/Pod/Classes/Core/A0Lock.m new file mode 100644 index 000000000..c198b0ea0 --- /dev/null +++ b/Pod/Classes/Core/A0Lock.m @@ -0,0 +1,92 @@ +// A0Lock.m +// +// Copyright (c) 2015 Auth0 (http://auth0.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "A0Lock.h" + +#define kCDNConfigurationURL @"https://cdn.auth0.com" +#define kEUCDNConfigurationURL @"https://cdn.eu.auth0.com" + +#define kClientIdKey @"Auth0ClientId" +#define kTenantKey @"Auth0Tenant" +#define kDomainKey @"Auth0Domain" +#define kConfigurationDomainKey @"Auth0ConfigurationDomain" + +@interface NSURL (A0Lock) + ++ (instancetype)URLWithAuth0Domain:(NSString *)domain; + +@end + +@implementation NSURL (A0Lock) + ++ (instancetype)URLWithAuth0Domain:(NSString *)domain { + NSURL *url = [domain hasPrefix:@"http"] ? [NSURL URLWithString:domain] : [NSURL URLWithString:[@"https://" stringByAppendingString:domain]]; + return url; +} + +@end + +@implementation A0Lock + +- (instancetype)init { + return [self initWithBundleInfo:[[NSBundle mainBundle] infoDictionary]]; +} + +- (instancetype)initWithBundleInfo:(NSDictionary *)info { + NSString *tenant = info[kTenantKey]; + NSString *clientId = info[kClientIdKey]; + NSString *domain = info[kDomainKey]; + NSString *configurationDomain = info[kConfigurationDomainKey]; + if (configurationDomain) { + return [self initWithClientId:clientId domain:domain ?: [NSString stringWithFormat:@"https://%@.auth0.com", tenant] configurationDomain:configurationDomain]; + } + return [self initWithClientId:clientId domain:domain ?: [NSString stringWithFormat:@"https://%@.auth0.com", tenant]]; +} + +- (instancetype)initWithClientId:(NSString *)clientId domain:(NSString *)domain { + NSURL *domainURL = [NSURL URLWithAuth0Domain:domain]; + NSURL *configurationURL = [domainURL.host hasSuffix:@".eu.auth0.com"] ? [NSURL URLWithString:kEUCDNConfigurationURL] : [NSURL URLWithString:kCDNConfigurationURL]; + return [self initWithClientId:clientId domain:domain configurationDomain:configurationURL.absoluteString]; +} + +- (instancetype)initWithClientId:(NSString *)clientId domain:(NSString *)domain configurationDomain:(NSString *)configurationDomain { + self = [super init]; + if (self) { + _clientId = clientId; + _domainURL = [NSURL URLWithAuth0Domain:domain]; + NSString *clientPath = [[@"client" stringByAppendingPathComponent:clientId] stringByAppendingPathExtension:@"js"]; + NSURL *configurationURL = [NSURL URLWithAuth0Domain:configurationDomain]; + _configurationURL = [NSURL URLWithString:clientPath relativeToURL:configurationURL]; + } + + return self; +} + ++ (instancetype)newLockWithClientId:(NSString *)clientId domain:(NSString *)domain { + return [[A0Lock alloc] initWithClientId:clientId domain:domain]; +} + ++ (instancetype)newLockWithClientId:(NSString *)clientId domain:(NSString *)domain configurationDomain:(NSString *)configurationDomain { + return [[A0Lock alloc] initWithClientId:clientId domain:domain configurationDomain:configurationDomain]; +} + +@end From 6dbdb18e8d19e5ae129e866abf61a65df1cf75dc Mon Sep 17 00:00:00 2001 From: Hernan Zalazar Date: Thu, 7 May 2015 18:54:47 -0300 Subject: [PATCH 3/7] Return A0APIClient to conform to protocol. A0Lock conforms to protocol A0APIClientProvider. Added logging to init methods. Raise NSException on debug when init params are invalid. --- Lock/Tests/A0LockSpec.m | 52 ++++++++++++++++++++++++++++++-- Pod/Classes/Core/A0APIv1Router.h | 2 ++ Pod/Classes/Core/A0APIv1Router.m | 12 ++++++++ Pod/Classes/Core/A0Lock.h | 17 +++++++++-- Pod/Classes/Core/A0Lock.m | 16 ++++++++++ 5 files changed, 95 insertions(+), 4 deletions(-) diff --git a/Lock/Tests/A0LockSpec.m b/Lock/Tests/A0LockSpec.m index f23a0be4b..ff9520261 100644 --- a/Lock/Tests/A0LockSpec.m +++ b/Lock/Tests/A0LockSpec.m @@ -37,8 +37,6 @@ - (instancetype)initWithBundleInfo:(NSDictionary *)info; describe(@"A0Lock", ^{ - __block A0Lock *lock; - describe(@"initialization", ^{ sharedExamplesFor(@"valid Lock", ^(NSDictionary *data) { @@ -152,6 +150,56 @@ - (instancetype)initWithBundleInfo:(NSDictionary *)info; @"clientId": kClientId, }); + + it(@"should fail to create", ^{ + expect(^{ + [A0Lock newLockWithClientId:nil domain:nil]; + }).to.raise(NSInternalInconsistencyException); + }); + + it(@"should fail to create", ^{ + expect(^{ + [A0Lock newLockWithClientId:kClientId domain:nil]; + }).to.raise(NSInternalInconsistencyException); + }); + + it(@"should fail to create", ^{ + expect(^{ + [A0Lock newLockWithClientId:nil domain:kDomain]; + }).to.raise(NSInternalInconsistencyException); + }); + + it(@"should fail to create", ^{ + expect(^{ + [A0Lock newLockWithClientId:nil domain:nil configurationDomain:nil]; + }).to.raise(NSInternalInconsistencyException); + }); + + it(@"should fail to create", ^{ + expect(^{ + [A0Lock newLockWithClientId:kClientId domain:nil configurationDomain:nil]; + }).to.raise(NSInternalInconsistencyException); + }); + + it(@"should fail to create", ^{ + expect(^{ + [A0Lock newLockWithClientId:nil domain:kDomain configurationDomain:nil]; + }).to.raise(NSInternalInconsistencyException); + + }); + + it(@"should fail to create", ^{ + expect(^{ + [A0Lock newLockWithClientId:nil domain:nil configurationDomain:kConfigurationDomain]; + }).to.raise(NSInternalInconsistencyException); + }); + + it(@"should fail to create", ^{ + expect(^{ + NSAssert([[A0Lock alloc] initWithBundleInfo:@{}], @"Non nil"); + }).to.raise(NSInternalInconsistencyException); + }); + }); }); diff --git a/Pod/Classes/Core/A0APIv1Router.h b/Pod/Classes/Core/A0APIv1Router.h index 05d1c1919..fba48070a 100644 --- a/Pod/Classes/Core/A0APIv1Router.h +++ b/Pod/Classes/Core/A0APIv1Router.h @@ -25,4 +25,6 @@ @interface A0APIv1Router : NSObject +- (instancetype)initWithClientId:(NSString *)clientId domainURL:(NSURL *)domainURL configurationURL:(NSURL *)configurationURL; + @end diff --git a/Pod/Classes/Core/A0APIv1Router.m b/Pod/Classes/Core/A0APIv1Router.m index 5a66c4697..4d8efb5e7 100644 --- a/Pod/Classes/Core/A0APIv1Router.m +++ b/Pod/Classes/Core/A0APIv1Router.m @@ -53,6 +53,18 @@ @implementation A0APIv1Router AUTH0_DYNAMIC_LOGGER_METHODS +- (instancetype)initWithClientId:(NSString *)clientId domainURL:(NSURL *)domainURL configurationURL:(NSURL *)configurationURL { + self = [super init]; + if (self) { + _endpointURL = domainURL; + _configurationURL = configurationURL; + A0LogInfo(@"Base URL of API is %@", self.endpointURL); + A0LogInfo(@"Configuration URL is %@", self.configurationURL); + _clientId = clientId; + } + return self; +} + - (void)configureWithBundleInfo:(NSDictionary *)bundleInfo { NSString *domain = bundleInfo[kDomainKey]; NSString *configDomain = bundleInfo[kConfigurationDomainKey]; diff --git a/Pod/Classes/Core/A0Lock.h b/Pod/Classes/Core/A0Lock.h index 663b57d6e..c3aba9df9 100644 --- a/Pod/Classes/Core/A0Lock.h +++ b/Pod/Classes/Core/A0Lock.h @@ -21,11 +21,12 @@ // THE SOFTWARE. #import +#import "A0APIClientProvider.h" /** * Main interface with Auth0 Lock for iOS. */ -@interface A0Lock : NSObject +@interface A0Lock : NSObject /** * Auth0 account's client identifier @@ -42,6 +43,18 @@ /** * Initialise a new instance with values from NSBundle + * The valid keys are the following: + + * ClientId: "Auth0ClientId" + * Tenant: "Auth0Tenant" + * Domain: "Auth0Domain" + * Config Domain: "Auth0ConfigurationDomain" + * + * It can be any of these configurations: + * 1. Domain + Domain Config + Client Id + * 2. Domain + Client Id + * 3. Tenant + Client Id + * The order also determines the precende, so if (1) and (2) are found in the dictionary, the option (1) will be used instead of (2). * * @return an instance of A0Lock */ @@ -89,7 +102,7 @@ * @param domain account domain * @param configurationDomain domain where the account configuration can be obtained. By default https://cdn.auth0.com for US or https://cdn.eu.auth0.com for EU * - * @return <#return value description#> + * @return a new instance */ + (instancetype)newLockWithClientId:(NSString *)clientId domain:(NSString *)domain diff --git a/Pod/Classes/Core/A0Lock.m b/Pod/Classes/Core/A0Lock.m index c198b0ea0..7bd7340dd 100644 --- a/Pod/Classes/Core/A0Lock.m +++ b/Pod/Classes/Core/A0Lock.m @@ -21,6 +21,8 @@ // THE SOFTWARE. #import "A0Lock.h" +#import "A0APIv1Router.h" +#import "A0APIClient.h" #define kCDNConfigurationURL @"https://cdn.auth0.com" #define kEUCDNConfigurationURL @"https://cdn.eu.auth0.com" @@ -47,6 +49,8 @@ + (instancetype)URLWithAuth0Domain:(NSString *)domain { @implementation A0Lock +AUTH0_DYNAMIC_LOGGER_METHODS + - (instancetype)init { return [self initWithBundleInfo:[[NSBundle mainBundle] infoDictionary]]; } @@ -56,6 +60,7 @@ - (instancetype)initWithBundleInfo:(NSDictionary *)info { NSString *clientId = info[kClientIdKey]; NSString *domain = info[kDomainKey]; NSString *configurationDomain = info[kConfigurationDomainKey]; + A0LogVerbose(@"Loaded info from bundle %@", info); if (configurationDomain) { return [self initWithClientId:clientId domain:domain ?: [NSString stringWithFormat:@"https://%@.auth0.com", tenant] configurationDomain:configurationDomain]; } @@ -63,12 +68,17 @@ - (instancetype)initWithBundleInfo:(NSDictionary *)info { } - (instancetype)initWithClientId:(NSString *)clientId domain:(NSString *)domain { + NSAssert(clientId.length > 0, @"Must supply a valid clientId"); + NSAssert(domain.length > 0, @"Must supply a valid domain"); NSURL *domainURL = [NSURL URLWithAuth0Domain:domain]; NSURL *configurationURL = [domainURL.host hasSuffix:@".eu.auth0.com"] ? [NSURL URLWithString:kEUCDNConfigurationURL] : [NSURL URLWithString:kCDNConfigurationURL]; return [self initWithClientId:clientId domain:domain configurationDomain:configurationURL.absoluteString]; } - (instancetype)initWithClientId:(NSString *)clientId domain:(NSString *)domain configurationDomain:(NSString *)configurationDomain { + NSAssert(clientId.length > 0, @"Must supply a valid clientId"); + NSAssert(domain.length > 0, @"Must supply a valid domain"); + NSAssert(configurationDomain.length > 0, @"Must supply a valid configuration domain"); self = [super init]; if (self) { _clientId = clientId; @@ -76,11 +86,17 @@ - (instancetype)initWithClientId:(NSString *)clientId domain:(NSString *)domain NSString *clientPath = [[@"client" stringByAppendingPathComponent:clientId] stringByAppendingPathExtension:@"js"]; NSURL *configurationURL = [NSURL URLWithAuth0Domain:configurationDomain]; _configurationURL = [NSURL URLWithString:clientPath relativeToURL:configurationURL]; + A0LogDebug(@"Auth0 Lock initialised with clientId: (%@) domainURL: (%@) configurationURL: (%@)", _clientId, _domainURL, _configurationURL); } return self; } +- (A0APIClient *)apiClient { + A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:self.clientId domainURL:self.domainURL configurationURL:self.configurationURL]; + return [[A0APIClient alloc] initWithAPIRouter:router]; +} + + (instancetype)newLockWithClientId:(NSString *)clientId domain:(NSString *)domain { return [[A0Lock alloc] initWithClientId:clientId domain:domain]; } From 513fe4735d856e4389d23aa488c3773955d13bd8 Mon Sep 17 00:00:00 2001 From: Hernan Zalazar Date: Fri, 8 May 2015 11:43:17 -0300 Subject: [PATCH 4/7] Moved Lock config to A0Lock. A0APIRouter only handles paths. A0Lock keeps a reference to router and api client. --- Lock/Podfile | 17 +- Lock/Podfile.lock | 3 + Lock/Tests/A0APIv1RouterSpec.m | 247 ++++------------------------- Pod/Classes/Core/A0APIClient.m | 10 +- Pod/Classes/Core/A0APIRouter.h | 47 ------ Pod/Classes/Core/A0APIv1Router.m | 69 ++------ Pod/Classes/Core/A0Lock.m | 30 +++- Pod/Classes/Core/A0UserAPIClient.m | 19 ++- 8 files changed, 90 insertions(+), 352 deletions(-) diff --git a/Lock/Podfile b/Lock/Podfile index 92f3c0e24..39826fb54 100644 --- a/Lock/Podfile +++ b/Lock/Podfile @@ -2,6 +2,13 @@ source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' +def pod_with_warnings + pod 'libextobjc', :inhibit_warnings => true #Ignore warnings for this lib + pod 'BDBOAuth1Manager', :inhibit_warnings => true #Ignore warnings for this lib + pod 'Facebook-iOS-SDK', :inhibit_warnings => true #Ignore warnings for this lib + pod 'ISO8601DateFormatter', :inhibit_warnings => true #Ignore warnings for this lib +end + target 'Lock', :exclusive => true do pod 'Lock', :path => '../' pod 'Lock/TouchID', :path => '../' @@ -9,8 +16,9 @@ target 'Lock', :exclusive => true do pod 'Lock/ReactiveCore', :path => '../' pod 'Lock/GooglePlus', :path => '../' pod 'Lock/1Password', :path => '../' - pod 'libextobjc', :inhibit_warnings => true #Ignore warnings for this lib - pod 'BDBOAuth1Manager', :inhibit_warnings => true #Ignore warnings for this lib + + pod_with_warnings + pod 'JWTDecode' pod 'SimpleKeychain' end @@ -19,11 +27,12 @@ target 'Tests', :exclusive => true do pod 'Lock', :path => '../' pod 'Lock/TouchID', :path => '../' pod 'Lock/SMS', :path => '../' - pod 'libextobjc', :inhibit_warnings => true #Ignore warnings for this lib - pod 'BDBOAuth1Manager', :inhibit_warnings => true #Ignore warnings for this lib + + pod_with_warnings pod 'Specta', '~> 0.5' pod 'Expecta' pod 'OCMockito' pod 'OHHTTPStubs' + pod 'OCHamcrest', :inhibit_warnings => true #Ignore warnings for this lib end diff --git a/Lock/Podfile.lock b/Lock/Podfile.lock index b26bed328..46dec56b5 100644 --- a/Lock/Podfile.lock +++ b/Lock/Podfile.lock @@ -160,6 +160,8 @@ PODS: DEPENDENCIES: - BDBOAuth1Manager - Expecta + - Facebook-iOS-SDK + - ISO8601DateFormatter - JWTDecode - libextobjc - Lock (from `../`) @@ -168,6 +170,7 @@ DEPENDENCIES: - Lock/ReactiveCore (from `../`) - Lock/SMS (from `../`) - Lock/TouchID (from `../`) + - OCHamcrest - OCMockito - OHHTTPStubs - SimpleKeychain diff --git a/Lock/Tests/A0APIv1RouterSpec.m b/Lock/Tests/A0APIv1RouterSpec.m index 3b71e01c2..cebd29e75 100644 --- a/Lock/Tests/A0APIv1RouterSpec.m +++ b/Lock/Tests/A0APIv1RouterSpec.m @@ -23,250 +23,59 @@ #import "Specta.h" #import "A0APIv1Router.h" -#define kTenant @"overmind" -#define kClientId @"1234567890" -#define kDomainURL @"https://domain.somewhere.co" -#define kAuth0Domain @"https://overmind.auth0.com" -#define kAuth0EUDomain @"https://overmind.eu.auth0.com" -#define kConfigurationURL @"https://configuration.somewhere.co" - -#define kClientIdKey @"Auth0ClientId" -#define kTenantKey @"Auth0Tenant" -#define kDomainKey @"Auth0Domain" -#define kConfigurationDomainKey @"Auth0ConfigurationDomain" - SpecBegin(A0APIv1Router) describe(@"A0APIv1Router", ^{ __block A0APIv1Router *router; - beforeEach(^{ - router = [[A0APIv1Router alloc] init]; + specify(@"default initializer should fail", ^{ + expect(^{ + router = [[A0APIv1Router alloc] init]; + }).to.raise(NSInternalInconsistencyException); }); - specify(@"default initializer", ^{ - router = [[A0APIv1Router alloc] init]; - expect(router).notTo.beNil(); + beforeEach(^{ + router = [[A0APIv1Router alloc] initWithClientId:@"1234567890" + domainURL:[NSURL URLWithString:@"https://samples.auth0.com"] + configurationURL:[NSURL URLWithString:@"https://cdn.auth0.com/client/1234567890.js"]]; }); - context(@"configure with tenant and client id", ^{ - - beforeEach(^{ - [router configureForTenant:kTenant clientId:kClientId]; - }); - - it(@"should have correct endpoint URL", ^{ - expect(router.endpointURL.absoluteString).to.equal(@"https://overmind.auth0.com"); - }); - - it(@"should have correct config URL", ^{ - expect(router.configurationURL.absoluteString).to.equal(@"https://cdn.auth0.com/client/1234567890.js"); - }); - - it(@"should fail with nil tenant", ^{ - expect(^{ - [router configureForTenant:nil clientId:kClientId]; - }).to.raise(NSInternalInconsistencyException); - }); - - it(@"should fail with nil client id", ^{ - expect(^{ - [router configureForTenant:kTenant clientId:nil]; - }).to.raise(NSInternalInconsistencyException); - }); - + specify(@"client identifier", ^{ + expect(router.clientId).to.equal(@"1234567890"); }); - context(@"configure with domain and config URL", ^{ - - beforeEach(^{ - [router configureForDomain:kDomainURL configurationDomain:kConfigurationURL clientId:kClientId]; - }); - - it(@"should have correct endpoint URL", ^{ - expect(router.endpointURL.absoluteString).to.equal(@"https://domain.somewhere.co"); - }); - - it(@"should have correct config URL", ^{ - expect(router.configurationURL.absoluteString).to.equal(@"https://configuration.somewhere.co/client/1234567890.js"); - }); - - it(@"should fail with nil domain", ^{ - expect(^{ - [router configureForDomain:nil configurationDomain:kConfigurationURL clientId:kClientId]; - }).to.raise(NSInternalInconsistencyException); - }); - - it(@"should fail with nil config", ^{ - expect(^{ - [router configureForDomain:kDomainURL configurationDomain:nil clientId:kClientId]; - }).to.raise(NSInternalInconsistencyException); - }); - - it(@"should fail with nil client id", ^{ - expect(^{ - [router configureForDomain:kDomainURL configurationDomain:kConfigurationURL clientId:nil]; - }).to.raise(NSInternalInconsistencyException); - }); - + specify(@"domain URL", ^{ + expect(router.endpointURL.absoluteString).equal(@"https://samples.auth0.com"); }); - context(@"configure with auth0 domain only", ^{ - - beforeEach(^{ - [router configureForDomain:kAuth0Domain clientId:kClientId]; - }); - - it(@"should have correct endpoint URL", ^{ - expect(router.endpointURL.absoluteString).to.equal(@"https://overmind.auth0.com"); - }); - - it(@"should have correct config URL", ^{ - expect(router.configurationURL.absoluteString).to.equal(@"https://cdn.auth0.com/client/1234567890.js"); - }); - + specify(@"configuration URL", ^{ + expect(router.configurationURL.absoluteString).equal(@"https://cdn.auth0.com/client/1234567890.js"); }); - context(@"configure with auth0 EU domain only", ^{ - - beforeEach(^{ - [router configureForDomain:kAuth0EUDomain clientId:kClientId]; - }); - - it(@"should have correct endpoint URL", ^{ - expect(router.endpointURL.absoluteString).to.equal(@"https://overmind.eu.auth0.com"); - }); - - it(@"should have correct config URL", ^{ - expect(router.configurationURL.absoluteString).to.equal(@"https://cdn.eu.auth0.com/client/1234567890.js"); - }); - + specify(@"tenant", ^{ + expect(router.tenant).to.equal(@"samples"); }); - context(@"configure with auth0 domain without protocol", ^{ - - beforeEach(^{ - [router configureForDomain:@"overmind.auth0.com" clientId:kClientId]; - }); - - it(@"should have correct endpoint URL", ^{ - expect(router.endpointURL.absoluteString).to.equal(@"https://overmind.auth0.com"); - }); - - it(@"should have correct config URL", ^{ - expect(router.configurationURL.absoluteString).to.equal(@"https://cdn.auth0.com/client/1234567890.js"); - }); - + specify(@"should fail with invalid client id", ^{ + expect(^{ + router = [[A0APIv1Router alloc] initWithClientId:nil domainURL:[NSURL URLWithString:@"https://samples.auth0.com"] configurationURL:[NSURL URLWithString:@"https://cdn.auth0.com/client/1234567890.js"]]; + }).to.raise(NSInternalInconsistencyException); }); - context(@"configure with non auth0 domain only", ^{ - - beforeEach(^{ - [router configureForDomain:kDomainURL clientId:kClientId]; - }); - - it(@"should have correct endpoint URL", ^{ - expect(router.endpointURL.absoluteString).to.equal(@"https://domain.somewhere.co"); - }); - - it(@"should have correct config URL", ^{ - expect(router.configurationURL.absoluteString).to.equal(@"https://domain.somewhere.co/client/1234567890.js"); - }); - - it(@"should fail with nil domain", ^{ - expect(^{ - [router configureForDomain:nil clientId:kClientId]; - }).to.raise(NSInternalInconsistencyException); - }); - - it(@"should fail with nil client id", ^{ - expect(^{ - [router configureForDomain:kDomainURL clientId:nil]; - }).to.raise(NSInternalInconsistencyException); - }); - + specify(@"should fail with invalid domain URL", ^{ + expect(^{ + router = [[A0APIv1Router alloc] initWithClientId:@"1234567890" domainURL:nil configurationURL:[NSURL URLWithString:@"https://cdn.auth0.com/client/1234567890.js"]]; + }).to.raise(NSInternalInconsistencyException); }); - sharedExamplesFor(@"configured from bundle", ^(NSDictionary *data) { - - beforeEach(^{ - [router configureWithBundleInfo:data[@"info"]]; - }); - - it(@"should have correct endpoint URL", ^{ - expect(router.endpointURL.absoluteString).to.equal(data[@"endpoint"]); - }); - - it(@"should have correct config URL", ^{ - expect(router.configurationURL.absoluteString).to.equal(data[@"config"]); - }); + specify(@"should fail with invalid configuration URL", ^{ + expect(^{ + router = [[A0APIv1Router alloc] initWithClientId:@"1234567890" domainURL:[NSURL URLWithString:@"https://samples.auth0.com"] configurationURL:nil]; + }).to.raise(NSInternalInconsistencyException); }); - - itShouldBehaveLike(@"configured from bundle", @{ - @"info": @{ - kTenantKey: kTenant, - kClientIdKey: kClientId, - }, - @"endpoint": @"https://overmind.auth0.com", - @"config": @"https://cdn.auth0.com/client/1234567890.js", - }); - itShouldBehaveLike(@"configured from bundle", @{ - @"info": @{ - kDomainKey: kDomainURL, - kClientIdKey: kClientId, - }, - @"endpoint": @"https://domain.somewhere.co", - @"config": @"https://domain.somewhere.co/client/1234567890.js", - }); - itShouldBehaveLike(@"configured from bundle", @{ - @"info": @{ - kDomainKey: kAuth0Domain, - kClientIdKey: kClientId, - }, - @"endpoint": @"https://overmind.auth0.com", - @"config": @"https://cdn.auth0.com/client/1234567890.js", - }); - itShouldBehaveLike(@"configured from bundle", @{ - @"info": @{ - kDomainKey: kDomainURL, - kConfigurationDomainKey: kConfigurationURL, - kClientIdKey: kClientId, - }, - @"endpoint": @"https://domain.somewhere.co", - @"config": @"https://configuration.somewhere.co/client/1234567890.js", - }); - itShouldBehaveLike(@"configured from bundle", @{ - @"info": @{ - kTenantKey: kTenant, - kDomainKey: kDomainURL, - kConfigurationDomainKey: kConfigurationURL, - kClientIdKey: kClientId, - }, - @"endpoint": @"https://domain.somewhere.co", - @"config": @"https://configuration.somewhere.co/client/1234567890.js", - }); - itShouldBehaveLike(@"configured from bundle", @{ - @"info": @{ - kTenantKey: kTenant, - kDomainKey: kDomainURL, - kClientIdKey: kClientId, - }, - @"endpoint": @"https://domain.somewhere.co", - @"config": @"https://domain.somewhere.co/client/1234567890.js", - }); - itShouldBehaveLike(@"configured from bundle", @{ - @"info": @{ - kTenantKey: kTenant, - kDomainKey: kAuth0Domain, - kClientIdKey: kClientId, - }, - @"endpoint": @"https://overmind.auth0.com", - @"config": @"https://cdn.auth0.com/client/1234567890.js", - }); - }); SpecEnd diff --git a/Pod/Classes/Core/A0APIClient.m b/Pod/Classes/Core/A0APIClient.m index 27f24ef27..cd3a4a43f 100644 --- a/Pod/Classes/Core/A0APIClient.m +++ b/Pod/Classes/Core/A0APIClient.m @@ -36,6 +36,7 @@ #import #import "A0UserAPIClient.h" #import "A0APIv1Router.h" +#import "A0Lock.h" #define kClientIdParamName @"client_id" #define kUsernameParamName @"username" @@ -67,8 +68,8 @@ @implementation A0APIClient - (instancetype)initWithClientId:(NSString *)clientId andTenant:(NSString *)tenant { NSAssert(clientId, @"You must supply your Auth0 app's Client Id."); NSAssert(tenant, @"You must supply your Auth0 app's Tenant."); - A0APIv1Router *router = [[A0APIv1Router alloc] init]; - [router configureForTenant:tenant clientId:clientId]; + A0Lock *lock = [A0Lock newLockWithClientId:clientId domain:[NSString stringWithFormat:@"https://%@.auth0.com", tenant]]; + A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; return [self initWithAPIRouter:router]; } @@ -92,10 +93,7 @@ + (instancetype)sharedClient { static A0APIClient *client; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - NSDictionary *info = [[NSBundle mainBundle] infoDictionary]; - A0APIv1Router *router = [[A0APIv1Router alloc] init]; - [router configureWithBundleInfo:info]; - client = [[A0APIClient alloc] initWithAPIRouter:router]; + client = [[A0Lock new] apiClient]; }); return client; } diff --git a/Pod/Classes/Core/A0APIRouter.h b/Pod/Classes/Core/A0APIRouter.h index ae7efec20..94b5328b9 100644 --- a/Pod/Classes/Core/A0APIRouter.h +++ b/Pod/Classes/Core/A0APIRouter.h @@ -24,12 +24,6 @@ /** * Class that handles base URL and paths of Auth0 APIs. - * It can be configured in three ways: - * 1. Tenant and Client Id - * 2. Domain and Client Id - * 3. Domain, Config Domain and Client Id. - * - * Also it can obtain its configuration from NSBundle user information. */ @protocol A0APIRouter @@ -52,47 +46,6 @@ */ @property (readonly, nonatomic) NSURL *configurationURL; -/** - * Configure router with values stored in bundle of app. - * The valid keys are the following: - - * ClientId: "Auth0ClientId" - * Tenant: "Auth0Tenant" - * Domain: "Auth0Domain" - * Config Domain: "Auth0ConfigurationDomain" - * - * It can be any of these configurations: - * 1. Domain + Domain Config + Client Id - * 2. Domain + Client Id - * 3. Tenant + Client Id - * The order also determines the precende, so if (1) and (2) are found in the dictionary, the option (1) will be used instead of (2). - * @param bundleInfo info in main bundle - */ -- (void)configureWithBundleInfo:(NSDictionary *)bundleInfo; - -/** - * Configure router with domain and client id - * - * @param domain domain url - * @param clientId id of the client - */ -- (void)configureForDomain:(NSString *)domain clientId:(NSString *)clientId; -/** - * Configure router with domain and domain config besides a client id. - * - * @param domain domain url - * @param configurationDomain config domain url - * @param clientId id of the client - */ -- (void)configureForDomain:(NSString *)domain configurationDomain:(NSString *)configurationDomain clientId:(NSString *)clientId; -/** - * Configure router with tenant and client id - * - * @param tenant name of the tenant of the account owner of the app. - * @param clientId id of the client - */ -- (void)configureForTenant:(NSString *)tenant clientId:(NSString *)clientId; - /** * `oauth/ro` path * diff --git a/Pod/Classes/Core/A0APIv1Router.m b/Pod/Classes/Core/A0APIv1Router.m index 4d8efb5e7..14082a074 100644 --- a/Pod/Classes/Core/A0APIv1Router.m +++ b/Pod/Classes/Core/A0APIv1Router.m @@ -22,15 +22,6 @@ #import "A0APIv1Router.h" -#define kAppBaseURLFormatString @"https://%@.auth0.com" -#define kCDNConfigurationURL @"https://cdn.auth0.com" -#define kEUCDNConfigurationURL @"https://cdn.eu.auth0.com" - -#define kClientIdKey @"Auth0ClientId" -#define kTenantKey @"Auth0Tenant" -#define kDomainKey @"Auth0Domain" -#define kConfigurationDomainKey @"Auth0ConfigurationDomain" - #define kLoginPath @"oauth/ro" #define kSignUpPath @"dbconnections/signup" #define kTokenInfoPath @"tokeninfo" @@ -53,7 +44,15 @@ @implementation A0APIv1Router AUTH0_DYNAMIC_LOGGER_METHODS +- (instancetype)init { + [NSException raise:NSInternalInconsistencyException format:@"Please use %@ initializer", NSStringFromSelector(@selector(initWithClientId:domainURL:configurationURL:))]; + return [super init]; +} + - (instancetype)initWithClientId:(NSString *)clientId domainURL:(NSURL *)domainURL configurationURL:(NSURL *)configurationURL { + NSAssert(clientId.length > 0, @"Must supply a valid client id"); + NSAssert(domainURL != nil, @"Must supply a non-nil domain URL"); + NSAssert(configurationURL != nil, @"Must supply a non-nil configuration URL"); self = [super init]; if (self) { _endpointURL = domainURL; @@ -61,55 +60,12 @@ - (instancetype)initWithClientId:(NSString *)clientId domainURL:(NSURL *)domainU A0LogInfo(@"Base URL of API is %@", self.endpointURL); A0LogInfo(@"Configuration URL is %@", self.configurationURL); _clientId = clientId; + NSString *host = _endpointURL.host; + _tenant = [host hasSuffix:@".auth0.com"] ? [[host componentsSeparatedByString:@"."] firstObject] : host; } return self; } -- (void)configureWithBundleInfo:(NSDictionary *)bundleInfo { - NSString *domain = bundleInfo[kDomainKey]; - NSString *configDomain = bundleInfo[kConfigurationDomainKey]; - NSString *clientId = bundleInfo[kClientIdKey]; - NSString *tenant = bundleInfo[kTenantKey]; - if (domain && configDomain) { - [self configureForDomain:domain configurationDomain:configDomain clientId:clientId]; - } else if(domain) { - [self configureForDomain:domain clientId:clientId]; - } else { - [self configureForTenant:tenant clientId:clientId]; - } -} - -- (void)configureForDomain:(NSString *)domain clientId:(NSString *)clientId { - NSURL *domainURL = [self createDomainURLFromString:domain]; - NSAssert(domainURL, @"You must supply a valid Auth0 domain."); - NSString *configurationDomain = domain; - if ([domainURL.host hasSuffix:@".auth0.com"]) { - configurationDomain = [domainURL.host hasSuffix:@".eu.auth0.com"] ? kEUCDNConfigurationURL : kCDNConfigurationURL; - } - [self configureForDomain:domain configurationDomain:configurationDomain clientId:clientId]; -} - -- (void)configureForDomain:(NSString *)domain configurationDomain:(NSString *)configurationDomain clientId:(NSString *)clientId { - NSURL *domainURL = [self createDomainURLFromString:domain]; - NSURL *configurationURL = [NSURL URLWithString:configurationDomain]; - NSAssert(domainURL, @"You must supply a valid Auth0 domain."); - NSAssert(configurationURL, @"You must supply a valid Auth0 config domain."); - NSAssert(clientId, @"You must supply your Auth0 app's Client Id."); - self.endpointURL = domainURL; - NSString *clientPath = [[@"client" stringByAppendingPathComponent:clientId] stringByAppendingPathExtension:@"js"]; - self.configurationURL = [NSURL URLWithString:clientPath relativeToURL:configurationURL]; - A0LogInfo(@"Base URL of API is %@", self.endpointURL); - A0LogInfo(@"Configuration URL is %@", self.configurationURL); - self.clientId = clientId; -} - -- (void)configureForTenant:(NSString *)tenant clientId:(NSString *)clientId { - NSAssert(tenant, @"You must supply your Auth0 app's Tenant."); - NSString *URLString = [NSString stringWithFormat:kAppBaseURLFormatString, tenant]; - [self configureForDomain:URLString configurationDomain:kCDNConfigurationURL clientId:clientId]; - self.tenant = tenant; -} - - (NSString *)loginPath { return kLoginPath; } @@ -150,9 +106,4 @@ - (NSString *)userPublicKeyPathForUser:(NSString *)userId { return [[NSString stringWithFormat:kPublicKeyUserPath, userId] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];; } -- (NSURL *)createDomainURLFromString:(NSString *)string { - NSAssert(string, @"Must supply a non-nil domain"); - NSURL *url = [string hasPrefix:@"http"] ? [NSURL URLWithString:string] : [NSURL URLWithString:[@"https://" stringByAppendingString:string]]; - return url; -} @end diff --git a/Pod/Classes/Core/A0Lock.m b/Pod/Classes/Core/A0Lock.m index 7bd7340dd..388a47e3b 100644 --- a/Pod/Classes/Core/A0Lock.m +++ b/Pod/Classes/Core/A0Lock.m @@ -47,6 +47,11 @@ + (instancetype)URLWithAuth0Domain:(NSString *)domain { @end +@interface A0Lock () +@property (strong, nonatomic) id router; +@property (strong, nonatomic) A0APIClient *client; +@end + @implementation A0Lock AUTH0_DYNAMIC_LOGGER_METHODS @@ -81,20 +86,31 @@ - (instancetype)initWithClientId:(NSString *)clientId domain:(NSString *)domain NSAssert(configurationDomain.length > 0, @"Must supply a valid configuration domain"); self = [super init]; if (self) { - _clientId = clientId; - _domainURL = [NSURL URLWithAuth0Domain:domain]; + NSURL *domainURL = [NSURL URLWithAuth0Domain:domain]; NSString *clientPath = [[@"client" stringByAppendingPathComponent:clientId] stringByAppendingPathExtension:@"js"]; - NSURL *configurationURL = [NSURL URLWithAuth0Domain:configurationDomain]; - _configurationURL = [NSURL URLWithString:clientPath relativeToURL:configurationURL]; - A0LogDebug(@"Auth0 Lock initialised with clientId: (%@) domainURL: (%@) configurationURL: (%@)", _clientId, _domainURL, _configurationURL); + NSURL *configurationURL = [NSURL URLWithString:clientPath relativeToURL:[NSURL URLWithAuth0Domain:configurationDomain]]; + A0LogDebug(@"Auth0 Lock initialised with clientId: (%@) domainURL: (%@) configurationURL: (%@)", clientId, domainURL, configurationURL); + _router = [[A0APIv1Router alloc] initWithClientId:clientId domainURL:domainURL configurationURL:configurationURL]; + _client = [[A0APIClient alloc] initWithAPIRouter:_router]; } return self; } - (A0APIClient *)apiClient { - A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:self.clientId domainURL:self.domainURL configurationURL:self.configurationURL]; - return [[A0APIClient alloc] initWithAPIRouter:router]; + return self.client; +} + +- (NSString *)clientId { + return [self.router clientId]; +} + +- (NSURL *)configurationURL { + return [self.router configurationURL]; +} + +- (NSURL *)domainURL { + return [self.router endpointURL]; } + (instancetype)newLockWithClientId:(NSString *)clientId domain:(NSString *)domain { diff --git a/Pod/Classes/Core/A0UserAPIClient.m b/Pod/Classes/Core/A0UserAPIClient.m index 6d50462a5..e20e603d2 100644 --- a/Pod/Classes/Core/A0UserAPIClient.m +++ b/Pod/Classes/Core/A0UserAPIClient.m @@ -27,6 +27,7 @@ #import "A0JSONResponseSerializer.h" #import "A0UserProfile.h" #import "A0APIv1Router.h" +#import "A0Lock.h" #define kAuthorizationHeaderName @"Authorization" #define kAuthorizationHeaderValueFormatString @"Bearer %@" @@ -80,31 +81,29 @@ - (instancetype)initWithRouter:(id)router idToken:(NSString *)idToken { - (instancetype)initWithClientId:(NSString *)clientId tenant:(NSString *)tenant accessToken:(NSString *)accessToken { NSAssert(clientId, @"You must supply your Auth0 app's Client Id."); NSAssert(tenant, @"You must supply your Auth0 app's Tenant."); - A0APIv1Router *router = [[A0APIv1Router alloc] init]; - [router configureForTenant:tenant clientId:clientId]; + A0Lock *lock = [A0Lock newLockWithClientId:clientId domain:[NSString stringWithFormat:@"https://%@.auth0.com", tenant]]; + A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; return [self initWithRouter:router accessToken:accessToken]; } - (instancetype)initWithClientId:(NSString *)clientId tenant:(NSString *)tenant idToken:(NSString *)idToken { NSAssert(clientId, @"You must supply your Auth0 app's Client Id."); NSAssert(tenant, @"You must supply your Auth0 app's Tenant."); - A0APIv1Router *router = [[A0APIv1Router alloc] init]; - [router configureForTenant:tenant clientId:clientId]; + A0Lock *lock = [A0Lock newLockWithClientId:clientId domain:[NSString stringWithFormat:@"https://%@.auth0.com", tenant]]; + A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; return [self initWithRouter:router idToken:idToken]; } + (A0UserAPIClient *)clientWithAccessToken:(NSString *)accessToken { - NSDictionary *info = [[NSBundle mainBundle] infoDictionary]; - A0APIv1Router *router = [[A0APIv1Router alloc] init]; - [router configureWithBundleInfo:info]; + A0Lock *lock = [A0Lock new]; + A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; A0UserAPIClient *client = [[A0UserAPIClient alloc] initWithRouter:router accessToken:accessToken]; return client; } + (A0UserAPIClient *)clientWithIdToken:(NSString *)idToken { - NSDictionary *info = [[NSBundle mainBundle] infoDictionary]; - A0APIv1Router *router = [[A0APIv1Router alloc] init]; - [router configureWithBundleInfo:info]; + A0Lock *lock = [A0Lock new]; + A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; A0UserAPIClient *client = [[A0UserAPIClient alloc] initWithRouter:router idToken:idToken]; return client; } From ceb7f691bdf4cd68b442db93b00abd1bb855976a Mon Sep 17 00:00:00 2001 From: Hernan Zalazar Date: Fri, 8 May 2015 11:56:19 -0300 Subject: [PATCH 5/7] Deprecate methods of API clients. --- Pod/Classes/Core/A0APIClient.h | 18 ++++---- Pod/Classes/Core/A0APIClient.m | 16 +++---- Pod/Classes/Core/A0UserAPIClient.h | 53 ++++++++++++++++++++--- Pod/Classes/Core/A0UserAPIClient.m | 67 +++++++++++++++++------------- 4 files changed, 102 insertions(+), 52 deletions(-) diff --git a/Pod/Classes/Core/A0APIClient.h b/Pod/Classes/Core/A0APIClient.h index c2b91b896..6ee62700e 100644 --- a/Pod/Classes/Core/A0APIClient.h +++ b/Pod/Classes/Core/A0APIClient.h @@ -44,14 +44,6 @@ typedef void(^A0APIClientDelegationSuccess)(A0Token *tokenInfo); /// @name Initialization ///---------------------------------------- -/** - Initialise the Client with Auth0's app client ID and tenant name - @param clientId app's client ID. - @param tenant app's tenant name - @return a new `A0APIClient` instance - */ -- (instancetype)initWithClientId:(NSString *)clientId andTenant:(NSString *)tenant; - /** Initialise the Client with a API router @param router API routes handler @@ -352,6 +344,16 @@ typedef void(^A0APIClientDelegationSuccess)(A0Token *tokenInfo); @interface A0APIClient (Deprecated) +/** + * Initialise the Client with Auth0's app client ID and tenant name + * @param clientId app's client ID. + * @param tenant app's tenant name + * + * @deprecated 1.12.0 + * @return a new `A0APIClient` instance + */ +- (instancetype)initWithClientId:(NSString *)clientId andTenant:(NSString *)tenant; + /** * Calls Auth0 delegation API with the refresh_token to obtain a new id_token. * diff --git a/Pod/Classes/Core/A0APIClient.m b/Pod/Classes/Core/A0APIClient.m index cd3a4a43f..3b6e2f271 100644 --- a/Pod/Classes/Core/A0APIClient.m +++ b/Pod/Classes/Core/A0APIClient.m @@ -65,14 +65,6 @@ @implementation A0APIClient AUTH0_DYNAMIC_LOGGER_METHODS -- (instancetype)initWithClientId:(NSString *)clientId andTenant:(NSString *)tenant { - NSAssert(clientId, @"You must supply your Auth0 app's Client Id."); - NSAssert(tenant, @"You must supply your Auth0 app's Tenant."); - A0Lock *lock = [A0Lock newLockWithClientId:clientId domain:[NSString stringWithFormat:@"https://%@.auth0.com", tenant]]; - A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; - return [self initWithAPIRouter:router]; -} - - (instancetype)initWithAPIRouter:(id)router { NSAssert(router, @"You must supply a valid API Router"); self = [super init]; @@ -519,6 +511,14 @@ - (A0Application *)parseApplicationFromJSONP:(NSData *)jsonpData error:(NSError @implementation A0APIClient (Deprecated) +- (instancetype)initWithClientId:(NSString *)clientId andTenant:(NSString *)tenant { + NSAssert(clientId, @"You must supply your Auth0 app's Client Id."); + NSAssert(tenant, @"You must supply your Auth0 app's Tenant."); + A0Lock *lock = [A0Lock newLockWithClientId:clientId domain:[NSString stringWithFormat:@"https://%@.auth0.com", tenant]]; + A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; + return [self initWithAPIRouter:router]; +} + - (void)delegationWithRefreshToken:(NSString *)refreshToken parameters:(A0AuthParameters *)parameters success:(A0APIClientDelegationSuccess)success diff --git a/Pod/Classes/Core/A0UserAPIClient.h b/Pod/Classes/Core/A0UserAPIClient.h index 42c5543a1..d9ed21485 100644 --- a/Pod/Classes/Core/A0UserAPIClient.h +++ b/Pod/Classes/Core/A0UserAPIClient.h @@ -36,12 +36,6 @@ typedef void(^A0UserAPIClientError)(NSError *error); - (instancetype)initWithRouter:(id)router accessToken:(NSString *)accessToken; - (instancetype)initWithRouter:(id)router idToken:(NSString *)idToken; -- (instancetype)initWithClientId:(NSString *)clientId tenant:(NSString *)tenant accessToken:(NSString *)accessToken; -- (instancetype)initWithClientId:(NSString *)clientId tenant:(NSString *)tenant idToken:(NSString *)idToken; - -+ (A0UserAPIClient *)clientWithAccessToken:(NSString *)accessToken; -+ (A0UserAPIClient *)clientWithIdToken:(NSString *)idToken; - ///---------------------------------------- /// @name User Profile ///---------------------------------------- @@ -88,3 +82,50 @@ typedef void(^A0UserAPIClientError)(NSError *error); failure:(A0UserAPIClientError)failure; @end + +@interface A0UserAPIClient (Deprecated) + +/** + * Initialise a new User API Client + * + * @param clientId account client identifier + * @param tenant account tenant name + * @param accessToken user's access token + * + * @deprecated 1.12.0 + * @return a A0UserAPIClient instance + */ +- (instancetype)initWithClientId:(NSString *)clientId tenant:(NSString *)tenant accessToken:(NSString *)accessToken __attribute__((deprecated)); +/** + * Initialise a new User API Client + * + * @param clientId account client identifier + * @param tenant account tenant name + * @param idToken user's id token + * + * @deprecated 1.12.0 + * @return a A0UserAPIClient instance + */ +- (instancetype)initWithClientId:(NSString *)clientId tenant:(NSString *)tenant idToken:(NSString *)idToken __attribute__((deprecated)); + +/** + * Creates a new client with an access token + * + * @param accessToken user's access token + * + * @deprecated 1.12.0 + * @return a new instance + */ ++ (A0UserAPIClient *)clientWithAccessToken:(NSString *)accessToken __attribute__((deprecated)); + +/** + * Creates a new client with a id token + * + * @param idToken user's id token + * + * @deprecated 1.12.0 + * @return a new instance + */ ++ (A0UserAPIClient *)clientWithIdToken:(NSString *)idToken __attribute__((deprecated)); + +@end \ No newline at end of file diff --git a/Pod/Classes/Core/A0UserAPIClient.m b/Pod/Classes/Core/A0UserAPIClient.m index e20e603d2..219d18a9b 100644 --- a/Pod/Classes/Core/A0UserAPIClient.m +++ b/Pod/Classes/Core/A0UserAPIClient.m @@ -78,36 +78,6 @@ - (instancetype)initWithRouter:(id)router idToken:(NSString *)idToken { return self; } -- (instancetype)initWithClientId:(NSString *)clientId tenant:(NSString *)tenant accessToken:(NSString *)accessToken { - NSAssert(clientId, @"You must supply your Auth0 app's Client Id."); - NSAssert(tenant, @"You must supply your Auth0 app's Tenant."); - A0Lock *lock = [A0Lock newLockWithClientId:clientId domain:[NSString stringWithFormat:@"https://%@.auth0.com", tenant]]; - A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; - return [self initWithRouter:router accessToken:accessToken]; -} - -- (instancetype)initWithClientId:(NSString *)clientId tenant:(NSString *)tenant idToken:(NSString *)idToken { - NSAssert(clientId, @"You must supply your Auth0 app's Client Id."); - NSAssert(tenant, @"You must supply your Auth0 app's Tenant."); - A0Lock *lock = [A0Lock newLockWithClientId:clientId domain:[NSString stringWithFormat:@"https://%@.auth0.com", tenant]]; - A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; - return [self initWithRouter:router idToken:idToken]; -} - -+ (A0UserAPIClient *)clientWithAccessToken:(NSString *)accessToken { - A0Lock *lock = [A0Lock new]; - A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; - A0UserAPIClient *client = [[A0UserAPIClient alloc] initWithRouter:router accessToken:accessToken]; - return client; -} - -+ (A0UserAPIClient *)clientWithIdToken:(NSString *)idToken { - A0Lock *lock = [A0Lock new]; - A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; - A0UserAPIClient *client = [[A0UserAPIClient alloc] initWithRouter:router idToken:idToken]; - return client; -} - #pragma mark - User Profile - (void)fetchUserProfileSuccess:(A0UserAPIClientUserProfileSuccess)success @@ -171,3 +141,40 @@ + (AFFailureBlock) sanitizeFailureBlock:(A0UserAPIClientError)failureBlock { } @end + +#pragma mark - Deprecated + +@implementation A0UserAPIClient (Deprecated) + +- (instancetype)initWithClientId:(NSString *)clientId tenant:(NSString *)tenant accessToken:(NSString *)accessToken { + NSAssert(clientId, @"You must supply your Auth0 app's Client Id."); + NSAssert(tenant, @"You must supply your Auth0 app's Tenant."); + A0Lock *lock = [A0Lock newLockWithClientId:clientId domain:[NSString stringWithFormat:@"https://%@.auth0.com", tenant]]; + A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; + return [self initWithRouter:router accessToken:accessToken]; +} + +- (instancetype)initWithClientId:(NSString *)clientId tenant:(NSString *)tenant idToken:(NSString *)idToken { + NSAssert(clientId, @"You must supply your Auth0 app's Client Id."); + NSAssert(tenant, @"You must supply your Auth0 app's Tenant."); + A0Lock *lock = [A0Lock newLockWithClientId:clientId domain:[NSString stringWithFormat:@"https://%@.auth0.com", tenant]]; + A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; + return [self initWithRouter:router idToken:idToken]; +} + ++ (A0UserAPIClient *)clientWithAccessToken:(NSString *)accessToken { + A0Lock *lock = [A0Lock new]; + A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; + A0UserAPIClient *client = [[A0UserAPIClient alloc] initWithRouter:router accessToken:accessToken]; + return client; +} + ++ (A0UserAPIClient *)clientWithIdToken:(NSString *)idToken { + A0Lock *lock = [A0Lock new]; + A0APIv1Router *router = [[A0APIv1Router alloc] initWithClientId:lock.clientId domainURL:lock.domainURL configurationURL:lock.configurationURL]; + A0UserAPIClient *client = [[A0UserAPIClient alloc] initWithRouter:router idToken:idToken]; + return client; +} + +@end + From a11ab11e55fd7bbd444d031b340b2ac7e068d3cb Mon Sep 17 00:00:00 2001 From: Hernan Zalazar Date: Fri, 8 May 2015 19:00:33 -0300 Subject: [PATCH 6/7] Start using A0Lock internally. --- Lock/Lock.xcodeproj/project.pbxproj | 6 ++ Lock/Lock/A0HomeViewController.m | 19 ++---- Lock/Lock/A0LockApplication.h | 33 +++++++++++ Lock/Lock/A0LockApplication.m | 58 +++++++++++++++++++ Lock/Lock/A0ViewController.m | 4 +- Pod/Classes/Core/A0APIClient.h | 15 ++--- .../Private/NSObject+A0APIClientProvider.m | 3 + Pod/Classes/Lock.h | 1 + Pod/Classes/SMS/A0SMSCodeViewController.h | 5 +- Pod/Classes/SMS/A0SMSCodeViewController.m | 11 ++-- Pod/Classes/SMS/A0SMSLockViewController.h | 7 ++- Pod/Classes/SMS/A0SMSLockViewController.m | 7 +++ .../TouchID/A0TouchIDLockViewController.h | 7 ++- .../TouchID/A0TouchIDLockViewController.m | 10 +++- .../TouchID/A0TouchIDRegisterViewController.h | 5 +- .../TouchID/A0TouchIDRegisterViewController.m | 9 ++- .../TouchID/A0TouchIDSignUpViewController.h | 10 ++-- .../TouchID/A0TouchIDSignUpViewController.m | 5 +- Pod/Classes/UI/A0LockSignUpViewController.h | 7 ++- Pod/Classes/UI/A0LockSignUpViewController.m | 4 +- Pod/Classes/UI/A0LockViewController.h | 7 ++- Pod/Classes/UI/A0LockViewController.m | 9 ++- Pod/Classes/UI/A0WebViewController.h | 4 +- Pod/Classes/UI/A0WebViewController.m | 3 +- .../Private/A0ActiveDirectoryViewController.h | 5 +- .../Private/A0ActiveDirectoryViewController.m | 11 ++-- .../UI/Private/A0AuthenticationUIComponent.h | 5 +- .../Private/A0ChangePasswordViewController.h | 4 +- .../Private/A0ChangePasswordViewController.m | 11 ++-- .../Private/A0DatabaseLoginViewController.h | 3 +- .../Private/A0DatabaseLoginViewController.m | 8 ++- .../A0FullActiveDirectoryViewController.h | 5 +- .../A0FullActiveDirectoryViewController.m | 1 + .../UI/Private/A0FullLoginViewController.h | 2 +- .../UI/Private/A0FullLoginViewController.m | 1 + .../UI/Private/A0SignUpViewController.h | 3 +- .../UI/Private/A0SignUpViewController.m | 13 +++-- ...0SmallSocialAuthenticationCollectionView.h | 3 +- ...0SmallSocialAuthenticationCollectionView.m | 1 + .../UI/Private/A0SocialLoginViewController.h | 3 +- .../UI/Private/A0SocialLoginViewController.m | 2 + .../UIViewController+LockNotification.m | 10 +++- 42 files changed, 258 insertions(+), 82 deletions(-) create mode 100644 Lock/Lock/A0LockApplication.h create mode 100644 Lock/Lock/A0LockApplication.m diff --git a/Lock/Lock.xcodeproj/project.pbxproj b/Lock/Lock.xcodeproj/project.pbxproj index a0fd72584..28a60aa80 100644 --- a/Lock/Lock.xcodeproj/project.pbxproj +++ b/Lock/Lock.xcodeproj/project.pbxproj @@ -26,6 +26,7 @@ 5F48BBA81A7B151700D8E05B /* POST-delegation.response in Resources */ = {isa = PBXBuildFile; fileRef = 5F48BBA71A7B151700D8E05B /* POST-delegation.response */; }; 5F7112E519D5C18B001971BE /* A0AuthParametersSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F7112E419D5C18B001971BE /* A0AuthParametersSpec.m */; }; 5F75E4541A2FB06D00EAB3B7 /* A0APIv1RouterSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F75E4531A2FB06D00EAB3B7 /* A0APIv1RouterSpec.m */; }; + 5F8D5FD71AFD637B00E9BF55 /* A0LockApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F8D5FD61AFD637B00E9BF55 /* A0LockApplication.m */; }; 5F91E66E19E32C48003150DF /* A0ConnectionSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F91E66D19E32C48003150DF /* A0ConnectionSpec.m */; }; 5F951A981A0EC7D600D128D0 /* A0HomeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F951A971A0EC7D600D128D0 /* A0HomeViewController.m */; }; 5F951ABB1A1189A600D128D0 /* Lock.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5F951ABD1A1189A600D128D0 /* Lock.strings */; }; @@ -98,6 +99,8 @@ 5F48BBA71A7B151700D8E05B /* POST-delegation.response */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "POST-delegation.response"; sourceTree = ""; }; 5F7112E419D5C18B001971BE /* A0AuthParametersSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = A0AuthParametersSpec.m; sourceTree = ""; }; 5F75E4531A2FB06D00EAB3B7 /* A0APIv1RouterSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = A0APIv1RouterSpec.m; sourceTree = ""; }; + 5F8D5FD51AFD637B00E9BF55 /* A0LockApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = A0LockApplication.h; sourceTree = ""; }; + 5F8D5FD61AFD637B00E9BF55 /* A0LockApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = A0LockApplication.m; sourceTree = ""; }; 5F91E66D19E32C48003150DF /* A0ConnectionSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = A0ConnectionSpec.m; sourceTree = ""; }; 5F951A961A0EC7D600D128D0 /* A0HomeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = A0HomeViewController.h; sourceTree = ""; }; 5F951A971A0EC7D600D128D0 /* A0HomeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = A0HomeViewController.m; sourceTree = ""; }; @@ -276,6 +279,8 @@ 5FF3B5161A25439400BE84F9 /* A0SettingsViewController.h */, 5FF3B5171A25439400BE84F9 /* A0SettingsViewController.m */, 5FA2CAEA1A7FE673009178C0 /* Launch Screen.xib */, + 5F8D5FD51AFD637B00E9BF55 /* A0LockApplication.h */, + 5F8D5FD61AFD637B00E9BF55 /* A0LockApplication.m */, ); path = Lock; sourceTree = ""; @@ -541,6 +546,7 @@ 6003F59E195388D20070C39A /* A0AppDelegate.m in Sources */, 6003F5A7195388D20070C39A /* A0ViewController.m in Sources */, 6003F59A195388D20070C39A /* main.m in Sources */, + 5F8D5FD71AFD637B00E9BF55 /* A0LockApplication.m in Sources */, 5F951A981A0EC7D600D128D0 /* A0HomeViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Lock/Lock/A0HomeViewController.m b/Lock/Lock/A0HomeViewController.m index 8ec1185fa..2eafed860 100644 --- a/Lock/Lock/A0HomeViewController.m +++ b/Lock/Lock/A0HomeViewController.m @@ -27,6 +27,7 @@ #import #import #import +#import "A0LockApplication.h" #define kClientIdKey @"Auth0ClientId" #define kTenantKey @"Auth0Tenant" @@ -42,7 +43,6 @@ static BOOL isRunningTests(void) { @interface A0HomeViewController () @property (strong, nonatomic) A0SimpleKeychain *keychain; - @end @implementation A0HomeViewController @@ -56,23 +56,13 @@ - (void)viewDidLoad { } #endif - A0TwitterAuthenticator *twitter = [A0TwitterAuthenticator newAuthenticatorWithKey:@"" - andSecret:@""]; - A0FacebookAuthenticator *facebook = [A0FacebookAuthenticator newAuthenticatorWithDefaultPermissions]; - NSString *googlePlusClientId = [[NSBundle mainBundle] infoDictionary][@"GooglePlusClientId"]; - A0GooglePlusAuthenticator *googleplus = [A0GooglePlusAuthenticator newAuthenticatorWithClientId:googlePlusClientId]; - [[A0IdentityProviderAuthenticator sharedInstance] registerAuthenticationProviders:@[ - twitter, - facebook, - googleplus, - ]]; - self.keychain = [A0SimpleKeychain keychainWithService:@"Auth0"]; @weakify(self); NSString* refreshToken = [self.keychain stringForKey: @"refresh_token"]; NSString* idToken = [self.keychain stringForKey: @"id_token"]; + A0APIClient *client = [[[A0LockApplication sharedInstance] lock] apiClient]; if (refreshToken) { - [[[A0APIClient sharedClient] fetchNewIdTokenWithRefreshToken:refreshToken parameters:nil] subscribeNext:^(A0Token *token) { + [[client fetchNewIdTokenWithRefreshToken:refreshToken parameters:nil] subscribeNext:^(A0Token *token) { @strongify(self); [self.keychain setString:token.idToken forKey:@"id_token"]; [self performSegueWithIdentifier:@"LoggedIn" sender:self]; @@ -93,6 +83,7 @@ - (void)loginNative:(id)sender { [self.keychain clearAll]; A0LockViewController *controller = [[A0LockViewController alloc] init]; @weakify(self); + controller.lock = [[A0LockApplication sharedInstance] lock]; controller.closable = YES; controller.loginAfterSignUp = YES; controller.usesEmail = YES; @@ -113,6 +104,7 @@ - (void)loginTouchID:(id)sender { [self.keychain clearAll]; A0TouchIDLockViewController *controller = [[A0TouchIDLockViewController alloc] init]; controller.closable = YES; + controller.lock = [[A0LockApplication sharedInstance] lock]; @weakify(self); controller.onAuthenticationBlock = ^(A0UserProfile *profile, A0Token *token) { NSLog(@"SUCCESS %@", profile); @@ -134,6 +126,7 @@ - (void)loginTouchID:(id)sender { - (void)loginSMS:(id)sender { [self.keychain clearAll]; A0SMSLockViewController *controller = [[A0SMSLockViewController alloc] init]; + controller.lock = [[A0LockApplication sharedInstance] lock]; controller.closable = YES; @weakify(self); controller.auth0APIToken = ^{ diff --git a/Lock/Lock/A0LockApplication.h b/Lock/Lock/A0LockApplication.h new file mode 100644 index 000000000..64807d10a --- /dev/null +++ b/Lock/Lock/A0LockApplication.h @@ -0,0 +1,33 @@ +// A0LockApplication.h +// +// Copyright (c) 2015 Auth0 (http://auth0.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +@class A0Lock; + +@interface A0LockApplication : NSObject + +@property (readonly, nonatomic) A0Lock *lock; + ++ (A0LockApplication *)sharedInstance; + +@end diff --git a/Lock/Lock/A0LockApplication.m b/Lock/Lock/A0LockApplication.m new file mode 100644 index 000000000..9da27b3a1 --- /dev/null +++ b/Lock/Lock/A0LockApplication.m @@ -0,0 +1,58 @@ +// A0LockApplication.m +// +// Copyright (c) 2015 Auth0 (http://auth0.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "A0LockApplication.h" + +#import + +@implementation A0LockApplication + +- (instancetype)init { + self = [super init]; + if (self) { + _lock = [A0Lock new]; + A0TwitterAuthenticator *twitter = [A0TwitterAuthenticator newAuthenticatorWithKey:@"" + andSecret:@""]; + twitter.clientProvider = _lock; + A0FacebookAuthenticator *facebook = [A0FacebookAuthenticator newAuthenticatorWithDefaultPermissions]; + facebook.clientProvider = _lock; + NSString *googlePlusClientId = [[NSBundle mainBundle] infoDictionary][@"GooglePlusClientId"]; + A0GooglePlusAuthenticator *googleplus = [A0GooglePlusAuthenticator newAuthenticatorWithClientId:googlePlusClientId]; + googleplus.clientProvider = _lock; + [[A0IdentityProviderAuthenticator sharedInstance] registerAuthenticationProviders:@[ + twitter, + facebook, + googleplus, + ]]; + } + return self; +} + ++ (A0LockApplication *)sharedInstance { + static A0LockApplication *instance; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance = [[A0LockApplication alloc] init]; + }); + return instance; +} +@end diff --git a/Lock/Lock/A0ViewController.m b/Lock/Lock/A0ViewController.m index a404a03ce..53fda0568 100644 --- a/Lock/Lock/A0ViewController.m +++ b/Lock/Lock/A0ViewController.m @@ -28,6 +28,7 @@ #import #import #import +#import "A0LockApplication.h" @interface A0ViewController () @@ -46,7 +47,8 @@ - (void)viewDidLoad { RACCommand *refreshCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) { @strongify(self); NSString* refreshToken = [self.keychain stringForKey: @"refresh_token"]; - return [[A0APIClient sharedClient] fetchNewIdTokenWithRefreshToken:refreshToken parameters:nil]; + A0APIClient *client = [[[A0LockApplication sharedInstance] lock] apiClient]; + return [client fetchNewIdTokenWithRefreshToken:refreshToken parameters:nil]; }]; [[refreshCommand.executionSignals flatten] subscribeNext:^(A0Token *token) { @strongify(self); diff --git a/Pod/Classes/Core/A0APIClient.h b/Pod/Classes/Core/A0APIClient.h index 6ee62700e..9758b8e6c 100644 --- a/Pod/Classes/Core/A0APIClient.h +++ b/Pod/Classes/Core/A0APIClient.h @@ -52,22 +52,23 @@ typedef void(^A0APIClientDelegationSuccess)(A0Token *tokenInfo); - (instancetype)initWithAPIRouter:(id)router; /** - * Returns a shared instance of `A0APIClient`. This instance is initialised with clientId and tenant from Info plist file entries. These entries are `Auth0ClientId` and `Auth0Tenant`. - * It can also be instantiated with a custom domain instead of Auth0's. - @return a shared `A0APIClient` instance. + Logout from Auth0 API */ -+ (instancetype)sharedClient; +- (void)logout; /** - Logout from Auth0 API + * Returns a shared instance of `A0APIClient`. This instance is initialised with clientId and tenant from Info plist file entries. These entries are `Auth0ClientId` and `Auth0Tenant`. + * It can also be instantiated with a custom domain instead of Auth0's. + * We recommend keeping yourself the `A0APIClient` instead instead of relying in this singleton, for this reason this method is deprecated. + * @deprecated 1.12.0 + * @return a shared `A0APIClient` instance. */ -- (void)logout; ++ (instancetype)sharedClient __attribute__((deprecated)); ///---------------------------------------- /// @name Configuration for Auth0 App ///---------------------------------------- - /** * Object that provides all URLs and Paths of Auth0 API. By default a router for API v1 is used. */ diff --git a/Pod/Classes/Core/Private/NSObject+A0APIClientProvider.m b/Pod/Classes/Core/Private/NSObject+A0APIClientProvider.m index 0148405a3..27edc7faa 100644 --- a/Pod/Classes/Core/Private/NSObject+A0APIClientProvider.m +++ b/Pod/Classes/Core/Private/NSObject+A0APIClientProvider.m @@ -26,7 +26,10 @@ @implementation NSObject (A0APIClientProvider) - (A0APIClient *)a0_apiClientFromProvider:(id)provider { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated" return [provider apiClient] ?: [A0APIClient sharedClient]; +#pragma GCC diagnostic pop } @end diff --git a/Pod/Classes/Lock.h b/Pod/Classes/Lock.h index 737078528..0cf1606b4 100644 --- a/Pod/Classes/Lock.h +++ b/Pod/Classes/Lock.h @@ -29,6 +29,7 @@ #import "A0APIClient.h" #endif +#import "A0Lock.h" #import "A0UserAPIClient.h" #import "A0Application.h" #import "A0Strategy.h" diff --git a/Pod/Classes/SMS/A0SMSCodeViewController.h b/Pod/Classes/SMS/A0SMSCodeViewController.h index 482570567..221fd67ae 100644 --- a/Pod/Classes/SMS/A0SMSCodeViewController.h +++ b/Pod/Classes/SMS/A0SMSCodeViewController.h @@ -21,14 +21,15 @@ // THE SOFTWARE. #import -#import "A0KeyboardEnabledView.h" +#import "A0AuthenticationUIComponent.h" @class A0AuthParameters, A0UserProfile, A0Token; -@interface A0SMSCodeViewController : UIViewController +@interface A0SMSCodeViewController : UIViewController @property (copy, nonatomic) NSString *phoneNumber; @property (copy, nonatomic) A0AuthParameters *parameters; +@property (strong, nonatomic) A0Lock *lock; @property (copy, nonatomic) void(^onAuthenticationBlock)(A0UserProfile *profile, A0Token *token); @end diff --git a/Pod/Classes/SMS/A0SMSCodeViewController.m b/Pod/Classes/SMS/A0SMSCodeViewController.m index dce68f8b9..4632b079e 100644 --- a/Pod/Classes/SMS/A0SMSCodeViewController.m +++ b/Pod/Classes/SMS/A0SMSCodeViewController.m @@ -29,6 +29,7 @@ #import "A0Errors.h" #import +#import "A0Lock.h" @interface A0SMSCodeViewController () @@ -86,11 +87,11 @@ - (void)login:(id)sender { A0ShowAlertErrorView(title, message); }; [self.loginButton setInProgress:YES]; - [[A0APIClient sharedClient] loginWithPhoneNumber:self.phoneNumber - passcode:passcode - parameters:self.parameters - success:self.onAuthenticationBlock - failure:failureBlock]; + [self.lock.apiClient loginWithPhoneNumber:self.phoneNumber + passcode:passcode + parameters:self.parameters + success:self.onAuthenticationBlock + failure:failureBlock]; } else { A0LogError(@"Must provide a non-empty passcode."); A0ShowAlertErrorView(A0LocalizedString(@"There was an error logging in"), A0LocalizedString(@"You must enter a valid SMS code")); diff --git a/Pod/Classes/SMS/A0SMSLockViewController.h b/Pod/Classes/SMS/A0SMSLockViewController.h index 62b59c7f8..ce1956083 100644 --- a/Pod/Classes/SMS/A0SMSLockViewController.h +++ b/Pod/Classes/SMS/A0SMSLockViewController.h @@ -23,10 +23,15 @@ #import #import "A0ContainerViewController.h" -@class A0AuthParameters, A0UserProfile, A0Token; +@class A0AuthParameters, A0UserProfile, A0Token, A0Lock; @interface A0SMSLockViewController : A0ContainerViewController +/** + * Instance of Lock with Auth0 account information. By default it will build this object with information from `Info.plist` if none is set. + */ +@property (strong, nonatomic) A0Lock *lock; + /** Allows the A0AuthenticationViewController to be dismissed by adding a button. Default is NO */ diff --git a/Pod/Classes/SMS/A0SMSLockViewController.m b/Pod/Classes/SMS/A0SMSLockViewController.m index 755837dec..41b2d9abf 100644 --- a/Pod/Classes/SMS/A0SMSLockViewController.m +++ b/Pod/Classes/SMS/A0SMSLockViewController.m @@ -28,6 +28,7 @@ #import #import "A0NavigationView.h" #import "A0TitleView.h" +#import "A0Lock.h" #define kCountryCodeKey @"auth0-lock-sms-country-code" #define kPhoneNumberKey @"auth0-lock-sms-phone" @@ -84,6 +85,11 @@ - (void)viewDidLoad { [self displayController:[self buildSMSSendCode]]; UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard:)]; [self.view addGestureRecognizer:tapRecognizer]; + + if (!self.lock) { + self.lock = [[A0Lock alloc] init]; + } + } - (void)close:(id)sender { @@ -140,6 +146,7 @@ - (A0SMSCodeViewController *)buildSMSCodeWithNumber:(NSString *)phoneNumber { controller.phoneNumber = phoneNumber; controller.parameters = self.authenticationParameters; controller.onAuthenticationBlock = self.onAuthenticationBlock; + controller.lock = self.lock; void(^showRegister)() = ^{ @strongify(self); [self displayController:[self buildSMSSendCode]]; diff --git a/Pod/Classes/TouchID/A0TouchIDLockViewController.h b/Pod/Classes/TouchID/A0TouchIDLockViewController.h index cefa19e36..b162cdb81 100644 --- a/Pod/Classes/TouchID/A0TouchIDLockViewController.h +++ b/Pod/Classes/TouchID/A0TouchIDLockViewController.h @@ -22,7 +22,7 @@ #import -@class A0UserProfile, A0Token, A0AuthParameters; +@class A0UserProfile, A0Token, A0AuthParameters, A0Lock; FOUNDATION_EXPORT NSString * const A0ThemeTouchIDLockButtonImageNormalName; FOUNDATION_EXPORT NSString * const A0ThemeTouchIDLockButtonImageHighlightedName; @@ -34,6 +34,11 @@ FOUNDATION_EXPORT NSString * const A0ThemeTouchIDLockContainerBackgroundColor; */ @interface A0TouchIDLockViewController : UIViewController +/** + * Instance of Lock with Auth0 account information. By default it will build this object with information from `Info.plist` if none is set. + */ +@property (strong, nonatomic) A0Lock *lock; + /** Allows the A0AuthenticationViewController to be dismissed by adding a button. Default is NO */ diff --git a/Pod/Classes/TouchID/A0TouchIDLockViewController.m b/Pod/Classes/TouchID/A0TouchIDLockViewController.m index 05c8fdb85..08707996e 100644 --- a/Pod/Classes/TouchID/A0TouchIDLockViewController.m +++ b/Pod/Classes/TouchID/A0TouchIDLockViewController.m @@ -34,6 +34,7 @@ #import "A0UserAPIClient.h" #import "A0Theme.h" #import "A0TitleView.h" +#import "A0Lock.h" NSString * const A0ThemeTouchIDLockButtonImageNormalName = @"A0ThemeTouchIDLockButtonImageNormalName"; NSString * const A0ThemeTouchIDLockButtonImageHighlightedName = @"A0ThemeTouchIDLockButtonImageHighlightedName"; @@ -160,7 +161,8 @@ - (void)viewDidLoad { [self.userClient registerPublicKey:pubKey device:deviceName user:profile.userId success:completionBlock failure:errorBlock]; }]; }; - controller.authenticationParameters = self.authenticationParameters; + controller.parameters = self.authenticationParameters; + controller.lock = self.lock; [self.navigationController pushViewController:controller animated:YES]; }; self.authentication.jwtPayload = ^{ @@ -173,13 +175,17 @@ - (void)viewDidLoad { self.authentication.authenticate = ^(NSString *jwt, A0ErrorBlock errorBlock) { @strongify(self); A0LogVerbose(@"Authenticating with signed JWT %@", jwt); - A0APIClient *client = [A0APIClient sharedClient]; + A0APIClient *client = self.lock.apiClient; [client loginWithIdToken:jwt deviceName:[self deviceName] parameters:self.authenticationParameters success:self.onAuthenticationBlock failure:errorBlock]; }; + if (!self.lock) { + self.lock = [[A0Lock alloc] init]; + } + } - (void)close:(id)sender { diff --git a/Pod/Classes/TouchID/A0TouchIDRegisterViewController.h b/Pod/Classes/TouchID/A0TouchIDRegisterViewController.h index cf868f41f..ad8bbbda2 100644 --- a/Pod/Classes/TouchID/A0TouchIDRegisterViewController.h +++ b/Pod/Classes/TouchID/A0TouchIDRegisterViewController.h @@ -23,13 +23,14 @@ #import #import "A0ContainerViewController.h" -@class A0AuthParameters, A0UserProfile, A0Token; +@class A0AuthParameters, A0UserProfile, A0Token, A0Lock; @interface A0TouchIDRegisterViewController : A0ContainerViewController @property (copy, nonatomic) void(^onRegisterBlock)(A0UserProfile *profile, A0Token *token); @property (copy, nonatomic) void(^onCancelBlock)(); -@property (copy, nonatomic) A0AuthParameters *authenticationParameters; +@property (copy, nonatomic) A0AuthParameters *parameters; +@property (strong, nonatomic) A0Lock *lock; @end diff --git a/Pod/Classes/TouchID/A0TouchIDRegisterViewController.m b/Pod/Classes/TouchID/A0TouchIDRegisterViewController.m index a843691d5..11aaa989a 100644 --- a/Pod/Classes/TouchID/A0TouchIDRegisterViewController.m +++ b/Pod/Classes/TouchID/A0TouchIDRegisterViewController.m @@ -57,7 +57,8 @@ - (void)viewDidLoad { @weakify(self); A0TouchIDSignUpViewController *signUpController = [[A0TouchIDSignUpViewController alloc] init]; signUpController.onRegisterBlock = self.onRegisterBlock; - signUpController.authenticationParameters = self.authenticationParameters; + signUpController.parameters = self.parameters; + signUpController.lock = self.lock; [self.navigationView removeAll]; [self.navigationView addButtonWithLocalizedTitle:A0LocalizedString(@"CANCEL") actionBlock:self.onCancelBlock]; [self.navigationView addButtonWithLocalizedTitle:A0LocalizedString(@"ALREADY HAVE AN ACCOUNT?") actionBlock:^{ @@ -74,8 +75,9 @@ - (A0DatabaseLoginViewController *)buildLogin { A0DatabaseLoginViewController *controller = [[A0DatabaseLoginViewController alloc] init]; controller.showSignUp = YES; controller.showResetPassword = YES; - controller.parameters = self.authenticationParameters; + controller.parameters = self.parameters; controller.onLoginBlock = self.onRegisterBlock; + controller.lock = self.lock; [self.navigationView removeAll]; [self.navigationView addButtonWithLocalizedTitle:A0LocalizedString(@"CANCEL") actionBlock:^{ @strongify(self); @@ -93,7 +95,8 @@ - (A0DatabaseLoginViewController *)buildLogin { - (A0ChangePasswordViewController *)buildChangePassword { @weakify(self); A0ChangePasswordViewController *controller = [[A0ChangePasswordViewController alloc] init]; - controller.parameters = self.authenticationParameters; + controller.parameters = self.parameters; + controller.lock = self.lock; controller.onChangePasswordBlock = ^{ @strongify(self); [self displayController:[self buildLogin]]; diff --git a/Pod/Classes/TouchID/A0TouchIDSignUpViewController.h b/Pod/Classes/TouchID/A0TouchIDSignUpViewController.h index 49fea0143..8da422f85 100644 --- a/Pod/Classes/TouchID/A0TouchIDSignUpViewController.h +++ b/Pod/Classes/TouchID/A0TouchIDSignUpViewController.h @@ -21,16 +21,18 @@ // THE SOFTWARE. #import -#import "A0KeyboardEnabledView.h" +#import "A0AuthenticationUIComponent.h" -@class A0AuthParameters, A0UserProfile, A0Token, A0CredentialFieldView; +@class A0AuthParameters, A0UserProfile, A0Token, A0CredentialFieldView, A0Lock; -@interface A0TouchIDSignUpViewController : UIViewController +@interface A0TouchIDSignUpViewController : UIViewController @property (weak, nonatomic) IBOutlet A0CredentialFieldView *emailField; @property (copy, nonatomic) void(^onRegisterBlock)(A0UserProfile *profile, A0Token *token); -@property (copy, nonatomic) A0AuthParameters *authenticationParameters; +@property (copy, nonatomic) A0AuthParameters *parameters; + +@property (strong, nonatomic) A0Lock *lock; @end diff --git a/Pod/Classes/TouchID/A0TouchIDSignUpViewController.m b/Pod/Classes/TouchID/A0TouchIDSignUpViewController.m index d67af7e0e..63eff6494 100644 --- a/Pod/Classes/TouchID/A0TouchIDSignUpViewController.m +++ b/Pod/Classes/TouchID/A0TouchIDSignUpViewController.m @@ -31,6 +31,7 @@ #import #import "A0EmailValidator.h" +#import "A0Lock.h" @interface A0TouchIDSignUpViewController () @@ -77,11 +78,11 @@ - (void)signUp:(id)sender { if (!error) { @weakify(self); A0LogDebug(@"Registering user with email %@ for TouchID", username); - A0APIClient *client = [A0APIClient sharedClient]; + A0APIClient *client = self.lock.apiClient; [client signUpWithUsername:username password:password loginOnSuccess:YES - parameters:self.authenticationParameters + parameters:self.parameters success:^(A0UserProfile *profile, A0Token *tokenInfo) { @strongify(self); if (self.onRegisterBlock) { diff --git a/Pod/Classes/UI/A0LockSignUpViewController.h b/Pod/Classes/UI/A0LockSignUpViewController.h index d2e438c5d..e50217f46 100644 --- a/Pod/Classes/UI/A0LockSignUpViewController.h +++ b/Pod/Classes/UI/A0LockSignUpViewController.h @@ -23,10 +23,15 @@ #import #import "A0ContainerViewController.h" -@class A0AuthParameters, A0UserProfile, A0Token; +@class A0AuthParameters, A0UserProfile, A0Token, A0Lock; @interface A0LockSignUpViewController : A0ContainerViewController +/** + * Instance of Lock with Auth0 account information. + */ +@property (strong, nonatomic) A0Lock *lock; + /** Block that is called on successful authentication. It has two parameters profile and token, which will be non-nil unless login is disabled after signup. */ diff --git a/Pod/Classes/UI/A0LockSignUpViewController.m b/Pod/Classes/UI/A0LockSignUpViewController.m index 611625366..bf7fd32b7 100644 --- a/Pod/Classes/UI/A0LockSignUpViewController.m +++ b/Pod/Classes/UI/A0LockSignUpViewController.m @@ -34,6 +34,7 @@ #import "A0SignUpViewController.h" #import "A0UIUtilities.h" #import "A0TitleView.h" +#import "A0Lock.h" @interface A0LockSignUpViewController () @@ -167,12 +168,13 @@ - (void)setInProgress:(BOOL)inProgress { - (void)loadApplicationInfo { @weakify(self); - [[A0APIClient sharedClient] fetchAppInfoWithSuccess:^(A0Application *application) { + [self.lock.apiClient fetchAppInfoWithSuccess:^(A0Application *application) { @strongify(self); A0LogDebug(@"Obtained application info. Starting to build Lock UI for Sign Up..."); [[A0IdentityProviderAuthenticator sharedInstance] configureForApplication:application]; A0LockConfiguration *configuration = [[A0LockConfiguration alloc] initWithApplication:application filter:self.connections]; configuration.defaultDatabaseConnectionName = self.defaultDatabaseConnectionName; + self.serviceCollectionView.lock = self.lock; [self.serviceCollectionView showSocialServicesForConfiguration:configuration]; A0SignUpViewController *controller = [[A0SignUpViewController alloc] init]; controller.loginUser = self.loginAfterSignUp; diff --git a/Pod/Classes/UI/A0LockViewController.h b/Pod/Classes/UI/A0LockViewController.h index 6282f43a2..ec7d52888 100644 --- a/Pod/Classes/UI/A0LockViewController.h +++ b/Pod/Classes/UI/A0LockViewController.h @@ -23,7 +23,7 @@ #import #import "A0ContainerViewController.h" -@class A0UserProfile, A0Token, A0AuthParameters; +@class A0UserProfile, A0Token, A0AuthParameters, A0Lock; typedef void(^A0AuthenticationBlock)(A0UserProfile *profile, A0Token *token); @@ -33,6 +33,11 @@ typedef void(^A0AuthenticationBlock)(A0UserProfile *profile, A0Token *token); */ @interface A0LockViewController : A0ContainerViewController +/** + * Instance of Lock with Auth0 account information. By default it will build this object with information from `Info.plist` if none is set. + */ +@property (strong, nonatomic) A0Lock *lock; + /** Block that is called on successful authentication. It has two parameters profile and token, which will be non-nil unless login is disabled after signup. */ diff --git a/Pod/Classes/UI/A0LockViewController.m b/Pod/Classes/UI/A0LockViewController.m index 2705a1e54..d9b94d384 100644 --- a/Pod/Classes/UI/A0LockViewController.m +++ b/Pod/Classes/UI/A0LockViewController.m @@ -49,6 +49,7 @@ #import "A0LockConfiguration.h" #import "A0LockNotification.h" #import "A0TitleView.h" +#import "A0Lock.h" @interface A0LockViewController () @@ -100,6 +101,9 @@ - (void)viewDidLoad { self.dismissButton.hidden = !self.closable; + if (!self.lock) { + self.lock = [[A0Lock alloc] init]; + } [[A0IdentityProviderAuthenticator sharedInstance] setUseWebAsDefault:!self.useWebView]; [self loadApplicationInfo]; } @@ -136,7 +140,7 @@ - (BOOL)prefersStatusBarHidden { - (void)loadApplicationInfo { @weakify(self); - [[A0APIClient sharedClient] fetchAppInfoWithSuccess:^(A0Application *application) { + [self.lock.apiClient fetchAppInfoWithSuccess:^(A0Application *application) { @strongify(self); A0LogDebug(@"Obtained application info. Starting to build Lock UI..."); [[A0IdentityProviderAuthenticator sharedInstance] configureForApplication:application]; @@ -222,6 +226,7 @@ - (void)layoutRootController { } if (rootController) { rootController.parameters = [self copyAuthenticationParameters]; + rootController.lock = self.lock; [self displayController:rootController layout:layout]; } else { NSString *title = A0LocalizedString(@"Failed to display login"); @@ -340,6 +345,7 @@ - (A0SignUpViewController *)newSignUpViewControllerWithSuccess:(void(^)(A0UserPr controller.parameters = [self copyAuthenticationParameters]; controller.defaultConnection = self.configuration.defaultDatabaseConnection; controller.onSignUpBlock = success; + controller.lock = self.lock; [controller addDisclaimerSubview:self.signUpDisclaimerView]; [self.navigationView removeAll]; @weakify(self); @@ -355,6 +361,7 @@ - (A0ChangePasswordViewController *)newChangePasswordViewController { controller.forceUsername = !self.usesEmail; controller.parameters = [self copyAuthenticationParameters]; controller.defaultConnection = self.configuration.defaultDatabaseConnection; + controller.lock = self.lock; @weakify(self); void(^block)() = ^{ @strongify(self); diff --git a/Pod/Classes/UI/A0WebViewController.h b/Pod/Classes/UI/A0WebViewController.h index 0fc8127dd..27998d9e9 100644 --- a/Pod/Classes/UI/A0WebViewController.h +++ b/Pod/Classes/UI/A0WebViewController.h @@ -22,12 +22,14 @@ #import -@class A0Token, A0UserProfile, A0Application, A0Strategy, A0AuthParameters; +@class A0Token, A0UserProfile, A0Application, A0Strategy, A0AuthParameters, A0Lock; @interface A0WebViewController : UIViewController @property (copy, nonatomic) void(^onAuthentication)(A0UserProfile *profile, A0Token *token); @property (copy, nonatomic) void(^onFailure)(NSError *error); +@property (strong, nonatomic) A0Lock *lock; + - (instancetype)initWithApplication:(A0Application *)application strategy:(A0Strategy *)strategy parameters:(A0AuthParameters *)parameters; diff --git a/Pod/Classes/UI/A0WebViewController.m b/Pod/Classes/UI/A0WebViewController.m index 28fac2fa8..7e15ca1c5 100644 --- a/Pod/Classes/UI/A0WebViewController.m +++ b/Pod/Classes/UI/A0WebViewController.m @@ -31,6 +31,7 @@ #import "A0AuthParameters.h" #import +#import "A0Lock.h" @interface A0WebViewController () @property (weak, nonatomic) IBOutlet UIButton *cancelButton; @@ -98,7 +99,7 @@ - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *) if (token) { void(^success)(A0UserProfile *, A0Token *) = self.onAuthentication; @weakify(self); - [[A0APIClient sharedClient] fetchUserProfileWithIdToken:token.idToken success:^(A0UserProfile *profile) { + [self.lock.apiClient fetchUserProfileWithIdToken:token.idToken success:^(A0UserProfile *profile) { @strongify(self); self.modalTransitionStyle = UIModalTransitionStyleCoverVertical; if (success) { diff --git a/Pod/Classes/UI/Private/A0ActiveDirectoryViewController.h b/Pod/Classes/UI/Private/A0ActiveDirectoryViewController.h index 8ca193d39..d860be811 100644 --- a/Pod/Classes/UI/Private/A0ActiveDirectoryViewController.h +++ b/Pod/Classes/UI/Private/A0ActiveDirectoryViewController.h @@ -24,11 +24,12 @@ #import "A0AuthenticationUIComponent.h" #import "A0ConnectionDomainMatcher.h" -@class A0ProgressButton, A0UserProfile, A0CredentialsValidator, A0Token, A0CredentialFieldView, A0AuthParameters,A0Connection; +@class A0UserProfile, A0CredentialsValidator, A0Token, A0AuthParameters, A0Connection, A0Lock; @interface A0ActiveDirectoryViewController : UIViewController -@property (strong, nonatomic) A0AuthParameters *parameters; +@property (copy, nonatomic) A0AuthParameters *parameters; +@property (strong, nonatomic) A0Lock *lock; @property (strong, nonatomic) A0Connection *defaultConnection; @property (copy, nonatomic) void(^onLoginBlock)(A0UserProfile *profile, A0Token *token); diff --git a/Pod/Classes/UI/Private/A0ActiveDirectoryViewController.m b/Pod/Classes/UI/Private/A0ActiveDirectoryViewController.m index 53521990c..98f736597 100644 --- a/Pod/Classes/UI/Private/A0ActiveDirectoryViewController.m +++ b/Pod/Classes/UI/Private/A0ActiveDirectoryViewController.m @@ -43,6 +43,7 @@ #import "A0CredentialsValidator.h" #import "A0UsernameValidator.h" #import "A0PasswordValidator.h" +#import "A0Lock.h" @interface A0ActiveDirectoryViewController () @@ -98,7 +99,7 @@ - (void)dealloc { - (void)access:(id)sender { if (self.matchedConnection || self.defaultConnection) { A0Connection *connection = self.matchedConnection ?: self.defaultConnection; - A0Application *application = [[A0APIClient sharedClient] application]; + A0Application *application = [self.lock.apiClient application]; A0Strategy *strategy = [application enterpriseStrategyWithConnection:connection.name]; if (!strategy.useResourceOwnerEndpoint) { [self loginUserWithConnection:connection]; @@ -128,7 +129,7 @@ - (void)access:(id)sender { }; A0AuthParameters *parameters = self.parameters.copy; [parameters setValue:connection.name forKey:@"connection"]; - [[A0APIClient sharedClient] loginWithUsername:username password:password parameters:parameters success:success failure:failure]; + [self.lock.apiClient loginWithUsername:username password:password parameters:parameters success:success failure:failure]; } else { [self postLoginErrorNotificationWithError:error]; [self.accessButton setInProgress:NO]; @@ -149,7 +150,8 @@ - (void)goToPasswordField:(id)sender { - (void)matchDomainInTextField:(UITextField *)textField { A0Connection *connection = [self.domainMatcher connectionForEmail:textField.text]; - A0Strategy *adStrategy = [A0APIClient sharedClient].application.activeDirectoryStrategy; + A0APIClient *client = self.lock.apiClient; + A0Strategy *adStrategy = client.application.activeDirectoryStrategy; BOOL showSingleSignOn = connection && ![adStrategy.connections containsObject:connection]; if (showSingleSignOn) { NSString *title = [NSString stringWithFormat:A0LocalizedString(@"Login with %@"), connection[A0ConnectionDomain]]; @@ -199,7 +201,7 @@ - (void)loginUserWithConnection:(A0Connection *)connection { } }; - A0Application *application = [A0APIClient sharedClient].application; + A0Application *application = [self.lock.apiClient application]; A0Strategy *strategy = [application enterpriseStrategyWithConnection:connection.name]; A0IdentityProviderAuthenticator *authenticator = [A0IdentityProviderAuthenticator sharedInstance]; A0AuthParameters *parameters = self.parameters.copy; @@ -214,6 +216,7 @@ - (void)loginUserWithConnection:(A0Connection *)connection { controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; controller.onAuthentication = successBlock; controller.onFailure = failureBlock; + controller.lock = self.lock; [self presentViewController:controller animated:YES completion:nil]; } } diff --git a/Pod/Classes/UI/Private/A0AuthenticationUIComponent.h b/Pod/Classes/UI/Private/A0AuthenticationUIComponent.h index 70f88daa7..4b942be34 100644 --- a/Pod/Classes/UI/Private/A0AuthenticationUIComponent.h +++ b/Pod/Classes/UI/Private/A0AuthenticationUIComponent.h @@ -24,13 +24,14 @@ #import "A0KeyboardEnabledView.h" -@class A0AuthParameters; +@class A0AuthParameters, A0Lock; /** * Protocol for all UIViewControllers that are part of the native iOS widget. */ @protocol A0AuthenticationUIComponent -- (void)setParameters:(A0AuthParameters *)parameters; +@property (copy, nonatomic) A0AuthParameters *parameters; +@property (strong, nonatomic) A0Lock *lock; @end diff --git a/Pod/Classes/UI/Private/A0ChangePasswordViewController.h b/Pod/Classes/UI/Private/A0ChangePasswordViewController.h index 7e874f8a1..fe1cb2e36 100644 --- a/Pod/Classes/UI/Private/A0ChangePasswordViewController.h +++ b/Pod/Classes/UI/Private/A0ChangePasswordViewController.h @@ -23,18 +23,18 @@ #import #import "A0AuthenticationUIComponent.h" -@class A0CredentialsValidator, A0AuthParameters, A0CredentialFieldView, A0Connection; +@class A0CredentialsValidator, A0AuthParameters, A0Connection, A0Lock, A0CredentialFieldView; @interface A0ChangePasswordViewController : UIViewController @property (weak, nonatomic) IBOutlet A0CredentialFieldView *userField; @property (copy, nonatomic) void(^onChangePasswordBlock)(); - @property (copy, nonatomic) A0AuthParameters *parameters; @property (assign, nonatomic) BOOL forceUsername; @property (strong, nonatomic) A0CredentialsValidator *validator; @property (copy, nonatomic) NSString *defaultEmail; @property (strong, nonatomic) A0Connection *defaultConnection; +@property (strong, nonatomic) A0Lock *lock; @end diff --git a/Pod/Classes/UI/Private/A0ChangePasswordViewController.m b/Pod/Classes/UI/Private/A0ChangePasswordViewController.m index b31c2cbe1..55f778219 100644 --- a/Pod/Classes/UI/Private/A0ChangePasswordViewController.m +++ b/Pod/Classes/UI/Private/A0ChangePasswordViewController.m @@ -42,6 +42,7 @@ #import #import #import "A0ConfirmPasswordValidator.h" +#import "A0Lock.h" @interface A0ChangePasswordViewController () @@ -154,11 +155,11 @@ - (IBAction)recover:(id)sender { NSString *message = [A0Errors isAuth0Error:error withCode:A0ErrorCodeNotConnectedToInternet] ? error.localizedFailureReason : [A0Errors localizedStringForChangePasswordError:error]; A0ShowAlertErrorView(title, message); }; - [[A0APIClient sharedClient] changePassword:password - forUsername:username - parameters:self.parameters - success:success - failure:failure]; + [self.lock.apiClient changePassword:password + forUsername:username + parameters:self.parameters + success:success + failure:failure]; } else { [self.recoverButton setInProgress:NO]; diff --git a/Pod/Classes/UI/Private/A0DatabaseLoginViewController.h b/Pod/Classes/UI/Private/A0DatabaseLoginViewController.h index c6ad99626..28c44aeaa 100644 --- a/Pod/Classes/UI/Private/A0DatabaseLoginViewController.h +++ b/Pod/Classes/UI/Private/A0DatabaseLoginViewController.h @@ -24,7 +24,7 @@ #import "A0AuthenticationUIComponent.h" #import "A0ConnectionDomainMatcher.h" -@class A0ProgressButton, A0UserProfile, A0CredentialsValidator, A0Token, A0CredentialFieldView, A0AuthParameters,A0Connection, A0PasswordFieldView; +@class A0UserProfile, A0CredentialsValidator, A0Token, A0CredentialFieldView, A0AuthParameters, A0Connection, A0PasswordFieldView, A0Lock; @interface A0DatabaseLoginViewController : UIViewController @@ -44,4 +44,5 @@ @property (strong, nonatomic) A0CredentialsValidator *validator; @property (strong, nonatomic) id domainMatcher; +@property (strong, nonatomic) A0Lock *lock; @end diff --git a/Pod/Classes/UI/Private/A0DatabaseLoginViewController.m b/Pod/Classes/UI/Private/A0DatabaseLoginViewController.m index 1961716e9..22b97e598 100644 --- a/Pod/Classes/UI/Private/A0DatabaseLoginViewController.m +++ b/Pod/Classes/UI/Private/A0DatabaseLoginViewController.m @@ -49,6 +49,7 @@ #endif #import "UIViewController+LockNotification.h" +#import "A0Lock.h" @interface A0DatabaseLoginViewController () @@ -145,7 +146,7 @@ - (void)fillLogin:(id)sender { - (void)access:(id)sender { if (self.matchedConnection) { - A0Application *application = [[A0APIClient sharedClient] application]; + A0Application *application = [self.lock.apiClient application]; A0Strategy *strategy = [application enterpriseStrategyWithConnection:self.matchedConnection.name]; if (strategy.useResourceOwnerEndpoint) { if (self.onShowEnterpriseLogin) { @@ -163,7 +164,7 @@ - (void)access:(id)sender { [self hideKeyboard]; NSString *username = [self.userField.textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; NSString *password = self.passwordField.textField.text; - A0APIClient *client = [A0APIClient sharedClient]; + A0APIClient *client = self.lock.apiClient; @weakify(self); A0APIClientAuthenticationSuccess success = ^(A0UserProfile *profile, A0Token *token){ @strongify(self); @@ -257,7 +258,7 @@ - (void)loginUserWithConnection:(A0Connection *)connection { } }; - A0Application *application = [A0APIClient sharedClient].application; + A0Application *application = [self.lock.apiClient application]; A0Strategy *strategy = [application enterpriseStrategyWithConnection:connection.name]; A0IdentityProviderAuthenticator *authenticator = [A0IdentityProviderAuthenticator sharedInstance]; A0AuthParameters *parameters = [self.parameters copy]; @@ -272,6 +273,7 @@ - (void)loginUserWithConnection:(A0Connection *)connection { controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; controller.onAuthentication = successBlock; controller.onFailure = failureBlock; + controller.lock = self.lock; [self presentViewController:controller animated:YES completion:nil]; } } diff --git a/Pod/Classes/UI/Private/A0FullActiveDirectoryViewController.h b/Pod/Classes/UI/Private/A0FullActiveDirectoryViewController.h index 854eb7650..44d96b118 100644 --- a/Pod/Classes/UI/Private/A0FullActiveDirectoryViewController.h +++ b/Pod/Classes/UI/Private/A0FullActiveDirectoryViewController.h @@ -23,11 +23,12 @@ #import #import "A0ActiveDirectoryViewController.h" -@class A0LockConfiguration, A0SmallSocialAuthenticationCollectionView; +@class A0LockConfiguration, A0SmallSocialAuthenticationCollectionView, A0Lock; @interface A0FullActiveDirectoryViewController : A0ActiveDirectoryViewController -@property (strong, nonatomic) A0LockConfiguration *configuration; @property (weak, nonatomic) IBOutlet A0SmallSocialAuthenticationCollectionView *serviceCollectionView; +@property (strong, nonatomic) A0LockConfiguration *configuration; + @end diff --git a/Pod/Classes/UI/Private/A0FullActiveDirectoryViewController.m b/Pod/Classes/UI/Private/A0FullActiveDirectoryViewController.m index 4b9c14e30..55f774958 100644 --- a/Pod/Classes/UI/Private/A0FullActiveDirectoryViewController.m +++ b/Pod/Classes/UI/Private/A0FullActiveDirectoryViewController.m @@ -50,6 +50,7 @@ - (void)viewDidLoad { self.orLabel.text = A0LocalizedString(@"OR"); self.serviceCollectionView.authenticationDelegate = self; self.serviceCollectionView.parameters = self.parameters; + self.serviceCollectionView.lock = self.lock; [self.serviceCollectionView showSocialServicesForConfiguration:self.configuration]; self.activityIndicator.color = [[A0Theme sharedInstance] colorForKey:A0ThemeTitleTextColor]; } diff --git a/Pod/Classes/UI/Private/A0FullLoginViewController.h b/Pod/Classes/UI/Private/A0FullLoginViewController.h index 463bce2cd..6b5dd63d8 100644 --- a/Pod/Classes/UI/Private/A0FullLoginViewController.h +++ b/Pod/Classes/UI/Private/A0FullLoginViewController.h @@ -23,7 +23,7 @@ #import #import "A0DatabaseLoginViewController.h" -@class A0Application, A0LockConfiguration, A0SmallSocialAuthenticationCollectionView; +@class A0Application, A0LockConfiguration, A0SmallSocialAuthenticationCollectionView, A0Lock; @interface A0FullLoginViewController : A0DatabaseLoginViewController diff --git a/Pod/Classes/UI/Private/A0FullLoginViewController.m b/Pod/Classes/UI/Private/A0FullLoginViewController.m index 4b45efaf1..525554c5b 100644 --- a/Pod/Classes/UI/Private/A0FullLoginViewController.m +++ b/Pod/Classes/UI/Private/A0FullLoginViewController.m @@ -51,6 +51,7 @@ - (void)viewDidLoad { self.orLabel.text = A0LocalizedString(@"OR"); self.serviceCollectionView.authenticationDelegate = self; self.serviceCollectionView.parameters = self.parameters; + self.serviceCollectionView.lock = self.lock; [self.serviceCollectionView showSocialServicesForConfiguration:self.config]; self.activityIndicator.color = [[A0Theme sharedInstance] colorForKey:A0ThemeTitleTextColor]; } diff --git a/Pod/Classes/UI/Private/A0SignUpViewController.h b/Pod/Classes/UI/Private/A0SignUpViewController.h index 95c5cfca8..0de0ecd95 100644 --- a/Pod/Classes/UI/Private/A0SignUpViewController.h +++ b/Pod/Classes/UI/Private/A0SignUpViewController.h @@ -30,13 +30,14 @@ @property (copy, nonatomic) void(^onSignUpBlock)(A0UserProfile *profile, A0Token *token); -@property (strong, nonatomic) A0AuthParameters *parameters; +@property (copy, nonatomic) A0AuthParameters *parameters; @property (assign, nonatomic) BOOL forceUsername; @property (strong, nonatomic) A0CredentialsValidator *validator; @property (assign, nonatomic, getter = shouldLoginUser) BOOL loginUser; @property (copy, nonatomic) NSString *customMessage; @property (strong, nonatomic) A0Connection *defaultConnection; +@property (strong, nonatomic) A0Lock *lock; - (void)addDisclaimerSubview:(UIView *)view; - (void)updateUIWithError:(NSError *)error; diff --git a/Pod/Classes/UI/Private/A0SignUpViewController.m b/Pod/Classes/UI/Private/A0SignUpViewController.m index c531de606..200a17b8e 100644 --- a/Pod/Classes/UI/Private/A0SignUpViewController.m +++ b/Pod/Classes/UI/Private/A0SignUpViewController.m @@ -43,6 +43,7 @@ #import #import +#import "A0Lock.h" @interface A0SignUpViewController () @@ -174,12 +175,12 @@ - (void)signUp:(id)sender { NSString *message = [A0Errors isAuth0Error:error withCode:A0ErrorCodeNotConnectedToInternet] ? error.localizedFailureReason : [A0Errors localizedStringForSignUpError:error]; A0ShowAlertErrorView(title, message); }; - [[A0APIClient sharedClient] signUpWithEmail:email - username:username - password:password - loginOnSuccess:self.shouldLoginUser - parameters:self.parameters - success:success failure:failure]; + [self.lock.apiClient signUpWithEmail:email + username:username + password:password + loginOnSuccess:self.shouldLoginUser + parameters:self.parameters + success:success failure:failure]; } else { [self postSignUpErrorNotificationWithError:error]; [self.signUpButton setInProgress:NO]; diff --git a/Pod/Classes/UI/Private/A0SmallSocialAuthenticationCollectionView.h b/Pod/Classes/UI/Private/A0SmallSocialAuthenticationCollectionView.h index dde38aa04..5a754fb1d 100644 --- a/Pod/Classes/UI/Private/A0SmallSocialAuthenticationCollectionView.h +++ b/Pod/Classes/UI/Private/A0SmallSocialAuthenticationCollectionView.h @@ -22,7 +22,7 @@ #import -@class A0SmallSocialAuthenticationCollectionView, A0UserProfile, A0Token, A0LockConfiguration, A0AuthParameters; +@class A0SmallSocialAuthenticationCollectionView, A0UserProfile, A0Token, A0LockConfiguration, A0AuthParameters, A0Lock; @protocol A0SmallSocialAuthenticationCollectionViewDelegate @@ -46,6 +46,7 @@ @property (weak, nonatomic) id authenticationDelegate; @property (strong, nonatomic) A0AuthParameters *parameters; +@property (strong, nonatomic) A0Lock *lock; - (void)showSocialServicesForConfiguration:(A0LockConfiguration *)configuration; diff --git a/Pod/Classes/UI/Private/A0SmallSocialAuthenticationCollectionView.m b/Pod/Classes/UI/Private/A0SmallSocialAuthenticationCollectionView.m index e14665abd..85ac032d8 100644 --- a/Pod/Classes/UI/Private/A0SmallSocialAuthenticationCollectionView.m +++ b/Pod/Classes/UI/Private/A0SmallSocialAuthenticationCollectionView.m @@ -126,6 +126,7 @@ - (void)triggerAuth:(UIButton *)sender { controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; controller.onAuthentication = successBlock; controller.onFailure = failureBlock; + controller.lock = self.lock; [self.authenticationDelegate socialAuthenticationCollectionView:self presentAuthenticationViewController:controller]; } } diff --git a/Pod/Classes/UI/Private/A0SocialLoginViewController.h b/Pod/Classes/UI/Private/A0SocialLoginViewController.h index de8f580e9..ea68c0a22 100644 --- a/Pod/Classes/UI/Private/A0SocialLoginViewController.h +++ b/Pod/Classes/UI/Private/A0SocialLoginViewController.h @@ -28,7 +28,8 @@ @interface A0SocialLoginViewController : UIViewController @property (strong, nonatomic) A0LockConfiguration *configuration; -@property (strong, nonatomic) A0AuthParameters *parameters; +@property (copy, nonatomic) A0AuthParameters *parameters; +@property (strong, nonatomic) A0Lock *lock; @property (copy, nonatomic) void(^onLoginBlock)(A0UserProfile *profile, A0Token *token); @end diff --git a/Pod/Classes/UI/Private/A0SocialLoginViewController.m b/Pod/Classes/UI/Private/A0SocialLoginViewController.m index 53a62a520..3d7676684 100644 --- a/Pod/Classes/UI/Private/A0SocialLoginViewController.m +++ b/Pod/Classes/UI/Private/A0SocialLoginViewController.m @@ -36,6 +36,7 @@ #import #import "UIViewController+LockNotification.h" +#import "A0Lock.h" #define kCellIdentifier @"ServiceCell" @@ -122,6 +123,7 @@ - (void)triggerAuth:(UIButton *)sender { controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; controller.onAuthentication = successBlock; controller.onFailure = failureBlock; + controller.lock = self.lock; [self presentViewController:controller animated:YES completion:nil]; } } diff --git a/Pod/Classes/UI/Private/UIViewController+LockNotification.m b/Pod/Classes/UI/Private/UIViewController+LockNotification.m index ea43f0aee..04e40507c 100644 --- a/Pod/Classes/UI/Private/UIViewController+LockNotification.m +++ b/Pod/Classes/UI/Private/UIViewController+LockNotification.m @@ -27,6 +27,7 @@ #import "A0Strategy.h" #import "A0Connection.h" #import "A0AuthParameters.h" +#import "A0Lock.h" @implementation UIViewController (LockNotification) @@ -39,8 +40,13 @@ - (void)postLoginErrorNotificationWithError:(NSError *)error { } - (void)postLoginSuccessfulWithUsername:(NSString *)username andParameters:(A0AuthParameters *)parameters { - A0APIClient *client = [A0APIClient sharedClient]; - NSString *connectionName = [parameters valueForKey:@"connection"] ?: client.application.databaseStrategy.connections.firstObject; + NSString *connectionName; + if ([self respondsToSelector:@selector(lock)]) { + A0Lock *lock = [self performSelector:@selector(lock)]; + A0APIClient *client = lock.apiClient; + connectionName = [parameters valueForKey:@"connection"] ?: client.application.databaseStrategy.connections.firstObject; + } + [[NSNotificationCenter defaultCenter] postNotificationName:A0LockNotificationLoginSuccessful object:nil userInfo:@{ From 791a7223befce3a1484d299b875ae4a080a8b489 Mon Sep 17 00:00:00 2001 From: Hernan Zalazar Date: Fri, 8 May 2015 19:20:31 -0300 Subject: [PATCH 7/7] Avoid deprecated method of A0UserAPIClient. --- Pod/Classes/Core/A0Lock.h | 19 +++++++++++++++++++ Pod/Classes/Core/A0Lock.m | 5 +++++ .../TouchID/A0TouchIDLockViewController.m | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Pod/Classes/Core/A0Lock.h b/Pod/Classes/Core/A0Lock.h index c3aba9df9..ba49e8c07 100644 --- a/Pod/Classes/Core/A0Lock.h +++ b/Pod/Classes/Core/A0Lock.h @@ -23,6 +23,8 @@ #import #import "A0APIClientProvider.h" +@class A0APIClient, A0UserAPIClient; + /** * Main interface with Auth0 Lock for iOS. */ @@ -108,4 +110,21 @@ domain:(NSString *)domain configurationDomain:(NSString *)configurationDomain; + +/** + * Auth0 Authentication API client. + * + * @return an API client + */ +- (A0APIClient *)apiClient; + +/** + * API client to make request to Auth0 authorized by the id_token + * + * @param idToken user's id_token + * + * @return an new API client + */ +- (A0UserAPIClient *)newUserAPIClientWithIdToken:(NSString *)idToken; + @end diff --git a/Pod/Classes/Core/A0Lock.m b/Pod/Classes/Core/A0Lock.m index 388a47e3b..2e73d0f29 100644 --- a/Pod/Classes/Core/A0Lock.m +++ b/Pod/Classes/Core/A0Lock.m @@ -23,6 +23,7 @@ #import "A0Lock.h" #import "A0APIv1Router.h" #import "A0APIClient.h" +#import "A0UserAPIClient.h" #define kCDNConfigurationURL @"https://cdn.auth0.com" #define kEUCDNConfigurationURL @"https://cdn.eu.auth0.com" @@ -101,6 +102,10 @@ - (A0APIClient *)apiClient { return self.client; } +- (A0UserAPIClient *)newUserAPIClientWithIdToken:(NSString *)idToken { + return [[A0UserAPIClient alloc] initWithRouter:self.router idToken:idToken]; +} + - (NSString *)clientId { return [self.router clientId]; } diff --git a/Pod/Classes/TouchID/A0TouchIDLockViewController.m b/Pod/Classes/TouchID/A0TouchIDLockViewController.m index 08707996e..f586c4e46 100644 --- a/Pod/Classes/TouchID/A0TouchIDLockViewController.m +++ b/Pod/Classes/TouchID/A0TouchIDLockViewController.m @@ -151,7 +151,7 @@ - (void)viewDidLoad { A0LogDebug(@"User %@ registered. Uploading public key...", profile.userId); [keychain setString:profile.userId forKey:@"auth0-userid"]; NSString *deviceName = [self deviceName]; - self.userClient = [A0UserAPIClient clientWithIdToken:token.idToken]; + self.userClient = [self.lock newUserAPIClientWithIdToken:token.idToken]; [self.userClient removePublicKeyOfDevice:deviceName user:profile.userId success:^{ @strongify(self); [self.userClient registerPublicKey:pubKey device:deviceName user:profile.userId success:completionBlock failure:errorBlock];