Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
william26 committed Aug 6, 2014
2 parents cfef2ef + 36a2aa1 commit bae6438
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 9 deletions.
1 change: 1 addition & 0 deletions Dist/OAuthiOS.framework/Versions/A/Headers/OAuthIOData.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
@property (nonatomic, strong) NSDictionary *request_conf;

@property (nonatomic, strong) NSString *oauth_token;
@property (nonatomic, strong) NSString *code;
@property (nonatomic, strong) NSString *oauth_token_secret;
@property (nonatomic, strong) NSString *access_token;
@property (nonatomic, strong) NSString *request_url;
Expand Down
9 changes: 8 additions & 1 deletion Dist/OAuthiOS.framework/Versions/A/Headers/OAuthIOModal.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
@protocol OAuthIODelegate <NSObject>
- (void)didReceiveOAuthIOResponse:(OAuthIORequest *)request;
- (void)didFailWithOAuthIOError:(NSError *)error;
- (void)didReceiveOAuthIOCode:(NSString *)code;
- (void)didAuthenticateServerSide:(NSString *)body andResponse:(NSURLResponse *) response;
- (void)didFailAuthenticationServerSide:(NSString *)body andResponse:(NSURLResponse *)response andError:(NSError *)error;
@end

@interface OAuthIOModal : UIViewController<UIWebViewDelegate>
Expand All @@ -43,15 +46,19 @@
UIWebView *_browser;
UINavigationBar *_navigationBar;
NSUInteger _navigationBarHeight;


}

@property NSMutableArray *saved_cookies;
@property (weak) id<OAuthIODelegate> delegate;
@property NSURLSession *session;
@property NSString *authUrl;

- (id)initWithKey:(NSString *)key delegate:(id)delegate;
- (id)initWithKey:(NSString *)key delegate:(id)delegate andOptions:(NSDictionary *) options;
- (void)showWithProvider:(NSString *)provider;
- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options;
- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options stateTokenUrl:(NSString*) stateUrl authUrl:(NSString*) authUrl;
- (BOOL) clearCache;
- (BOOL) clearCacheForProvider:(NSString *)provider;
- (BOOL) cacheAvailableForProvider:(NSString *)provider;
Expand Down
Binary file modified Dist/OAuthiOS.framework/Versions/A/OAuthiOS
Binary file not shown.
4 changes: 2 additions & 2 deletions OAuth.io.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Pod::Spec.new do |s|
#

s.name = "OAuth.io"
s.version = "1.1.3"
s.version = "1.2.0"
s.summary = "OAuth that just works!"

s.description = <<-DESC
Expand Down Expand Up @@ -71,7 +71,7 @@ Pod::Spec.new do |s|
# Supports git, hg, bzr, svn and HTTP.
#

s.source = { :git => "https://github.com/oauth-io/oauth-ios.git", :tag => "1.1.3" }
s.source = { :git => "https://github.com/oauth-io/oauth-ios.git", :tag => "1.2.0" }


# ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
Expand Down
1 change: 1 addition & 0 deletions OAuthiOS/Src/OAuthIOData.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
@property (nonatomic, strong) NSDictionary *request_conf;

@property (nonatomic, strong) NSString *oauth_token;
@property (nonatomic, strong) NSString *code;
@property (nonatomic, strong) NSString *oauth_token_secret;
@property (nonatomic, strong) NSString *access_token;
@property (nonatomic, strong) NSString *request_url;
Expand Down
5 changes: 4 additions & 1 deletion OAuthiOS/Src/OAuthIOData.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ - (id)initWithDictionary:(NSDictionary *)dict

[_request setValue:_oauth_token forKey:@"oauth_token"];
[_request setValue:_oauth_token_secret forKey:@"oauth_token_secret"];
} else {
} else if ([[dict objectForKey:@"data"] objectForKey:@"code"] != nil) {
_code = [[dict objectForKey:@"data"] objectForKey:@"code"];
_request = nil;
}else {
[NSException raise:@"Wrong credentials" format:@"A problem occured with the credentials data initialization"];
}

