Advertisement
Guest User

Untitled

a guest
May 23rd, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.79 KB | None | 0 0
  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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement