Advertisement
Guest User

Untitled

a guest
Jan 29th, 2016
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. //  FacebookService.m
  3. //  NineSpot
  4. //
  5. //  Created by Nick Dalton on 11/28/14.
  6. //  Copyright (c) 2014 NineSpot. All rights reserved.
  7. //
  8.  
  9. #import <FacebookSDK/FacebookSDK.h>
  10. #import <CommonCrypto/CommonCrypto.h>
  11.  
  12. #import "FacebookService.h"
  13.  
  14. #import "AppDelegate.h"
  15. #import "EndUser.h"
  16.  
  17.  
  18. NSString *const kNotificationLoginFacebookSuccess = @"NotificationLoginFacebookSuccess";
  19.  
  20.  
  21. @implementation FacebookService
  22.  
  23.  
  24. #pragma mark - AppDelegate handlers
  25.  
  26. - (BOOL)handleOpenURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication
  27. {
  28.     return [FBAppCall handleOpenURL:url
  29.                   sourceApplication:sourceApplication
  30.                     fallbackHandler:^(FBAppCall *call) {
  31.                         DDLogDebug(@"In fallback handler");
  32.                     }];
  33. }
  34.  
  35. - (void)handleApplicationDidBecomeActive
  36. {
  37.     // Call the 'activateApp' method to log an app event for use in analytics and advertising reporting.
  38.     [FBAppEvents activateApp];
  39.    
  40.     // We need to properly handle activation of the application with regards to SSO
  41.     //  (e.g., returning from iOS 6.0 authorization dialog or from fast app switching).
  42.     [FBAppCall handleDidBecomeActive];
  43. }
  44.  
  45. - (void)handleApplicationWillTerminate
  46. {
  47.     // If the app is going away, we close the session object.
  48.     [FBSession.activeSession close];
  49. }
  50.  
  51.  
  52. #pragma mark - Facebook session
  53.  
  54. - (BOOL)isSessionOpen
  55. {
  56.     BOOL isOpen = FBSession.activeSession.isOpen;
  57.     DDLogDebug(@"Facebook Session is %@", isOpen ? @"open" : @"not open");
  58.    
  59.     DDLogDebug(@"Facebook access token expires: %@", FBSession.activeSession.accessTokenData.expirationDate);
  60.    
  61.     return isOpen;
  62. }
  63.  
  64. - (void)openSessionFromTokenCache
  65. {
  66.     DDLogDebug(@"Facebook openSessionFromTokenCache");
  67.    
  68.     // Try to open a Facebook session from a token cache
  69.     if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
  70.         // Yes, so just open the session (this won't display any UX).
  71.         [FBSession openActiveSessionWithReadPermissions:@[@"public_profile", @"email"]
  72.                                            allowLoginUI:NO
  73.                                       completionHandler:^(FBSession *session,
  74.                                                           FBSessionState status,
  75.                                                           NSError *error) {
  76.                                           // Respond to session state changes
  77.                                           [self facebookSessionStateChanged:session state:status error:error];
  78.                                       }];
  79.     }
  80. }
  81.  
  82. - (void)login
  83. {
  84.     DDLogDebug(@"Facebook login");
  85.    
  86.     [FBSession openActiveSessionWithReadPermissions:@[@"public_profile", @"email"]
  87.                                        allowLoginUI:YES
  88.                                   completionHandler:^(FBSession *session,
  89.                                                       FBSessionState status,
  90.                                                       NSError *error) {
  91.                                       // Respond to session state changes
  92.                                       [self facebookSessionStateChanged:session state:status error:error];
  93.                                   }];
  94. }
  95.  
  96. - (void)logout
  97. {
  98.     DDLogDebug(@"Facebook logout");
  99.     [FBSession.activeSession closeAndClearTokenInformation];
  100. }
  101.  
  102. - (void)facebookSessionStateChanged:(FBSession *)session
  103.                               state:(FBSessionState) state
  104.                               error:(NSError *)error
  105. {
  106.     DDLogDebug(@"FBSessionState changed to: %lu", (unsigned long)state);
  107.    
  108.     // Capture demographic data
  109.     if ([session isOpen]) {
  110.         [[FBRequest requestForMe] startWithCompletionHandler:
  111.          ^(FBRequestConnection *connection,
  112.            NSDictionary<FBGraphUser> *user,
  113.            NSError *connectionError) {
  114.              if (!connectionError) {
  115.                  DDLogDebug(@"FBGraphUser: %@", user);
  116.                  EndUser *endUser = [self endUserFromFacebookUser:user];
  117.                  [ApplicationDelegate.webService saveEndUser:endUser];
  118.                  [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationLoginFacebookSuccess object:endUser];
  119.              } else {
  120.                  DDLogError(@"Error in FBRequest requestForMe: %@", [connectionError localizedDescription]);
  121.              }
  122.          }];
  123.     }
  124.    
  125. }
  126.  
  127.  
  128. #pragma mark - EndUser helper methods
  129.  
  130. - (EndUser *)endUserFromFacebookUser:(id<FBGraphUser>)user
  131. {
  132.     EndUser *endUser = [[EndUser alloc] init];
  133.    
  134.     endUser.name = user.name;
  135.     endUser.emailAddress = [user objectForKey:@"email"];
  136.     endUser.userId = user.objectID;
  137.    
  138.     NSString *genderString = [user objectForKey:@"gender"];
  139.     if (genderString) {
  140.         NSString *genderCharacter = [[genderString substringToIndex:1] uppercaseString];
  141.         endUser.gender = genderCharacter;
  142.     }
  143.    
  144.     endUser.accessToken = FBSession.activeSession.accessTokenData.accessToken;
  145.     endUser.password = [self generatedPasswordForFacebookUser:user];
  146.     endUser.isFacebookUser = YES;
  147.    
  148.     // Get profile picture
  149.     [[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *FBuser, NSError *error) {
  150.         if (error) {
  151.             DDLogError(@"Error fetching Facebook profile picture: %@", [error localizedDescription]);
  152.         } else {
  153.             NSString *urlString = [NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=normal", [FBuser objectID]];
  154.             if (urlString) {
  155.                 @try {
  156.                     endUser.mediumThumbnailURL = [NSURL URLWithString:urlString];
  157.                     [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationEndUserUpdated object:endUser];
  158.                 }
  159.                 @catch (NSException *exception) {
  160.                     DDLogError(@"Error cretating URL for Facebook thumbnail %@ : %@", urlString, [exception description]);
  161.                 }
  162.             }
  163.         }
  164.     }];
  165.    
  166.     return endUser;
  167. }
  168.  
  169. - (NSString *)generatedPasswordForFacebookUser:(id<FBGraphUser>)user
  170. {
  171.     NSString *password = nil;
  172.    
  173.     NSString *userId = user.objectID;
  174.     if (userId) {
  175.         NSString *hash = [self computeSHA256DigestForString:userId withSalt:@"42"];
  176.         NSString *trimmedHash = [hash substringToIndex:16];
  177.         password = [NSString stringWithFormat:@"fb%@.", trimmedHash];
  178.     }
  179.    
  180.     return password;
  181. }
  182.  
  183. - (NSString *)computeSHA256DigestForString:(NSString *)input
  184. {
  185.     const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding];
  186.     NSData *data = [NSData dataWithBytes:cstr length:input.length];
  187.     uint8_t digest[CC_SHA256_DIGEST_LENGTH];
  188.    
  189.     CC_SHA256(data.bytes, (unsigned int)data.length, digest);
  190.    
  191.     NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
  192.     for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
  193.         [output appendFormat:@"%02x", digest[i]];
  194.     }
  195.     return output;
  196. }
  197.  
  198. - (NSString *)computeSHA256DigestForString:(NSString *)input withSalt:(NSString *)salt
  199. {
  200.     const char *cData = [input cStringUsingEncoding:NSUTF8StringEncoding];
  201.     const char *cKey = [salt cStringUsingEncoding:NSUTF8StringEncoding];
  202.     uint8_t cHMAC[CC_SHA256_DIGEST_LENGTH];
  203.    
  204.     CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
  205.    
  206.     NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
  207.     for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
  208.         [output appendFormat:@"%02x", cHMAC[i]];
  209.     }
  210.     return output;
  211. }
  212.  
  213. @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement