2011-02-01 09:51:02 -06:00
|
|
|
//
|
|
|
|
// MPOAuthAPIRequestLoader.m
|
|
|
|
// MPOAuthConnection
|
|
|
|
//
|
|
|
|
// Created by Karl Adam on 08.12.05.
|
|
|
|
// Copyright 2008 matrixPointer. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#import "MPOAuthAPIRequestLoader.h"
|
|
|
|
#import "MPOAuthURLRequest.h"
|
|
|
|
#import "MPOAuthURLResponse.h"
|
|
|
|
#import "MPOAuthConnection.h"
|
|
|
|
#import "MPOAuthCredentialStore.h"
|
|
|
|
#import "MPOAuthCredentialConcreteStore.h"
|
|
|
|
#import "MPURLRequestParameter.h"
|
|
|
|
#import "NSURLResponse+Encoding.h"
|
|
|
|
#import "MPDebug.h"
|
|
|
|
|
|
|
|
NSString * const MPOAuthNotificationRequestTokenReceived = @"MPOAuthNotificationRequestTokenReceived";
|
|
|
|
NSString * const MPOAuthNotificationRequestTokenRejected = @"MPOAuthNotificationRequestTokenRejected";
|
|
|
|
NSString * const MPOAuthNotificationAccessTokenReceived = @"MPOAuthNotificationAccessTokenReceived";
|
|
|
|
NSString * const MPOAuthNotificationAccessTokenRejected = @"MPOAuthNotificationAccessTokenRejected";
|
|
|
|
NSString * const MPOAuthNotificationAccessTokenRefreshed = @"MPOAuthNotificationAccessTokenRefreshed";
|
|
|
|
NSString * const MPOAuthNotificationOAuthCredentialsReady = @"MPOAuthNotificationOAuthCredentialsReady";
|
|
|
|
NSString * const MPOAuthNotificationErrorHasOccurred = @"MPOAuthNotificationErrorHasOccurred";
|
|
|
|
|
|
|
|
@interface MPOAuthAPIRequestLoader ()
|
|
|
|
- (void)_interrogateResponseForOAuthData;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@protocol MPOAuthAPIInternalClient;
|
|
|
|
|
|
|
|
@implementation MPOAuthAPIRequestLoader
|
|
|
|
|
|
|
|
- (id)initWithURL:(NSURL *)inURL {
|
|
|
|
return [self initWithRequest:[[[MPOAuthURLRequest alloc] initWithURL:inURL andParameters:nil] autorelease]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id)initWithRequest:(MPOAuthURLRequest *)inRequest {
|
2011-02-12 09:17:28 -06:00
|
|
|
if ((self = [super init])) {
|
2011-02-01 09:51:02 -06:00
|
|
|
[self setOauthRequest:inRequest];
|
|
|
|
data = [[NSMutableData alloc] init];
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (oneway void)dealloc {
|
|
|
|
[credentials release];
|
|
|
|
[oauthRequest release];
|
|
|
|
[oauthResponse release];
|
|
|
|
[data release];
|
|
|
|
[responseString release];
|
|
|
|
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setCredentials:(id)theCredentials {
|
|
|
|
[credentials release];
|
|
|
|
credentials = [theCredentials retain];
|
|
|
|
}
|
|
|
|
- (id<MPOAuthCredentialStore,MPOAuthParameterFactory>)credentials {
|
|
|
|
return credentials;
|
|
|
|
}
|
|
|
|
- (void)setOauthRequest:(MPOAuthURLRequest *)theRequest {
|
|
|
|
[oauthRequest release];
|
|
|
|
oauthRequest = [theRequest retain];
|
|
|
|
}
|
|
|
|
- (MPOAuthURLRequest *)oauthRequest {
|
|
|
|
return oauthRequest;
|
|
|
|
}
|
|
|
|
- (void)setOauthResponse:(MPOAuthURLResponse *)theResponse {
|
|
|
|
[oauthResponse release];
|
|
|
|
oauthResponse = [theResponse retain];
|
|
|
|
}
|
|
|
|
- (MPOAuthURLResponse *)oauthResponse {
|
|
|
|
if (oauthResponse==nil)
|
|
|
|
oauthResponse = [[MPOAuthURLResponse alloc] init];
|
|
|
|
return oauthResponse;
|
|
|
|
}
|
|
|
|
- (NSData *)data {
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
- (NSString *)responseString {
|
|
|
|
if (responseString==nil)
|
|
|
|
responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
|
|
return responseString;
|
|
|
|
}
|
|
|
|
- (void)setTarget:(id)theTarget {
|
|
|
|
target = theTarget;
|
|
|
|
}
|
|
|
|
- (id)target {
|
|
|
|
return target;
|
|
|
|
}
|
|
|
|
- (void)setAction:(SEL)theAction {
|
|
|
|
action = theAction;
|
|
|
|
}
|
|
|
|
- (SEL)action {
|
|
|
|
return action;
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
- (void)loadSynchronously:(BOOL)inSynchronous {
|
|
|
|
NSAssert(credentials, @"Unable to load without valid credentials");
|
|
|
|
NSAssert(credentials.consumerKey, @"Unable to load, credentials contain no consumer key");
|
|
|
|
|
|
|
|
if (!inSynchronous) {
|
|
|
|
[MPOAuthConnection connectionWithRequest:oauthRequest delegate:self credentials:credentials];
|
|
|
|
} else {
|
|
|
|
MPOAuthURLResponse *theOAuthResponse = nil;
|
|
|
|
data = [[MPOAuthConnection sendSynchronousRequest:oauthRequest usingCredentials:credentials returningResponse:&theOAuthResponse error:nil] retain];
|
|
|
|
[self setOauthResponse:theOAuthResponse];
|
|
|
|
[self _interrogateResponseForOAuthData];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)theError {
|
|
|
|
MPLog(@"%p: [%@ %@] %@, %@", self, NSStringFromClass([self class]), NSStringFromSelector(_cmd), connection, theError);
|
|
|
|
if ([target respondsToSelector:@selector(loader:didFailWithError:)]) {
|
|
|
|
[target performSelector: @selector(loader:didFailWithError:) withObject: self withObject: theError];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
|
|
|
|
[[self oauthResponse] setResponse:response];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
|
|
|
|
MPLog(@"%@", NSStringFromSelector(_cmd));
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData {
|
|
|
|
[data appendData:theData];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse {
|
|
|
|
MPLog( @"[%@ %@]: %@, %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), request, redirectResponse);
|
|
|
|
return request;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
|
|
|
[self _interrogateResponseForOAuthData];
|
|
|
|
|
|
|
|
if (action) {
|
|
|
|
if ([target conformsToProtocol:@protocol(MPOAuthAPIInternalClient)]) {
|
|
|
|
[target performSelector:action withObject:self withObject:data];
|
|
|
|
} else {
|
|
|
|
[target performSelector:action withObject:[oauthRequest url] withObject:responseString];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
- (void)_interrogateResponseForOAuthData {
|
|
|
|
NSString *response = responseString;
|
|
|
|
NSDictionary *foundParameters = nil;
|
|
|
|
int status = [(NSHTTPURLResponse *)[[self oauthResponse] response] statusCode];
|
|
|
|
|
|
|
|
if ([response length] > 5 && [[response substringToIndex:5] isEqualToString:@"oauth"]) {
|
|
|
|
foundParameters = [MPURLRequestParameter parameterDictionaryFromString:response];
|
|
|
|
oauthResponse.oauthParameters = foundParameters;
|
|
|
|
|
|
|
|
if (status == 401 || ([response length] > 13 && [[response substringToIndex:13] isEqualToString:@"oauth_problem"])) {
|
|
|
|
NSString *aParameterValue = nil;
|
|
|
|
MPLog(@"oauthProblem = %@", foundParameters);
|
|
|
|
|
|
|
|
if ([foundParameters count] && (aParameterValue = [foundParameters objectForKey:@"oauth_problem"])) {
|
|
|
|
if ([aParameterValue isEqualToString:@"token_rejected"]) {
|
|
|
|
if ([credentials requestToken] && ![credentials accessToken]) {
|
|
|
|
[credentials setRequestToken:nil];
|
|
|
|
[credentials setRequestTokenSecret:nil];
|
|
|
|
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPOAuthNotificationRequestTokenRejected
|
|
|
|
object:nil
|
|
|
|
userInfo:foundParameters];
|
|
|
|
} else if ([credentials accessToken] && ![credentials requestToken]) {
|
|
|
|
// your access token may be invalid due to a number of reasons so it's up to the
|
|
|
|
// user to decide whether or not to remove them
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPOAuthNotificationAccessTokenRejected
|
|
|
|
object:nil
|
|
|
|
userInfo:foundParameters];
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// something's messed up, so throw an error
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPOAuthNotificationErrorHasOccurred
|
|
|
|
object:nil
|
|
|
|
userInfo:foundParameters];
|
|
|
|
}
|
|
|
|
} else if ([response length] > 11 && [[response substringToIndex:11] isEqualToString:@"oauth_token"]) {
|
|
|
|
NSString *aParameterValue = nil;
|
|
|
|
MPLog(@"foundParameters = %@", foundParameters);
|
|
|
|
|
|
|
|
if ([foundParameters count] && (aParameterValue = [foundParameters objectForKey:@"oauth_token"])) {
|
|
|
|
if (![credentials requestToken] && ![credentials accessToken]) {
|
|
|
|
[credentials setRequestToken:aParameterValue];
|
|
|
|
[credentials setRequestTokenSecret:[foundParameters objectForKey:@"oauth_token_secret"]];
|
|
|
|
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPOAuthNotificationRequestTokenReceived
|
|
|
|
object:nil
|
|
|
|
userInfo:foundParameters];
|
|
|
|
|
|
|
|
} else if (![credentials accessToken] && [credentials requestToken]) {
|
|
|
|
[credentials setRequestToken:nil];
|
|
|
|
[credentials setRequestTokenSecret:nil];
|
|
|
|
[credentials setAccessToken:aParameterValue];
|
|
|
|
[credentials setAccessTokenSecret:[foundParameters objectForKey:@"oauth_token_secret"]];
|
|
|
|
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPOAuthNotificationAccessTokenReceived
|
|
|
|
object:nil
|
|
|
|
userInfo:foundParameters];
|
|
|
|
|
|
|
|
} else if ([credentials accessToken] && ![credentials requestToken]) {
|
|
|
|
// replace the current token
|
|
|
|
[credentials setAccessToken:aParameterValue];
|
|
|
|
[credentials setAccessTokenSecret:[foundParameters objectForKey:@"oauth_token_secret"]];
|
|
|
|
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:MPOAuthNotificationAccessTokenRefreshed
|
|
|
|
object:nil
|
|
|
|
userInfo:foundParameters];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|