Skip to content

Restructure authentication provider APIs on PFUser to be able to publicly support them. #136

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 3, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#import <Foundation/Foundation.h>

#import <Parse/PFConstants.h>

#import "PFAuthenticationProvider.h"

NS_ASSUME_NONNULL_BEGIN
Expand All @@ -31,26 +33,17 @@ NS_ASSUME_NONNULL_BEGIN
/// @name Authentication
///--------------------------------------

- (BFTask *)authenticateAsyncWithProviderForAuthType:(NSString *)authType;
- (BFTask *)deauthenticateAsyncWithProviderForAuthType:(NSString *)authType;

- (BOOL)restoreAuthenticationWithAuthData:(nullable NSDictionary *)authData
withProviderForAuthType:(NSString *)authType;
- (BFTask *)restoreAuthenticationAsyncWithAuthData:(nullable NSDictionary *)authData
forProviderWithAuthType:(NSString *)authType;

///--------------------------------------
/// @name Log In
///--------------------------------------

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

///--------------------------------------
/// @name Link
///--------------------------------------

- (BFTask *)linkUserAsync:(PFUser *)user withAuthType:(NSString *)authType;
- (BFTask *)linkUserAsync:(PFUser *)user withAuthType:(NSString *)authType authData:(NSDictionary *)authData;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@

#import "PFUserAuthenticationController.h"

#import <Bolts/BFTask.h>

#import "BFTask+Private.h"
#import "PFMacros.h"
#import "PFUserPrivate.h"
#import "PFObjectPrivate.h"
#import "PFAnonymousUtils.h"
#import "PFAnonymousAuthenticationProvider.h"
#import "PFUserController.h"
#import "PFAssert.h"

