SHARE
TWEET

Untitled

a guest May 23rd, 2018 82 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. //  FROAuthRequest.m
  3. //  kroonjuwelen
  4. //
  5. //  Created by Jonathan Dalrymple on 12/04/2010.
  6. //  Copyright 2010 Float:Right. All rights reserved.
  7. //
  8.  
  9. #import "FROAuthRequest.h"
  10.  
  11. @interface FROAuthRequest(private)
  12.  
  13. - (void) prepare;
  14. - (NSString *)signatureBaseString;
  15. - (NSString*) signatureBaseStringForURL:(NSURL*) pURL
  16.                             withMethod:(NSString*) method
  17.                             withParams:(NSDictionary*) dictionary;
  18. - (NSString *)timestamp;
  19. - (NSString *)nonce;
  20.  
  21. @end
  22.  
  23. @interface ASIFormDataRequest(private)
  24.  
  25. -(id) postData;
  26.  
  27. @end
  28.  
  29. @implementation FROAuthRequest
  30.  
  31. @synthesize token = _token;
  32. @synthesize consumer = _consumer;
  33. @synthesize signatureProvider = _signatureProvider;
  34.  
  35. #pragma mark -
  36. #pragma mark Factory Methods
  37. +(id) requestWithURL: (NSURL *)newURL  
  38.             consumer: (OAConsumer*) consumer
  39.                token: (OAToken*) token
  40.                realm: (NSString*) realm
  41.    signatureProvider: (id<OASignatureProviding>) provider
  42. {  
  43.     return [[[FROAuthRequest alloc] initWithURL: newURL
  44.                                        consumer: consumer
  45.                                           token: token
  46.                                           realm: realm
  47.                               signatureProvider: provider
  48.              ] autorelease];
  49. }
  50.  
  51.  
  52. #pragma mark -
  53. #pragma mark Init Methods
  54. -(id) initWithURL: (NSURL *)newURL  
  55.             consumer: (OAConsumer*) consumer
  56.                token: (OAToken*) token
  57.                realm: (NSString*) realm
  58.    signatureProvider: (id<OASignatureProviding>) provider
  59. {
  60.  
  61.     if( self = [super initWithURL: newURL] ){
  62.        
  63.         //Alter this after the request has been created;
  64.         //[self setRequestMethod:@"POST"];
  65.        
  66.         [self setConsumer: consumer];
  67.  
  68.                
  69.         if( token == nil ){
  70.             self.token = [[OAToken alloc] init];
  71.         }
  72.         else{
  73.             self.token = token;
  74.         }
  75.        
  76.         _realm = realm ? [realm retain] : @"";
  77.        
  78.         if( provider == nil ){
  79.            
  80.             self.signatureProvider = [[OAHMAC_SHA1SignatureProvider alloc] init];
  81.         }
  82.         else{
  83.             self.signatureProvider = provider;
  84.         }
  85.        
  86.         _nonce = nil;
  87.        
  88.         _timestamp = nil;
  89.    
  90.     }
  91.    
  92.     return self;
  93.    
  94. }
  95.  
  96.  
  97. #pragma mark -
  98. #pragma mark Start Methods
  99. //Overload start ASync
  100. -(void) startAsynchronous{
  101.  
  102.     [self prepare];
  103.  
  104.     [super startAsynchronous];
  105.    
  106. }
  107.  
  108. -(void) startSynchronous{
  109.    
  110.     [self prepare];
  111.    
  112.     [super startSynchronous];
  113. }
  114.  
  115.  
  116. #pragma mark -
  117. #pragma mark Overloaded ASIFormDataRequest
  118. - (void)buildPostBody
  119. {
  120.     //If we want to do anything other than GET, build a body
  121.     if(![[self requestMethod] isEqualToString:@"GET"]){
  122.         [super buildPostBody];
  123.     }
  124.    
  125. }
  126.  
  127. /*
  128.  
  129.  
  130. - (void)requestFinished{
  131.    
  132.     NSLog(@"[FROAuthRequest] Request Finished");
  133.  
  134.    
  135.     [super requestFinished];
  136. }
  137. */
  138. - (void)requestFailed:(FROAuthRequest *) pRequest{
  139. #if DEBUG
  140.     NSLog(@"[FROAuthRequest requestFailed] %@", [pRequest error]);
  141. #endif
  142.     //[super requestFinished];
  143. }
  144.  
  145.  
  146. //-**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-
  147. //      OAuth Methods
  148. //-**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-
  149. #pragma mark -
  150. #pragma mark Request Token
  151. +(OAToken*) _requestTokenFromProvider:(NSURL*) requestURL
  152.                      withConsumer:(OAConsumer*) pConsumer
  153.                         forObject:(id) pDelegate
  154. {
  155.    
  156. #if DEBUG
  157.     NSLog(@"[FROAuthRequest requestToken]");
  158. #endif
  159.     FROAuthRequest* tokenRequest;
  160.    
  161.     tokenRequest = [FROAuthRequest requestWithURL: requestURL
  162.                                          consumer: pConsumer
  163.                                             token: nil
  164.                                             realm: nil
  165.                                 signatureProvider: nil
  166.                     ];
  167.    
  168.     [tokenRequest startSynchronous];
  169.    
  170.     return [FROAuthRequest _didRequestToken: tokenRequest forObject:pDelegate];
  171. }
  172.  
  173. /*
  174.  Request token callback
  175.  */
  176. +(OAToken*) _didRequestToken:(FROAuthRequest*) pRequest
  177.                forObject:pDelegate
  178. {
  179.  
  180.     OAToken *tempToken;
  181.    
  182.     //Parse out the token
  183.     if( [pRequest responseString] && [pRequest responseStatusCode] == 200 ){
  184.        
  185.         tempToken = [[[OAToken alloc] initWithHTTPResponseBody: [pRequest responseString]] autorelease];
  186. #if DEBUG
  187.         NSLog(@"[FROAuthRequest didRequestToken] Found a response \r\n%@", [pRequest responseString]);
  188.  
  189.         NSLog(@"[FROAuthRequest didRequestToken] New Request Token Created key:%@ secret:%@",tempToken.key,tempToken.secret);
  190. #endif
  191.         //Authenticate the token
  192.         if( [tempToken key] != nil){
  193.  
  194.             if( pDelegate && [pDelegate respondsToSelector:@selector(authenticateToken:withProvider:)]){
  195.                
  196.                 [pDelegate performSelector:@selector( authenticateToken:withProvider:) withObject: tempToken withObject: [pRequest url]];
  197.                 //[pDelegate authenticateToken: tempToken withProvider:[pRequest url]];
  198.  
  199.             }
  200.            
  201.             return tempToken;          
  202.         }
  203.     }
  204.     else{
  205.        
  206.         UIAlertView *alertView;
  207.        
  208.         alertView = [[UIAlertView alloc] initWithTitle: NSLocalizedString(@"Could not connect",@"Could not connect")
  209.                                                message: NSLocalizedString(@"Could not to connect to the internet",@"Could not to connect to the internet")
  210.                                               delegate: nil
  211.                                      cancelButtonTitle: NSLocalizedString(@"ok",@"Ok")
  212.                                      otherButtonTitles: nil
  213.                      ];
  214.        
  215.         [alertView show];
  216.        
  217.         [alertView release];
  218. #if DEBUG      
  219.         NSLog(@"[FROAuthRequest didRequestToken] failed");
  220. #endif
  221.     }
  222.  
  223.     //Notify the parent that we failed
  224.     //[[self delegate] performSelectorOnMainThread:[self didFailSelector] withObject:self waitUntilDone:[NSThread isMainThread]];      
  225.    
  226.     return nil;
  227. }
  228.  
  229.  
  230. #pragma mark -
  231. #pragma mark Authorize Token
  232. +(OAToken*) _accessTokenWithRequestToken:(OAToken*) pToken
  233.                         fromProvider:(NSURL*) accessURL
  234.                          forConsumer:(OAConsumer*) pConsumer
  235.                            forObject:(id) pDelegate
  236. {
  237.  
  238. #if DEBUG
  239.     NSLog(@"[FROAuthRequest authorizeToken]");
  240. #endif
  241.     FROAuthRequest* authorizeRequest;
  242.    
  243.     //Append the pin to the token
  244.     //NSString *URLStr = [accessURL absoluteString];
  245.    
  246.     //URLStr = [URLStr stringByAppendingString:[NSString stringWithFormat:@"?oauth_verifier=%s", pToken.pin]];
  247.    
  248.     authorizeRequest = [FROAuthRequest requestWithURL: accessURL //[NSURL URLWithString:URLStr]
  249.                                              consumer: pConsumer
  250.                                                 token: pToken
  251.                                                 realm: nil
  252.                                     signatureProvider: nil
  253.                         ];
  254.  
  255.     //We are already operating on a seperate thread so using this should be fine
  256.     [authorizeRequest startSynchronous];
  257.    
  258.     //This log can be split into callbacks
  259.     if( [authorizeRequest responseStatusCode] == 200 && [authorizeRequest responseString] ){
  260. #if DEBUG
  261.         NSLog(@"[FROAuthRequest] Created new Access Token! \r\n%@", [authorizeRequest responseString]);
  262. #endif
  263.         //Set the access token
  264.         return [[[OAToken alloc] initWithHTTPResponseBody:[authorizeRequest responseString]] autorelease];
  265.  
  266.     }
  267.     else{
  268. #if DEBUG
  269.         NSLog(@"[FROAuthRequest] Failed to get Access Token!");
  270. #endif 
  271.         return nil;
  272.     }
  273. }
  274.  
  275. //Use xAuth to authorize a token
  276. +(OAToken*) _accessTokenFromProvider:(NSURL*) accessURL
  277.                         WithUsername:(NSString*) pUsername
  278.                             password:(NSString*) pPassword
  279.                          andConsumer:(OAConsumer*) pConsumer
  280. {
  281.    
  282.     FROAuthRequest *accessRequest;
  283.    
  284.     //Insure that it SSL
  285.     if( ![[accessURL scheme] isEqualToString:@"https"] ){
  286. #if DEBUG
  287.         NSLog(@"Not SSL :%@",[accessURL scheme]);
  288. #endif     
  289.         //return nil;
  290.     }
  291.    
  292.     accessRequest = [FROAuthRequest requestWithURL: accessURL
  293.                                           consumer: pConsumer
  294.                                              token: nil  
  295.                                              realm: nil
  296.                                  signatureProvider: nil
  297.                      ];
  298.    
  299.     [accessRequest setRequestMethod:@"POST"];
  300.    
  301.     [accessRequest setPostValue:pUsername forKey:@"x_auth_username"];
  302.    
  303.     [accessRequest setPostValue:pPassword forKey:@"x_auth_password"];
  304.    
  305.     [accessRequest setPostValue:@"client_auth" forKey:@"x_auth_mode"];
  306.    
  307.     [accessRequest startSynchronous];
  308.    
  309.     if( [accessRequest responseStatusCode] == 200 && [accessRequest responseString] ){
  310. #if DEBUG
  311.         NSLog(@"[FROAuthRequest xAuthToken] Success \r\n%@", [accessRequest responseString]);
  312. #endif     
  313.         return [[[OAToken alloc] initWithHTTPResponseBody:[accessRequest responseString]] autorelease];
  314.     }
  315.     else{
  316.        
  317.         UIAlertView *alertView;
  318.        
  319.         alertView = [[UIAlertView alloc] initWithTitle: @""
  320.                                                message: @"Couldn't find "
  321.                                               delegate: nil
  322.                                      cancelButtonTitle: nil
  323.                                      otherButtonTitles: nil
  324.                      ];
  325.        
  326.         [alertView show];
  327.        
  328.         [alertView release];
  329. #if DEBUG
  330.         NSLog(@"[FROAuthRequest xAuthToken] Failure \r\n%@", [accessRequest error]);
  331. #endif     
  332.         return nil;
  333.     }
  334. }
  335.  
  336. //-**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-
  337. //          Utilites
  338. //-**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-
  339.  
  340. /*
  341.  URL encode a string
  342.  */
  343. - (NSString *) URLEncodedString: (NSString *) string {
  344.     CFStringRef preprocessedString = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, (CFStringRef) string, CFSTR(""), kCFStringEncodingUTF8);
  345.     NSString *result = (NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
  346.                                                                            preprocessedString,
  347.                                                                            NULL,
  348.                                                                            CFSTR("!*'();:@&=+$,/?%#[]"),
  349.                                                                            kCFStringEncodingUTF8);
  350.     [result autorelease];
  351.    
  352.     //NSLog(@"RETAIN COUNT %d",CFGetRetainCount( preprocessedString));
  353.    
  354.     if( preprocessedString != NULL ){
  355.         CFRelease(preprocessedString);     
  356.     }
  357.  
  358.     //Handle Spaces
  359.     result = [result stringByReplacingOccurrencesOfString:@"%20" withString:@"%2520"];
  360.    
  361.     //Handle Hashes
  362.     result = [result stringByReplacingOccurrencesOfString:@"%23" withString:@"%2523"];
  363.    
  364.     //Handle Colons
  365.     //result = [result stringByReplacingOccurrencesOfString:@"%3A" withString:@"%253A"];
  366.  
  367. #if DEBUG
  368.     NSLog(@"String encoded \r\nin:%@ \r\nout:%@", string, result);
  369. #endif
  370.     return result; 
  371. }
  372.  
  373. //Create a url string
  374. - (NSString *)URLStringWithoutQueryFromURL: (NSURL *) pURL
  375. {
  376.     NSArray *parts = [[pURL absoluteString] componentsSeparatedByString:@"?"];
  377.     return [parts objectAtIndex:0];
  378. }
  379.  
  380. /*
  381.  Generate a timestamp on demand
  382.  */
  383. - (NSString*)timestamp
  384. {
  385.     if(!_timestamp) {
  386.         _timestamp = [NSString stringWithFormat:@"%d", time(NULL)];
  387.     }
  388.    
  389.     return _timestamp;
  390. }
  391.  
  392. //Generate Nonce on demand
  393. - (NSString*)nonce
  394. {
  395.    
  396.     if( !_nonce ){
  397.         CFUUIDRef theUUID = CFUUIDCreate(NULL);
  398.         CFStringRef string = CFUUIDCreateString(NULL, theUUID);
  399.         CFRelease(theUUID);
  400.        
  401.         _nonce = (NSString *)string;
  402.     }
  403.  
  404.     return _nonce;
  405. }
  406.  
  407. //Create BaseString
  408. - (NSString *)signatureBaseString
  409. {
  410.    
  411.     NSMutableDictionary *params;
  412.     NSString        *queryStr;
  413.     //NSArray           *queryParams;
  414.    
  415.     params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
  416.                             [[self consumer] key],
  417.                             @"oauth_consumer_key",
  418.                             [[self token] key] ? [[self token] key] : @"",  //Stops nil from being entered and causing a failure
  419.                             @"oauth_token",
  420.                             [[self signatureProvider] name],
  421.                             @"oauth_signature_method",
  422.                             [self timestamp],
  423.                             @"oauth_timestamp",
  424.                             [self nonce],
  425.                             @"oauth_nonce",
  426.                             @"1.0",
  427.                             @"oauth_version",
  428.                             nil
  429.                             ];
  430.    
  431.     //Find out if the params to the query
  432.     if( queryStr = [[self url] query] ){
  433.         //Break the query up into pairs and add them to the dictionary
  434.         for( NSString *keyValPairStr in [queryStr componentsSeparatedByString:@"&"]){
  435.            
  436.             //NSLog(@"KeyVal Pair %@", keyValPairStr );
  437.            
  438.             NSArray *keyValPair = [keyValPairStr componentsSeparatedByString:@"="];
  439.            
  440.             [params setObject: [keyValPair objectAtIndex:1] forKey: [keyValPair objectAtIndex:0]];
  441.         }
  442.        
  443.     }
  444.    
  445.     //If this is post request find out
  446.     if( [self isKindOfClass:[ASIFormDataRequest class]] && [self respondsToSelector:@selector(postData)]){
  447.        
  448.         for( NSString *key in [self postData] ){
  449.            
  450.             [params setValue:[[self postData] objectForKey:key] forKey:key];
  451.         }
  452.        
  453.     }
  454.    
  455.    
  456.     return [self signatureBaseStringForURL: [self url]
  457.                                 withMethod: [self requestMethod]
  458.                                 withParams: (NSDictionary*)params
  459.             ];
  460. }
  461.  
  462. //Create a signature base string
  463. -(NSString*) signatureBaseStringForURL:(NSURL*) pURL
  464.                             withMethod:(NSString*) method
  465.                             withParams:(NSDictionary*) dictionary{
  466.    
  467.     NSMutableArray *pairs;
  468.     NSArray *sortedPairs;
  469.     NSString *key, *tmp;
  470.     NSString *baseString, *normalizedString;
  471.    
  472.     if( [dictionary count] < 6 ){
  473.         @throw [NSException exceptionWithName:@"InvalidParameterCount"
  474.                                        reason:[NSString stringWithFormat:@"Passed Dictionary contains too few entries (6 Min vs %d found)", [dictionary count]]
  475.                                      userInfo:[NSDictionary dictionaryWithObjectsAndKeys: dictionary,@"dictionary",self,@"request",nil]];
  476.     }
  477.    
  478.     pairs = [[NSMutableArray alloc] init];
  479.    
  480.     for( key in dictionary ){
  481.        
  482.         if( [[dictionary objectForKey:key] length] > 0){
  483.             tmp = [NSString stringWithFormat:@"%@=%@", key, [dictionary objectForKey:key] ];
  484.            
  485.             tmp = [self URLEncodedString: tmp];
  486.            
  487.             [pairs addObject:tmp];         
  488.         }
  489.         else{
  490.             #if DEBUG
  491.             NSLog(@"[FRORequest signatureBaseString] %@ was nil, skipping", key);
  492.             #endif
  493.         }
  494.  
  495.     }
  496.    
  497.     sortedPairs = [pairs sortedArrayUsingSelector:@selector(compare:)];
  498.    
  499.     normalizedString = [sortedPairs componentsJoinedByString:@"&"];
  500.    
  501.     baseString = [NSString stringWithFormat:@"%@&%@&%@",
  502.                      [method uppercaseString],
  503.                      [self URLEncodedString:[self URLStringWithoutQueryFromURL:pURL]],
  504.                      [self URLEncodedString: normalizedString]
  505.                   ];
  506.    
  507.     //Cleanup
  508.     [pairs release];
  509. #if DEBUG
  510.     NSLog(@"Basestring \r\n%@", baseString);
  511. #endif 
  512.     return baseString;
  513. }
  514.  
  515. //Add Auth header to this request
  516. - (void)prepare
  517. {
  518.     // sign
  519.     // Secrets must be urlencoded before concatenated with '&'
  520.     // TODO: if later RSA-SHA1 support is added then a little code redesign is needed
  521.     NSString    *consumerSecret, *tokenSecret, *signature, *oauthToken, *oauthHeader;
  522.  
  523.     consumerSecret = [self URLEncodedString: self.consumer.secret];
  524.    
  525.     tokenSecret = [self URLEncodedString: self.token.secret];
  526.  
  527.     signature = [self.signatureProvider signClearText:[self signatureBaseString]
  528.                                       withSecret:[NSString stringWithFormat:@"%@&%@", consumerSecret, tokenSecret]];
  529.    
  530.     // set OAuth headers
  531.  
  532.     if ([self.token.key isEqualToString:@""]){
  533.         oauthToken = @""; // not used on Request Token transactions
  534.     }
  535.     else{
  536.         oauthToken = [NSString stringWithFormat:@"oauth_token=\"%@\", ", [self URLEncodedString: self.token.key]];
  537.     }
  538.    
  539.     oauthHeader = [NSString stringWithFormat:
  540.                              @"OAuth realm=\"%@\", oauth_consumer_key=\"%@\", %@oauth_signature_method=\"%@\", oauth_signature=\"%@\", oauth_timestamp=\"%@\", oauth_nonce=\"%@\", oauth_version=\"1.0\"",
  541.                              [self URLEncodedString: _realm],
  542.                              [self URLEncodedString: [self.consumer key]],
  543.                              oauthToken,
  544.                              [self URLEncodedString: [self.signatureProvider name]],
  545.                              [self URLEncodedString: signature],
  546.                              [self timestamp],
  547.                              [self nonce]
  548.                              ];
  549.    
  550.     if (self.token.pin.length) oauthHeader = [oauthHeader stringByAppendingFormat: @", oauth_verifier=\"%@\"", self.token.pin];                 //added for the Twitter OAuth implementation
  551. #if DEBUG
  552.     NSLog(@"[FROAuthRequest prepare] \r\nAuthentication Header %@", oauthHeader);
  553. #endif 
  554.     [self addRequestHeader:@"Authorization" value: oauthHeader];
  555.  
  556. }
  557.  
  558. #pragma mark -
  559. #pragma mark Dealloc
  560. -(void) dealloc{
  561. /* 
  562.     [self.requestToken release];
  563. */
  564.     [_realm release];
  565.    
  566.     [_nonce release];
  567.    
  568.     // Cause a crash if if a nil check is done
  569.     //[_timestamp release];
  570.  
  571.     [_consumer release];
  572.    
  573.     [self.signatureProvider release];
  574.    
  575.     [self.token release];
  576.    
  577.     [super dealloc];
  578. }
  579.  
  580. @end
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top