Skip to content
This repository has been archived by the owner on Aug 16, 2023. It is now read-only.

Added re-auth for tokens that expire #37

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion Providers/Facebook/SimpleAuthFacebookProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ - (NSDictionary *)dictionaryWithRemoteAccount:(NSDictionary *)remoteAccount syst
if (location) {
user[@"location"] = location;
}
user[@"verified"] = remoteAccount[@"verified"];
if (remoteAccount[@"verified"])
user[@"verified"] = remoteAccount[@"verified"];
user[@"urls"] = @{
@"Facebook" : remoteAccount[@"link"],
};
Expand Down
68 changes: 67 additions & 1 deletion Providers/FacebookWeb/SimpleAuthFaceBookWebProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,28 @@ - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion {
}];
}

- (void)reAuthorizeWithToken:(NSString *)token completionHandler:(SimpleAuthRequestHandler)completion{
if (token.length <= 0) {
// There is no token so we are going to use the standard login method
[self authorizeWithCompletion:completion];
return;
}
[[[self reAuthAccessTokenWithToken:token]
flattenMap:^(NSDictionary *response) {
NSArray *signals = @[
[self accountWithAccessToken:response],
[RACSignal return:response]
];
return [self rac_liftSelector:@selector(dictionaryWithAccount:accessToken:) withSignalsFromArray:signals];
}]
subscribeNext:^(id x) {
completion(x, nil);
}
error:^(NSError *error) {
completion(nil, error);
}];
}


#pragma mark - Private

Expand Down Expand Up @@ -98,6 +120,49 @@ - (RACSignal *)accessToken {
}];
}

- (RACSignal *)reAuthAccessTokenWithToken:(NSString *)preToken {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
dispatch_async(dispatch_get_main_queue(), ^{
NSDictionary *parameters = @{
@"client_id" : self.options[@"app_id"],
@"grant_type" :@"fb_exchange_token",
@"response_type" : @"token",
@"grant_type" :@"fb_exchange_token",
@"client_secret" : self.options[@"app_secret"],
@"fb_exchange_token" : preToken
};

NSString *URLString = [NSString stringWithFormat:
@"https://graph.facebook.com/oauth/access_token?%@",
[CMDQueryStringSerialization queryStringWithDictionary:parameters]];
NSError *responseError = nil;
NSURLResponse *response = nil;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:URLString]];
NSData *dataResponse = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&responseError];
if (!responseError){
NSString *responseString = [[NSString alloc] initWithData:dataResponse encoding:NSUTF8StringEncoding];
NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:responseString];
id token = dictionary[@"access_token"];
id expiration = dictionary[@"expires"];

// Check for error
if (!token || !expiration) {
[subscriber sendError:[NSError errorWithDomain:@"Missing token or experation from facebook" code:101 userInfo:nil]];
return;
}
// Send completion
[subscriber sendNext:@{@"access_token" : token, @"expires_in" : expiration}];
[subscriber sendCompleted];
}
else {
[subscriber sendError:responseError];
return ;
}
});
return nil;
}];
}


- (RACSignal *)accountWithAccessToken:(NSDictionary *)accessToken {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
Expand Down Expand Up @@ -170,7 +235,8 @@ - (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account accessToken:(NSD
if (location) {
user[@"location"] = location;
}
user[@"verified"] = account[@"verified"];
if (account[@"verified"])
user[@"verified"] = account[@"verified"];
user[@"urls"] = @{
@"Facebook" : account[@"link"],
};
Expand Down
24 changes: 24 additions & 0 deletions SimpleAuth/SimpleAuth.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,28 @@ extern NSString * const SimpleAuthEndActivityBlockKey;
*/
+ (void)authorize:(NSString *)provider options:(NSDictionary *)options completion:(SimpleAuthRequestHandler)completion;

/**
Perform re-authorization with the given provider and all previously configured
and default provider options. This is for providers where the token expires and you
want to renew the non expired token.

@param token the unexpired token recieved from the service
@param completion Called on the main queue when the operation is complete.

@see +authorize:options:completion:
*/
+ (void)reAuthorize:(NSString *)provider token:(NSString *)token completion:(SimpleAuthRequestHandler)completion;

/**
Perform re-authorization with the given provider and all previously configured
and default provider options. This is for providers where the token expires and you
want to renew the non expired token.

@param token the unexpired token recieved from the service
@param completion Called on the main queue when the operation is complete.

@see +authorize:options:completion:
*/
+ (void)reAuthorize:(NSString *)type options:(NSDictionary *)options token:(NSString *)token completion:(SimpleAuthRequestHandler)completion;

@end
29 changes: 29 additions & 0 deletions SimpleAuth/SimpleAuth.m
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,35 @@ + (void)authorize:(NSString *)type options:(NSDictionary *)options completion:(S
}


+ (void)reAuthorize:(NSString *)type token:(NSString *)token completion:(SimpleAuthRequestHandler)completion {
[self reAuthorize:type options:nil token:token completion:completion];
}


+ (void)reAuthorize:(NSString *)type options:(NSDictionary *)options token:(NSString *)token completion:(SimpleAuthRequestHandler)completion{
// Load the provider class
Class klass = [self providers][type];
NSAssert(klass, @"There is no class registered to handle %@ requests.", type);

// Create options dictionary
NSDictionary *defaultOptions = [klass defaultOptions];
NSDictionary *registeredOptions = [self configuration][type];
NSMutableDictionary *resolvedOptions = [NSMutableDictionary new];
[resolvedOptions addEntriesFromDictionary:defaultOptions];
[resolvedOptions addEntriesFromDictionary:registeredOptions];
[resolvedOptions addEntriesFromDictionary:options];

// Create the provider and run authorization
SimpleAuthProvider *provider = [(SimpleAuthProvider *)[klass alloc] initWithOptions:resolvedOptions];
[provider reAuthorizeWithToken:token completionHandler:^(id responseObject, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(responseObject, error);
});
[provider class]; // Kepp the provider around until the callback is complete
}];
}


#pragma mark - Internal

+ (void)registerProviderClass:(Class)klass {
Expand Down
1 change: 1 addition & 0 deletions SimpleAuth/SimpleAuthProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@

- (instancetype)initWithOptions:(NSDictionary *)options;
- (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion;
- (void)reAuthorizeWithToken:(NSString *)token completionHandler:(SimpleAuthRequestHandler)completion;

@end
5 changes: 5 additions & 0 deletions SimpleAuth/SimpleAuthProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion {
[self doesNotRecognizeSelector:_cmd];
}

- (void)reAuthorizeWithToken:(NSString *)token completionHandler:(SimpleAuthRequestHandler)completion {
// Provider doesn't have a re authorize token method setup revert back to standard authorization
[self authorizeWithCompletion:completion];
}


#pragma mark - Accessors

Expand Down
1 change: 1 addition & 0 deletions SimpleAuthDemo/SADAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ - (void)configureAuthorizaionProviders {

// app_id is required
SimpleAuth.configuration[@"facebook"] = @{};
// app_secret optional required for re-authorization of token
SimpleAuth.configuration[@"facebook-web"] = @{};

// client_id and redirect_uri are required
Expand Down
4 changes: 3 additions & 1 deletion SimpleAuthDemo/SADProviderListViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

#import "SimpleAuth.h"

@interface SADProviderListViewController ()
@interface SADProviderListViewController () {
NSMutableDictionary *tokens;
}

@end

Expand Down