Expand Down
9 changes: 8 additions & 1 deletion OAuthiOS/Src/OAuthIOModal.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
@protocol OAuthIODelegate <NSObject>
- (void)didReceiveOAuthIOResponse:(OAuthIORequest *)request;
- (void)didFailWithOAuthIOError:(NSError *)error;
- (void)didReceiveOAuthIOCode:(NSString *)code;
- (void)didAuthenticateServerSide:(NSString *)body andResponse:(NSURLResponse *) response;
- (void)didFailAuthenticationServerSide:(NSString *)body andResponse:(NSURLResponse *)response andError:(NSError *)error;
@end

@interface OAuthIOModal : UIViewController<UIWebViewDelegate>
Expand All @@ -43,15 +46,19 @@
UIWebView *_browser;
UINavigationBar *_navigationBar;
NSUInteger _navigationBarHeight;


}

@property NSMutableArray *saved_cookies;
@property (weak) id<OAuthIODelegate> delegate;
@property NSURLSession *session;
@property NSString *authUrl;

- (id)initWithKey:(NSString *)key delegate:(id)delegate;
- (id)initWithKey:(NSString *)key delegate:(id)delegate andOptions:(NSDictionary *) options;
- (void)showWithProvider:(NSString *)provider;
- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options;
- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options stateTokenUrl:(NSString*) stateUrl authUrl:(NSString*) authUrl;
- (BOOL) clearCache;
- (BOOL) clearCacheForProvider:(NSString *)provider;
- (BOOL) cacheAvailableForProvider:(NSString *)provider;
Expand Down
93 changes: 89 additions & 4 deletions OAuthiOS/Src/OAuthIOModal.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#import "OAuthIOModal.h"

@implementation OAuthIOModal

NSString *_host;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
Expand Down Expand Up @@ -146,10 +145,63 @@ - (void)getTokens:(NSString *)url
[data_to_file writeToFile:file_url atomically:YES];
}

if (_saved_cookies != nil) {
NSHTTPCookie *cookie;
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (cookie in _saved_cookies) {
[storage setCookie:cookie];
}
[[NSUserDefaults standardUserDefaults] synchronize];
}


@try {
OAuthIORequest *request = [self buildRequestObject:json];
if ([self.delegate respondsToSelector:@selector(didReceiveOAuthIOResponse:)])
[self.delegate didReceiveOAuthIOResponse:request];
if ([[request getCredentials] objectForKey:@"code"] != nil && _authUrl != nil) {
//Signing in to the selected URL, giving back the response

NSString *code = [[request getCredentials] objectForKey:@"code"];
NSString *post = [NSString stringWithFormat:@"code=%@", code];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
NSMutableURLRequest *state_request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:_authUrl]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[state_request setHTTPMethod:@"POST"];
[state_request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[state_request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[state_request setHTTPBody:postData];

[[_session dataTaskWithRequest:state_request
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
NSString *body = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
if ([httpResponse statusCode] == 200) {
if ([self.delegate respondsToSelector:@selector(didAuthenticateServerSide:andResponse:)])
[self.delegate didAuthenticateServerSide:body andResponse:response];
} else {
NSDictionary *userInfo = @{
NSLocalizedDescriptionKey: NSLocalizedString(@"Operation was unsuccessful.", nil),
NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The authentication endpoint did not return 200 OK.", nil),
NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Are you using the right authentication endpoint?", nil)
};
NSError *error = [NSError errorWithDomain:@"com.oauthio.error"
code:-1
userInfo:userInfo];
if ([self.delegate respondsToSelector:@selector(didFailAuthenticationServerSide:andResponse:andError:)])
[self.delegate didFailAuthenticationServerSide:body andResponse:response andError:error];
}
}] resume];

} else if ([[request getCredentials] objectForKey:@"code"] != nil) {
if ([self.delegate respondsToSelector:@selector(didReceiveOAuthIOCode:)])
[self.delegate didReceiveOAuthIOCode:[[request getCredentials] objectForKey:@"code"]];
}else {
if ([self.delegate respondsToSelector:@selector(didReceiveOAuthIOResponse:)])
[self.delegate didReceiveOAuthIOResponse:request];
}
}
@catch (NSException *e) {
NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary];
Expand Down Expand Up @@ -251,6 +303,38 @@ - (void)showWithProvider:(NSString *)provider {
[self showWithProvider:provider options:nil];
}

- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options stateTokenUrl:(NSString*) stateUrl authUrl:(NSString*) authUrl;
{
_session = [NSURLSession sharedSession];
_authUrl = authUrl;
[[_session dataTaskWithURL:[NSURL URLWithString:stateUrl]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSString *body = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
if (dictionary != nil && [dictionary objectForKey:@"token"] != nil) {

NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSMutableDictionary *options_mut = [options mutableCopy];
[options_mut setObject:[dictionary objectForKey:@"token"] forKey:@"state"];
[self showWithProvider:provider options:options_mut];
} else {
NSDictionary *userInfo = @{
NSLocalizedDescriptionKey: NSLocalizedString(@"Operation was unsuccessful.", nil),
NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The state token could not be retrieved.", nil),
NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Are you using the right state token retrieval endpoint?", nil)
};
NSError *error = [NSError errorWithDomain:@"com.oauthio.error"
code:-1
userInfo:userInfo];
if ([self.delegate respondsToSelector:@selector(didFailAuthenticationServerSide:andResponse:andError:)])
[self.delegate didFailAuthenticationServerSide:body andResponse:response andError:error];
}

}] resume];
}

- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options
{
_options = options;
Expand Down Expand Up @@ -293,11 +377,12 @@ - (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options

NSURLRequest *url = [_oauth getOAuthRequest:provider andUrl:_callback_url andOptions:options];
if ([[_options objectForKey:@"clear-popup-cache"] isEqual: @"true"]) {
// [[NSURLCache sharedURLCache] removeAllCachedResponses];
NSHTTPCookie *cookie;
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
_saved_cookies = [[NSMutableArray alloc] init];
for (cookie in [storage cookies]) {
[storage deleteCookie:cookie];
[_saved_cookies addObject:cookie];
}
[[NSUserDefaults standardUserDefaults] synchronize];
}
Expand Down
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,42 @@ You can filter the fields returned by this method by passing a `NSArray` contain
}];
```

Notes on the server-side flow
=============================

If you're planning to use OAuth.io from your back-end thanks to one of our server-side SDKs, the usage of this SDK is a bit different.

First, a little reminder of the server-side flow, in which all API calls are performed server-side, as well as authentication (thanks to a code retrieved in the front-end). The server-side flow involves the following steps:

- Retrieving of a state token from your back-end in your front-end
- Launching the authentication popup in the front-end, with the state token, gives back a code
- Sending the code back to the back-end
- Authenticating in the back-end thanks to the code
- Performing API calls in the back-end

Thus, in your back-end, you need two endpoints:

- one for the state token (GET)
- one for the authentication (POST with the code as parameter)

In the iOS SDK, the calls to these endpoints are performed automatically. All you need to do is give their URLs to the `showWithProvider` method like this:

```Objective-C
[_oauthioModal showWithProvider:@"facebook" options:options stateTokenUrl:@"http://example/state/url" authUrl:@"http://example/auth/url"];
```
This will first call the state URL, then show the authentication popup to the user, get the code, and finally send the code to the authentication URL.
To know when the process is done, you need to add the following methods to your OAuthIODelegate class:
```Objective-C
- (void)didAuthenticateServerSide:(NSString *)body andResponse:(NSURLResponse *) response;
- (void)didFailAuthenticationServerSide:(NSString *)body andResponse:(NSURLResponse *)response andError:(NSError *)error;
```

The first one will catches a successfull authentication (which usually means the authentication URL returned "200 OK") and give you the body and response objects it got from that URL. The second one will catch errors (state token not found, unsucessfull authentication).


Contributing
============

Expand Down

0 comments on commit bae6438

Please sign in to comment.