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

add VKontakte provider #107

Open
wants to merge 10 commits 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
9 changes: 6 additions & 3 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ PODS:
- SimpleAuth/Tumblr (= 0.3.9)
- SimpleAuth/Twitter (= 0.3.9)
- SimpleAuth/TwitterWeb (= 0.3.9)
- SimpleAuth/VKontakteWeb (= 0.3.9)
- SimpleAuth/BoxWeb (0.3.9):
- SimpleAuth/Core
- SimpleAuth/Core (0.3.9):
Expand Down Expand Up @@ -72,20 +73,22 @@ PODS:
- SimpleAuth/TwitterWeb (0.3.9):
- cocoa-oauth
- SimpleAuth/Core
- SimpleAuth/VKontakteWeb (0.3.9):
- SimpleAuth/Core

DEPENDENCIES:
- SimpleAuth (from `..`)

EXTERNAL SOURCES:
SimpleAuth:
:path: ".."
:path: ..

SPEC CHECKSUMS:
CMDQueryStringSerialization: 03c5d9847a4eaa2b3e4e439ce1ae24f914cc7fe1
cocoa-oauth: 1200a2170276a62a975f2786d505dab6e2db1fa8
ISO8601: 8805b6cd6b2d0f7e594f7c5b50e8b00b51695ac0
NSData+Base64: 4e84902c4db907a15673474677e57763ef3903e4
ReactiveCocoa: e2db045570aa97c695e7aa97c2bcab222ae51f4a
SimpleAuth: bc7d594f90711a7e6ef7624dce5aa8c8b09770ab
SimpleAuth: 84c0a98a8797f3b9400d699f3a2c7e3be5dde1ca

COCOAPODS: 0.36.4
COCOAPODS: 0.37.2
1 change: 1 addition & 0 deletions Example/SimpleAuth/Providers.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@
<string>trello-web</string>
<string>box-web</string>
<string>onedrive-web</string>
<string>vkontakte-web</string>
</array>
</plist>
4 changes: 4 additions & 0 deletions Example/SimpleAuth/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 Expand Up @@ -88,6 +89,9 @@ - (void)configureAuthorizaionProviders {

// client_id and client_secret are required
SimpleAuth.configuration[@"onedrive-web"] = @{};

// client_id is required
SimpleAuth.configuration[@"vkontakte-web"] = @{};
}


Expand Down
24 changes: 24 additions & 0 deletions Pod/Core/SimpleAuth.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,30 @@
*/
+ (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;

/**
Determine whether the provider can handle the callback URL or not.

Expand Down
27 changes: 27 additions & 0 deletions Pod/Core/SimpleAuth.m
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,33 @@ + (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
}];
}

+ (BOOL)handleCallback:(NSURL *)URL {
NSParameterAssert(URL != nil);
Expand Down
1 change: 1 addition & 0 deletions Pod/Core/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 Pod/Core/SimpleAuthProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,9 @@ - (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];
}

@end
8 changes: 6 additions & 2 deletions Pod/Providers/Facebook/SimpleAuthFacebookProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ - (RACSignal *)systemAccount {
- (RACSignal *)remoteAccountWithSystemAccount:(ACAccount *)account {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSURL *URL = [NSURL URLWithString:@"https://graph.facebook.com/me"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:URL parameters:nil];
NSDictionary *parameters = @{
@"fields" : @"name,first_name,last_name,verified,email,location,link"
};
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:URL parameters:parameters];
request.account = account;
[request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *connectionError) {
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)];
Expand Down Expand Up @@ -140,7 +143,8 @@ - (NSDictionary *)infoDictionaryWithRemoteAccount:(NSDictionary *)remoteAccount
if (location) {
dictionary[@"location"] = location;
}

if (remoteAccount[@"verified"])
dictionary[@"verified"] = remoteAccount[@"verified"];
dictionary[@"urls"] = @{
@"Facebook": remoteAccount[@"link"]
};
Expand Down
68 changes: 67 additions & 1 deletion Pod/Providers/FacebookWeb/SimpleAuthFaceBookWebProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,27 @@ - (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,10 +119,55 @@ - (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) {
NSDictionary *parameters = @{ @"access_token" : accessToken[@"access_token"] };
NSDictionary *parameters = @{
@"access_token" : accessToken[@"access_token"],
@"fields" : @"name,first_name,last_name,verified,email,location,link"
};
NSString *URLString = [NSString stringWithFormat:
@"https://graph.facebook.com/me?%@",
[CMDQueryStringSerialization queryStringWithDictionary:parameters]];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// SimpleAuthVKontakteWebLoginViewController.h
// SimpleAuth
//
// Created by Mikhail Kupriyanov on 7/7/15.
//

#import "SimpleAuthWebViewController.h"

@interface SimpleAuthVKontakteWebLoginViewController : SimpleAuthWebViewController

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// SimpleAuthVKontakteWebLoginViewController.m
// SimpleAuth
//
// Created by Mikhail Kupriyanov on 7/7/15.
//

#import "SimpleAuthVKontakteWebLoginViewController.h"

@implementation SimpleAuthVKontakteWebLoginViewController

#pragma mark - SimpleAuthWebViewController

- (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken {
if ((self = [super initWithOptions:options requestToken:requestToken])) {
self.title = @"VKontakte";
}
return self;
}

- (NSURLRequest *)initialRequest {
NSDictionary *parameters = @{
@"client_id" : self.options[@"client_id"],
@"redirect_uri" : self.options[SimpleAuthRedirectURIKey],
@"response_type" : @"token",
@"scope" : [self.options[@"permission"] componentsJoinedByString:@","],
@"display" : @"mobile",
@"v" : @"5.34"
};

NSString *URLString = [NSString stringWithFormat:
@"https://oauth.vk.com/authorize?%@",
[CMDQueryStringSerialization queryStringWithDictionary:parameters]];
NSURL *URL = [NSURL URLWithString:URLString];

return [NSURLRequest requestWithURL:URL];
}

@end
12 changes: 12 additions & 0 deletions Pod/Providers/VKontakteWeb/SimpleAuthVKontakteWebProvider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// SimpleAuthVKontakteWebProvider.h
// SimpleAuth
//
// Created by Mikhail Kupriyanov on 7/7/15.
//

#import "SimpleAuthProvider.h"

@interface SimpleAuthVKontakteWebProvider : SimpleAuthProvider

@end
Loading