Skip to content

Commit 8b2b57b

Browse files
committed
Merge pull request #136 from ParsePlatform/nlutsenko.authProviders
Restructure authentication provider APIs on PFUser to be able to publicly support them.
2 parents 572f6d1 + 792e4aa commit 8b2b57b

File tree

10 files changed

+299
-235
lines changed

10 files changed

+299
-235
lines changed

Parse/Internal/User/AuthenticationProviders/Controller/PFUserAuthenticationController.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
#import <Foundation/Foundation.h>
1111

12+
#import <Parse/PFConstants.h>
13+
1214
#import "PFAuthenticationProvider.h"
1315

1416
NS_ASSUME_NONNULL_BEGIN
@@ -31,26 +33,17 @@ NS_ASSUME_NONNULL_BEGIN
3133
/// @name Authentication
3234
///--------------------------------------
3335

34-
- (BFTask *)authenticateAsyncWithProviderForAuthType:(NSString *)authType;
3536
- (BFTask *)deauthenticateAsyncWithProviderForAuthType:(NSString *)authType;
3637

37-
- (BOOL)restoreAuthenticationWithAuthData:(nullable NSDictionary *)authData
38-
withProviderForAuthType:(NSString *)authType;
38+
- (BFTask *)restoreAuthenticationAsyncWithAuthData:(nullable NSDictionary *)authData
39+
forProviderWithAuthType:(NSString *)authType;
3940

4041
///--------------------------------------
4142
/// @name Log In
4243
///--------------------------------------
4344

44-
- (BFTask *)logInUserAsyncWithAuthType:(NSString *)authType;
4545
- (BFTask *)logInUserAsyncWithAuthType:(NSString *)authType authData:(NSDictionary *)authData;
4646

47-
///--------------------------------------
48-
/// @name Link
49-
///--------------------------------------
50-
51-
- (BFTask *)linkUserAsync:(PFUser *)user withAuthType:(NSString *)authType;
52-
- (BFTask *)linkUserAsync:(PFUser *)user withAuthType:(NSString *)authType authData:(NSDictionary *)authData;
53-
5447
@end
5548

5649
NS_ASSUME_NONNULL_END

Parse/Internal/User/AuthenticationProviders/Controller/PFUserAuthenticationController.m

Lines changed: 69 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@
99

1010
#import "PFUserAuthenticationController.h"
1111

12-
#import <Bolts/BFTask.h>
13-
12+
#import "BFTask+Private.h"
1413
#import "PFMacros.h"
1514
#import "PFUserPrivate.h"
15+
#import "PFObjectPrivate.h"
16+
#import "PFAnonymousUtils.h"
17+
#import "PFAnonymousAuthenticationProvider.h"
18+
#import "PFUserController.h"
19+
#import "PFAssert.h"
1620