@interface PFUserAuthenticationController () {
dispatch_queue_t _dataAccessQueue;
Expand Down Expand Up @@ -42,10 +46,13 @@ - (instancetype)init {
///--------------------------------------

- (void)registerAuthenticationProvider:(id<PFAuthenticationProvider>)provider {
PFParameterAssert(provider, @"Authentication provider can't be `nil`.");

NSString *authType = [[provider class] authType];
if (!authType) {
return;
}
PFParameterAssert(authType, @"Authentication provider's `authType` can't be `nil`.");
PFConsistencyAssert(![self authenticationProviderForAuthType:authType],
@"Authentication provider already registered for authType `%@`.", authType);

dispatch_sync(_dataAccessQueue, ^{
_authenticationProviders[authType] = provider;
});
Expand Down Expand Up @@ -82,57 +89,81 @@ - (void)unregisterAuthenticationProvider:(id<PFAuthenticationProvider>)provider
#pragma mark - Authentication
///--------------------------------------

- (BFTask *)authenticateAsyncWithProviderForAuthType:(NSString *)authType {
id<PFAuthenticationProvider> provider = [self authenticationProviderForAuthType:authType];
return [provider authenticateAsync];
}

- (BFTask *)deauthenticateAsyncWithProviderForAuthType:(NSString *)authType {
id<PFAuthenticationProvider> provider = [self authenticationProviderForAuthType:authType];
if (provider) {
return [provider deauthenticateAsync];
return [provider deauthenticateInBackground];
}
return [BFTask taskWithResult:nil];
}

- (BOOL)restoreAuthenticationWithAuthData:(NSDictionary *)authData withProviderForAuthType:(NSString *)authType {
- (BFTask *)restoreAuthenticationAsyncWithAuthData:(nullable NSDictionary *)authData
forProviderWithAuthType:(NSString *)authType {
id<PFAuthenticationProvider> provider = [self authenticationProviderForAuthType:authType];
if (!provider) {
return YES;
return [BFTask taskWithResult:nil];
}
return [provider restoreAuthenticationWithAuthData:authData];
return [provider restoreAuthenticationInBackgroundWithAuthData:authData];
}

///--------------------------------------
#pragma mark - Log In
///--------------------------------------

- (BFTask *)logInUserAsyncWithAuthType:(NSString *)authType {
@weakify(self);
return [[self authenticateAsyncWithProviderForAuthType:authType] continueWithSuccessBlock:^id(BFTask *task) {
@strongify(self);
return [self logInUserAsyncWithAuthType:authType authData:task.result];
}];
}

- (BFTask *)logInUserAsyncWithAuthType:(NSString *)authType authData:(NSDictionary *)authData {
return [PFUser _logInWithAuthTypeInBackground:authType authData:authData];
}

///--------------------------------------
#pragma mark - Link
///--------------------------------------

- (BFTask *)linkUserAsync:(PFUser *)user withAuthType:(NSString *)authType {
@weakify(self);
return [[self authenticateAsyncWithProviderForAuthType:authType] continueWithSuccessBlock:^id(BFTask *task) {
@strongify(self);
return [self linkUserAsync:user withAuthType:authType authData:task.result];
}];
}
//TODO: (nlutsenko) Make it fully async.
//TODO: (nlutsenko) Inject `PFUserController` here.
PFUser *currentUser = [PFUser currentUser];
if (currentUser && [PFAnonymousUtils isLinkedWithUser:currentUser]) {
if ([currentUser isLazy]) {
PFUser *user = currentUser;
BFTask *resolveLaziness = nil;
NSDictionary *oldAnonymousData = nil;
@synchronized (user.lock) {
oldAnonymousData = user.authData[[PFAnonymousAuthenticationProvider authType]];

// Replace any anonymity with the new linked authData
[user stripAnonymity];

[user.authData setObject:authData forKey:authType];
[user.linkedServiceNames addObject:authType];

resolveLaziness = [user resolveLazinessAsync:[BFTask taskWithResult:nil]];
}

return [resolveLaziness continueAsyncWithBlock:^id(BFTask *task) {
if (task.isCancelled || task.exception || task.error) {
[user.authData removeObjectForKey:authType];
[user.linkedServiceNames removeObject:authType];
[user restoreAnonymity:oldAnonymousData];
return task;
}
return task.result;
}];
} else {
return [[currentUser linkWithAuthTypeInBackground:authType
authData:authData] continueAsyncWithBlock:^id(BFTask *task) {
NSError *error = task.error;
if (error) {
if (error.code == kPFErrorAccountAlreadyLinked) {
// An account that's linked to the given authData already exists,
// so log in instead of trying to claim.
return [[PFUser userController] logInCurrentUserAsyncWithAuthType:authType
authData:authData
revocableSession:[PFUser _isRevocableSessionEnabled]];
} else {
return task;
}
}

return [BFTask taskWithResult:currentUser];
}];
}
}
return [[PFUser userController] logInCurrentUserAsyncWithAuthType:authType
authData:authData
revocableSession:[PFUser _isRevocableSessionEnabled]];

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

@end
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,12 @@ + (NSString *)authType {
return @"anonymous";
}

- (BFTask *)authenticateAsync {
return [BFTask taskWithResult:self.authData];
}

- (BFTask *)deauthenticateAsync {
- (BFTask *)deauthenticateInBackground {
return [BFTask taskWithResult:nil];
}

- (BOOL)restoreAuthenticationWithAuthData:(NSDictionary *)authData {
return YES;
- (BFTask *)restoreAuthenticationInBackgroundWithAuthData:(NSDictionary *)authData {
return [BFTask taskWithResult:nil];
}

///--------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/

#import "PFAnonymousUtils.h"
#import <Parse/PFAnonymousUtils.h>

@class PFAnonymousAuthenticationProvider;
@class PFUser;

@interface PFAnonymousUtils (Private)

+ (PFAnonymousAuthenticationProvider *)_authenticationProvider;
+ (void)_clearAuthenticationProvider;

+ (PFUser *)_lazyLogIn;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@

#import <Foundation/Foundation.h>

@class BFTask;
#import <Bolts/BFTask.h>

#import <Parse/PFConstants.h>

//TODO: (nlutsenko) Update documentation for all these methods.

PF_ASSUME_NONNULL_BEGIN

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

/*!
Invoked by a PFUser to authenticate with the service. This function should call back PFUser (using the supplied blocks) to notify it of success.
The NSDictionary passed to the success block should contain relevant authData (and should match the server's expectations of data to be used
for verifying identity on the server).
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.
*/
- (BFTask *)authenticateAsync;

/*!
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.
*/
- (BFTask *)deauthenticateAsync;
- (BFTask *)deauthenticateInBackground;

/*!
Upon logging in (or restoring a PFUser from disk), authData is returned from the server, and the PFUser passes that data into this function,
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
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
internal state. Returning NO from this function indicates the authData was somehow invalid, and the user should be unlinked from the provider.
*/
- (BOOL)restoreAuthenticationWithAuthData:(NSDictionary *)authData;
- (BFTask *)restoreAuthenticationInBackgroundWithAuthData:(PF_NULLABLE NSDictionary *)authData;

@end

PF_ASSUME_NONNULL_END
32 changes: 26 additions & 6 deletions Parse/Internal/User/PFUserPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

#import <Foundation/Foundation.h>

# import <Parse/PFUser.h>
#import <Parse/PFUser.h>

#import "PFAuthenticationProvider.h"

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

@class BFTask;
@class PFCommandResult;
@class PFUserController;

@interface PFUser (Private)

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

- (void)checkSignUpParams;

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

- (BFTask *)_linkWithAuthTypeInBackground:(NSString *)authType authData:(NSDictionary *)authData;

- (BFTask *)_unlinkWithAuthTypeInBackground:(NSString *)authType;

- (void)synchronizeAuthDataWithAuthType:(NSString *)authType;

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

+ (PFUserController *)userController;

@end

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

- (BFTask *)_logOutAsync;

///--------------------------------------
/// @name Authentication Providers
///--------------------------------------

// TODO: (nlutsenko) Add Documentation
+ (void)registerAuthenticationProvider:(id<PFAuthenticationProvider>)authenticationProvider;

// TODO: (nlutsenko) Add Documentation
+ (BFTask *)logInWithAuthTypeInBackground:(NSString *)authType authData:(NSDictionary *)authData;

// TODO: (nlutsenko) Add Documentation
- (BFTask *)linkWithAuthTypeInBackground:(NSString *)authType authData:(NSDictionary *)authData;

// TODO: (nlutsenko) Add Documentation
- (BFTask *)unlinkWithAuthTypeInBackground:(NSString *)authType;

///--------------------------------------
/// @name Authentication Providers (Private)
///--------------------------------------

+ (void)_unregisterAuthenticationProvider:(id<PFAuthenticationProvider>)provider;

@end
Loading