1721
@interface PFUserAuthenticationController () {
1822
dispatch_queue_t _dataAccessQueue;
@@ -42,10 +46,13 @@ - (instancetype)init {
4246
///--------------------------------------
4347

4448
- (void)registerAuthenticationProvider:(id<PFAuthenticationProvider>)provider {
49+
PFParameterAssert(provider, @"Authentication provider can't be `nil`.");
50+
4551
NSString *authType = [[provider class] authType];
46-
if (!authType) {
47-
return;
48-
}
52+
PFParameterAssert(authType, @"Authentication provider's `authType` can't be `nil`.");
53+
PFConsistencyAssert(![self authenticationProviderForAuthType:authType],
54+
@"Authentication provider already registered for authType `%@`.", authType);
55+
4956
dispatch_sync(_dataAccessQueue, ^{
5057
_authenticationProviders[authType] = provider;
5158
});
@@ -82,57 +89,81 @@ - (void)unregisterAuthenticationProvider:(id<PFAuthenticationProvider>)provider
8289
#pragma mark - Authentication
8390
///--------------------------------------
8491

85-
- (BFTask *)authenticateAsyncWithProviderForAuthType:(NSString *)authType {
86-
id<PFAuthenticationProvider> provider = [self authenticationProviderForAuthType:authType];
87-
return [provider authenticateAsync];
88-
}
89-
9092
- (BFTask *)deauthenticateAsyncWithProviderForAuthType:(NSString *)authType {
9193
id<PFAuthenticationProvider> provider = [self authenticationProviderForAuthType:authType];
9294
if (provider) {
93-
return [provider deauthenticateAsync];
95+
return [provider deauthenticateInBackground];
9496
}
9597
return [BFTask taskWithResult:nil];
9698
}
9799

98-
- (BOOL)restoreAuthenticationWithAuthData:(NSDictionary *)authData withProviderForAuthType:(NSString *)authType {
100+
- (BFTask *)restoreAuthenticationAsyncWithAuthData:(nullable NSDictionary *)authData
101+
forProviderWithAuthType:(NSString *)authType {
99102
id<PFAuthenticationProvider> provider = [self authenticationProviderForAuthType:authType];
100103
if (!provider) {
101-
return YES;
104+
return [BFTask taskWithResult:nil];
102105
}
103-
return [provider restoreAuthenticationWithAuthData:authData];
106+
return [provider restoreAuthenticationInBackgroundWithAuthData:authData];
104107
}
105108

106109
///--------------------------------------
107110
#pragma mark - Log In
108111
///--------------------------------------
109112

110-
- (BFTask *)logInUserAsyncWithAuthType:(NSString *)authType {
111-
@weakify(self);
112-
return [[self authenticateAsyncWithProviderForAuthType:authType] continueWithSuccessBlock:^id(BFTask *task) {
113-
@strongify(self);
114-
return [self logInUserAsyncWithAuthType:authType authData:task.result];
115-
}];
116-
}
117-
118113
- (BFTask *)logInUserAsyncWithAuthType:(NSString *)authType authData:(NSDictionary *)authData {
119-
return [PFUser _logInWithAuthTypeInBackground:authType authData:authData];
120-
}
121-
122-
///--------------------------------------
123-
#pragma mark - Link
124-
///--------------------------------------
125-
126-
- (BFTask *)linkUserAsync:(PFUser *)user withAuthType:(NSString *)authType {
127-
@weakify(self);
128-
return [[self authenticateAsyncWithProviderForAuthType:authType] continueWithSuccessBlock:^id(BFTask *task) {
129-
@strongify(self);
130-
return [self linkUserAsync:user withAuthType:authType authData:task.result];
131-
}];
132-
}
114+
//TODO: (nlutsenko) Make it fully async.
115+
//TODO: (nlutsenko) Inject `PFUserController` here.
116+
PFUser *currentUser = [PFUser currentUser];
117+
if (currentUser && [PFAnonymousUtils isLinkedWithUser:currentUser]) {
118+
if ([currentUser isLazy]) {
119+
PFUser *user = currentUser;
120+
BFTask *resolveLaziness = nil;
121+
NSDictionary *oldAnonymousData = nil;
122+
@synchronized (user.lock) {
123+
oldAnonymousData = user.authData[[PFAnonymousAuthenticationProvider authType]];
124+
125+
// Replace any anonymity with the new linked authData
126+
[user stripAnonymity];
127+
128+
[user.authData setObject:authData forKey:authType];
129+
[user.linkedServiceNames addObject:authType];
130+
131+
resolveLaziness = [user resolveLazinessAsync:[BFTask taskWithResult:nil]];
132+
}
133+
134+
return [resolveLaziness continueAsyncWithBlock:^id(BFTask *task) {
135+
if (task.isCancelled || task.exception || task.error) {
136+
[user.authData removeObjectForKey:authType];
137+
[user.linkedServiceNames removeObject:authType];
138+
[user restoreAnonymity:oldAnonymousData];
139+
return task;
140+
}
141+
return task.result;
142+
}];
143+
} else {
144+
return [[currentUser linkWithAuthTypeInBackground:authType
145+
authData:authData] continueAsyncWithBlock:^id(BFTask *task) {
146+
NSError *error = task.error;
147+
if (error) {
148+
if (error.code == kPFErrorAccountAlreadyLinked) {
149+
// An account that's linked to the given authData already exists,
150+
// so log in instead of trying to claim.
151+
return [[PFUser userController] logInCurrentUserAsyncWithAuthType:authType
152+
authData:authData
153+
revocableSession:[PFUser _isRevocableSessionEnabled]];
154+
} else {
155+
return task;
156+
}
157+
}
158+
159+
return [BFTask taskWithResult:currentUser];
160+
}];
161+
}
162+
}
163+
return [[PFUser userController] logInCurrentUserAsyncWithAuthType:authType
164+
authData:authData
165+
revocableSession:[PFUser _isRevocableSessionEnabled]];
133166

134-
- (BFTask *)linkUserAsync:(PFUser *)user withAuthType:(NSString *)authType authData:(NSDictionary *)authData {
135-
return [user _linkWithAuthTypeInBackground:authType authData:authData];
136167
}
137168

138169
@end

Parse/Internal/User/AuthenticationProviders/Providers/Anonymous/PFAnonymousAuthenticationProvider.m

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,12 @@ + (NSString *)authType {
2121
return @"anonymous";
2222
}
2323

24-
- (BFTask *)authenticateAsync {
25-
return [BFTask taskWithResult:self.authData];
26-
}
27-
28-
- (BFTask *)deauthenticateAsync {
24+
- (BFTask *)deauthenticateInBackground {
2925
return [BFTask taskWithResult:nil];
3026
}
3127

32-
- (BOOL)restoreAuthenticationWithAuthData:(NSDictionary *)authData {
33-
return YES;
28+
- (BFTask *)restoreAuthenticationInBackgroundWithAuthData:(NSDictionary *)authData {
29+
return [BFTask taskWithResult:nil];
3430
}
3531

3632
///--------------------------------------

Parse/Internal/User/AuthenticationProviders/Providers/Anonymous/PFAnonymousUtils_Private.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
* of patent rights can be found in the PATENTS file in the same directory.
88
*/
99

10-
#import "PFAnonymousUtils.h"
10+
#import <Parse/PFAnonymousUtils.h>
1111

1212
@class PFAnonymousAuthenticationProvider;
1313
@class PFUser;
1414

1515
@interface PFAnonymousUtils (Private)
1616

1717
+ (PFAnonymousAuthenticationProvider *)_authenticationProvider;
18+
+ (void)_clearAuthenticationProvider;
1819

1920
+ (PFUser *)_lazyLogIn;
2021

Parse/Internal/User/AuthenticationProviders/Providers/PFAuthenticationProvider.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@
99

1010
#import <Foundation/Foundation.h>
1111

12-
@class BFTask;
12+
#import <Bolts/BFTask.h>
13+
14+
#import <Parse/PFConstants.h>
15+
16+
//TODO: (nlutsenko) Update documentation for all these methods.
17+
18+
PF_ASSUME_NONNULL_BEGIN
1319

1420
/*!
1521
A common protocol for general Parse authentication providers.
@@ -26,23 +32,18 @@
2632
+ (NSString *)authType;
2733

2834
/*!
29-
Invoked by a PFUser to authenticate with the service. This function should call back PFUser (using the supplied blocks) to notify it of success.
30-
The NSDictionary passed to the success block should contain relevant authData (and should match the server's expectations of data to be used
31-
for verifying identity on the server).
35+
Invoked by a PFUser upon logOut. Deauthenticate should be used to clear any state being kept by the provider that is associated with the logged-in user.
3236
*/
33-
- (BFTask *)authenticateAsync;
34-
35-
/*!
36-
Invoked by a PFUser upon logOut. Deauthenticate should be used to clear any state being kept by the provider that is associated with the logged-in user.
37-
*/
38-
- (BFTask *)deauthenticateAsync;
37+
- (BFTask *)deauthenticateInBackground;
3938

4039
/*!
4140
Upon logging in (or restoring a PFUser from disk), authData is returned from the server, and the PFUser passes that data into this function,
4241
allowin the authentication provider to set up its internal state appropriately (e.g. setting auth tokens and keys on a service's SDK so that the SDK
4342
can be used immediately, without having to reauthorize). authData can be nil, in which case the user has been unlinked, and the service should clear its
4443
internal state. Returning NO from this function indicates the authData was somehow invalid, and the user should be unlinked from the provider.
4544
*/
46-
- (BOOL)restoreAuthenticationWithAuthData:(NSDictionary *)authData;
45+
- (BFTask *)restoreAuthenticationInBackgroundWithAuthData:(PF_NULLABLE NSDictionary *)authData;
4746

4847
@end
48+
49+
PF_ASSUME_NONNULL_END

Parse/Internal/User/PFUserPrivate.h

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
#import <Foundation/Foundation.h>
1111

12-
# import <Parse/PFUser.h>
12+
#import <Parse/PFUser.h>
1313

1414
#import "PFAuthenticationProvider.h"
1515

@@ -19,6 +19,7 @@ extern NSString *const PFUserCurrentUserKeychainItemName;
1919

2020
@class BFTask;
2121
@class PFCommandResult;
22+
@class PFUserController;
2223

2324
@interface PFUser (Private)
2425

@@ -32,13 +33,8 @@ extern NSString *const PFUserCurrentUserKeychainItemName;
3233

3334
- (void)checkSignUpParams;
3435

35-
+ (BFTask *)_logInWithAuthTypeInBackground:(NSString *)authType authData:(NSDictionary *)authData;
3636
- (BFTask *)_handleServiceLoginCommandResult:(PFCommandResult *)result;
3737

38-
- (BFTask *)_linkWithAuthTypeInBackground:(NSString *)authType authData:(NSDictionary *)authData;
39-
40-
- (BFTask *)_unlinkWithAuthTypeInBackground:(NSString *)authType;
41-
4238
- (void)synchronizeAuthDataWithAuthType:(NSString *)authType;
4339

4440
+ (PFUser *)logInLazyUserWithAuthType:(NSString *)authType authData:(NSDictionary *)authData;
@@ -52,6 +48,8 @@ extern NSString *const PFUserCurrentUserKeychainItemName;
5248
+ (BOOL)_isRevocableSessionEnabled;
5349
+ (void)_setRevocableSessionEnabled:(BOOL)enabled;
5450

51+
+ (PFUserController *)userController;
52+
5553
@end
5654

5755
// Private Properties
@@ -74,4 +72,26 @@ extern NSString *const PFUserCurrentUserKeychainItemName;
7472

7573
- (BFTask *)_logOutAsync;
7674

75+
///--------------------------------------
76+
/// @name Authentication Providers
77+
///--------------------------------------
78+
79+
// TODO: (nlutsenko) Add Documentation
80+
+ (void)registerAuthenticationProvider:(id<PFAuthenticationProvider>)authenticationProvider;
81+
82+
// TODO: (nlutsenko) Add Documentation
83+
+ (BFTask *)logInWithAuthTypeInBackground:(NSString *)authType authData:(NSDictionary *)authData;
84+
85+
// TODO: (nlutsenko) Add Documentation
86+
- (BFTask *)linkWithAuthTypeInBackground:(NSString *)authType authData:(NSDictionary *)authData;
87+
88+
// TODO: (nlutsenko) Add Documentation
89+
- (BFTask *)unlinkWithAuthTypeInBackground:(NSString *)authType;
90+
91+
///--------------------------------------
92+
/// @name Authentication Providers (Private)
93+
///--------------------------------------
94+
95+
+ (void)_unregisterAuthenticationProvider:(id<PFAuthenticationProvider>)provider;
96+
7797
@end

0 commit comments

Comments
 (0)