├── Example ├── SimpleAuth │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── Artboard 1.png │ │ │ ├── Artboard 2.png │ │ │ ├── Artboard 3.png │ │ │ ├── Artboard 4.png │ │ │ └── Contents.json │ ├── SADProviderListViewController.h │ ├── SADAppDelegate.h │ ├── Prefix.pch │ ├── main.m │ ├── Providers.plist │ ├── Info.plist │ ├── LaunchScreen.xib │ ├── SADProviderListViewController.m │ └── SADAppDelegate.m ├── Podfile ├── SimpleAuth.xcworkspace │ └── contents.xcworkspacedata ├── Podfile.lock └── SimpleAuth.xcodeproj │ └── xcshareddata │ └── xcschemes │ └── SimpleAuth.xcscheme ├── Pod ├── Resources │ └── en.lproj │ │ └── Localizable.strings ├── Core │ ├── SimpleAuthUtilities.h │ ├── SimpleAuth-Prefix.pch │ ├── ios │ │ ├── UIWindow+SimpleAuthAdditions.h │ │ ├── UIViewController+SimpleAuthAdditions.h │ │ ├── UIWindow+SimpleAuthAdditions.m │ │ ├── UIViewController+SimpleAuthAdditions.m │ │ ├── SimpleAuthWebViewController.h │ │ └── SimpleAuthWebViewController.m │ ├── SimpleAuthSingleSignOnProvider.h │ ├── NSObject+SimpleAuthAdditions.h │ ├── SimpleAuthDefines.m │ ├── SimpleAuthUtilities.m │ ├── SimpleAuthProvider.h │ ├── ACAccountStore+SimpleAuth.h │ ├── NSObject+SimpleAuthAdditions.m │ ├── SimpleAuthProvider.m │ ├── ACAccountStore+SimpleAuth.m │ ├── SimpleAuthDefines.h │ ├── SimpleAuth.h │ └── SimpleAuth.m └── Providers │ ├── VKontakteWeb │ ├── SimpleAuthVKontakteWebProvider.h │ ├── SimpleAuthVKontakteWebLoginViewController.h │ ├── SimpleAuthVKontakteWebLoginViewController.m │ └── SimpleAuthVKontakteWebProvider.m │ ├── BoxWeb │ ├── SimpleAuthBoxWebProvider.h │ ├── SimpleAuthBoxWebLoginViewController.h │ ├── SimpleAuthBoxWebLoginViewController.m │ └── SimpleAuthBoxWebProvider.m │ ├── TripIt │ ├── SimpleAuthTripItProvider.h │ ├── SimpleAuthTripItLoginViewController.h │ └── SimpleAuthTripItLoginViewController.m │ ├── GoogleWeb │ ├── SimpleAuthGoogleWebProvider.h │ ├── SimpleAuthGoogleWebLoginViewController.h │ ├── SimpleAuthGoogleWebLoginViewController.m │ └── SimpleAuthGoogleWebProvider.m │ ├── Meetup │ ├── SimpleAuthMeetupProvider.h │ ├── SimpleAuthMeetupLoginViewController.h │ ├── SimpleAuthMeetupLoginViewController.m │ └── SimpleAuthMeetupProvider.m │ ├── Strava │ ├── SimpleAuthStravaWebProvider.h │ ├── SimpleAuthStravaWebLoginViewController.h │ ├── SimpleAuthStravaWebLoginViewController.m │ └── SimpleAuthStravaWebProvider.m │ ├── Tumblr │ ├── SimpleAuthTumblrProvider.h │ ├── SimpleAuthTumblrLoginViewController.h │ ├── SimpleAuthTumblrLoginViewController.m │ └── SimpleAuthTumblrProvider.m │ ├── Trello │ ├── SimpleAuthTrelloProvider.h │ ├── SimpleAuthTrelloLoginViewController.h │ ├── SimpleAuthTrelloLoginViewController.m │ └── SimpleAuthTrelloProvider.m │ ├── Facebook │ ├── SimpleAuthFacebookProvider.h │ └── SimpleAuthFacebookProvider.m │ ├── OneDriveWeb │ ├── SimpleAuthOneDriveWebProvider.h │ ├── SimpleAuthOneDriveWebLoginViewController.h │ ├── SimpleAuthOneDriveWebLoginViewController.m │ └── SimpleAuthOneDriveWebProvider.m │ ├── Twitter │ └── SimpleAuthTwitterProvider.h │ ├── DropboxWeb │ ├── SimpleAuthDropboxWebProvider.h │ ├── SimpleAuthDropboxWebLoginViewController.h │ ├── SimpleAuthDropboxWebLoginViewController.m │ └── SimpleAuthDropboxWebProvider.m │ ├── Instagram │ ├── SimpleAuthInstagramProvider.h │ ├── SimpleAuthInstagramLoginViewController.h │ ├── SimpleAuthInstagramLoginViewController.m │ └── SimpleAuthInstagramProvider.m │ ├── LinkedIn │ ├── SimpleAuthLinkedInWebProvider.h │ ├── SimpleAuthLinkedInWebLoginViewController.h │ ├── SimpleAuthLinkedInWebLoginViewController.m │ └── SimpleAuthLinkedInWebProvider.m │ ├── TwitterWeb │ ├── SimpleAuthTwitterWebProvider.h │ ├── SimpleAuthTwitterWebLoginViewController.h │ └── SimpleAuthTwitterWebLoginViewController.m │ ├── FacebookWeb │ ├── SimpleAuthFaceBookWebProvider.h │ ├── SimpleAuthFacebookWebLoginViewController.h │ └── SimpleAuthFacebookWebLoginViewController.m │ ├── SinaWeiboWeb │ ├── SimpleAuthSinaWeiboWebProvider.h │ ├── SimpleAuthSinaWeiboWebLoginViewController.h │ ├── SimpleAuthSinaWeiboWebLoginViewController.m │ └── SimpleAuthSinaWeiboWebProvider.m │ └── FoursquareWeb │ ├── SimpleAuthFoursquareWebProvider.h │ ├── SimpleAuthFoursquareWebLoginViewController.h │ ├── SimpleAuthFoursquareWebLoginViewController.m │ └── SimpleAuthFoursquareWebProvider.m ├── .gitignore ├── LICENSE ├── Readme.markdown └── SimpleAuth.podspec /Example/SimpleAuth/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | platform :ios, '6.0' 3 | pod 'SimpleAuth', :path => '..' 4 | -------------------------------------------------------------------------------- /Example/SimpleAuth/Images.xcassets/AppIcon.appiconset/Artboard 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpkupriyanov/SimpleAuth/HEAD/Example/SimpleAuth/Images.xcassets/AppIcon.appiconset/Artboard 1.png -------------------------------------------------------------------------------- /Example/SimpleAuth/Images.xcassets/AppIcon.appiconset/Artboard 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpkupriyanov/SimpleAuth/HEAD/Example/SimpleAuth/Images.xcassets/AppIcon.appiconset/Artboard 2.png -------------------------------------------------------------------------------- /Example/SimpleAuth/Images.xcassets/AppIcon.appiconset/Artboard 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpkupriyanov/SimpleAuth/HEAD/Example/SimpleAuth/Images.xcassets/AppIcon.appiconset/Artboard 3.png -------------------------------------------------------------------------------- /Example/SimpleAuth/Images.xcassets/AppIcon.appiconset/Artboard 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpkupriyanov/SimpleAuth/HEAD/Example/SimpleAuth/Images.xcassets/AppIcon.appiconset/Artboard 4.png -------------------------------------------------------------------------------- /Pod/Resources/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleAuth.strings 3 | SimpleAuth 4 | 5 | Created by Caleb Davenport on 10/7/14. 6 | Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | */ 8 | 9 | // General strings 10 | "CANCEL" = "Cancel"; 11 | -------------------------------------------------------------------------------- /Pod/Core/SimpleAuthUtilities.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthUtilities.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 10/7/14. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | NSString *SimpleAuthLocalizedString(NSString *key); 12 | -------------------------------------------------------------------------------- /Pod/Providers/VKontakteWeb/SimpleAuthVKontakteWebProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthVKontakteWebProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Mikhail Kupriyanov on 7/7/15. 6 | // 7 | 8 | #import "SimpleAuthProvider.h" 9 | 10 | @interface SimpleAuthVKontakteWebProvider : SimpleAuthProvider 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Example/SimpleAuth.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Pod/Core/SimpleAuth-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuth-Prefix.pch 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/6/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #ifdef __OBJC__ 10 | #import 11 | #import 12 | #endif 13 | -------------------------------------------------------------------------------- /Example/SimpleAuth/SADProviderListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SADProviderListViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/16/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | @interface SADProviderListViewController : UITableViewController 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /Pod/Providers/BoxWeb/SimpleAuthBoxWebProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthBoxWebProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by dkhamsing on 3/26/15. 6 | // Copyright (c) 2015 dkhamsing. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthBoxWebProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/TripIt/SimpleAuthTripItProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTripItProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Mark Krenek on 8/15/14. 6 | // Copyright (c) 2014 Mark Krenek. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthTripItProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Core/ios/UIWindow+SimpleAuthAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIWindow+SimpleAuthAdditions.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/14/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | @interface UIWindow (SimpleAuthAdditions) 10 | 11 | + (instancetype)SimpleAuth_mainWindow; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/GoogleWeb/SimpleAuthGoogleWebProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthGoogleWebProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Ramon Vicente on 2/24/15. 6 | // Copyright (c) 2015 UMOBI. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthGoogleWebProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/Meetup/SimpleAuthMeetupProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthMeetupProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Mouhcine El Amine on 17/01/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthMeetupProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/Strava/SimpleAuthStravaWebProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthStravaWebProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Ben Stahl on 7/27/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthStravaWebProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/Tumblr/SimpleAuthTumblrProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTumblrProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/16/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthTumblrProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | *.xccheckout 19 | *.xcworkspace 20 | 21 | #CocoaPods 22 | Pods 23 | -------------------------------------------------------------------------------- /Example/SimpleAuth/SADAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SADAppDelegate.h 3 | // SimpleAuthDemo 4 | // 5 | // Created by Caleb Davenport on 1/16/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | @interface SADAppDelegate : UIResponder 10 | 11 | @property (strong, nonatomic) UIWindow *window; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Core/SimpleAuthSingleSignOnProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthSingleSignOnProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Julien Seren-Rosso on 14/02/2014. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | @protocol SimpleAuthSingleSignOnProvider 10 | 11 | - (BOOL)handleCallback:(NSURL *)URL; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/Trello/SimpleAuthTrelloProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTrelloProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Damiano Buscemi on 22/08/14. 6 | // Copyright (c) 2014 Crispy Bacon, S.r.l. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthTrelloProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/Facebook/SimpleAuthFacebookProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthFacebookProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/6/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthFacebookProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/OneDriveWeb/SimpleAuthOneDriveWebProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthOneDriveWebProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by dkhamsing on 3/31/15. 6 | // Copyright (c) 2015 dkhamsing. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthOneDriveWebProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/Twitter/SimpleAuthTwitterProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTwitterProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/6/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthTwitterProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/DropboxWeb/SimpleAuthDropboxWebProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthDropboxWebProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/23/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthDropboxWebProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/Instagram/SimpleAuthInstagramProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthInstagramProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/7/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthInstagramProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/LinkedIn/SimpleAuthLinkedInWebProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthLinkedInProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Abhishek Sheth on 24/01/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthLinkedInWebProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/TwitterWeb/SimpleAuthTwitterWebProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTwitterWebProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/15/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthTwitterWebProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/VKontakteWeb/SimpleAuthVKontakteWebLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthVKontakteWebLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Mikhail Kupriyanov on 7/7/15. 6 | // 7 | 8 | #import "SimpleAuthWebViewController.h" 9 | 10 | @interface SimpleAuthVKontakteWebLoginViewController : SimpleAuthWebViewController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Pod/Providers/FacebookWeb/SimpleAuthFaceBookWebProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthFaceBookWebProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/22/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthFaceBookWebProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/SinaWeiboWeb/SimpleAuthSinaWeiboWebProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthSinaWeiboWebProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Alexander Schuch on 17/02/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthSinaWeiboWebProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Core/ios/UIViewController+SimpleAuthAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+SimpleAuthAdditions.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/14/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | @interface UIViewController (SimpleAuthAdditions) 10 | 11 | + (instancetype)SimpleAuth_presentedViewController; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/FoursquareWeb/SimpleAuthFoursquareWebProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthFoursquareWebProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Julien Seren-Rosso on 23/01/2014. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthFoursquareWebProvider : SimpleAuthProvider 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/BoxWeb/SimpleAuthBoxWebLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthBoxWebLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by dkhamsing on 3/26/15. 6 | // Copyright (c) 2015 dkhamsing. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthBoxWebLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/TripIt/SimpleAuthTripItLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTripItLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Mark Krenek on 8/15/14. 6 | // Copyright (c) 2014 Mark Krenek. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthTripItLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/Tumblr/SimpleAuthTumblrLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTumblrLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/16/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthTumblrLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/GoogleWeb/SimpleAuthGoogleWebLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthGoogleWebLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Ramon Vicente on 2/24/15. 6 | // Copyright (c) 2015 UMOBI. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthGoogleWebLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/Meetup/SimpleAuthMeetupLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthMeetupLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Mouhcine El Amine on 17/01/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthMeetupLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/Strava/SimpleAuthStravaWebLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthStravaWebLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Ben Stahl on 7/27/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthStravaWebLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/OneDriveWeb/SimpleAuthOneDriveWebLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthOneDriveWebLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by dkhamsing on 3/31/15. 6 | // Copyright (c) 2015 dkhamsing. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthOneDriveWebLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/Trello/SimpleAuthTrelloLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTrelloLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Damiano Buscemi on 22/08/14. 6 | // Copyright (c) 2014 Crispy Bacon, S.r.l. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthTrelloLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/DropboxWeb/SimpleAuthDropboxWebLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthDropboxWebLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/23/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthDropboxWebLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/Instagram/SimpleAuthInstagramLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthInstagramLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/7/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthInstagramLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/LinkedIn/SimpleAuthLinkedInWebLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthLinkedInWebLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Abhishek Sheth on 24/01/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthLinkedInWebLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/TwitterWeb/SimpleAuthTwitterWebLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTwitterWebLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/15/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthTwitterWebLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/FacebookWeb/SimpleAuthFacebookWebLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthFacebookWebLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/22/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthFacebookWebLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/SinaWeiboWeb/SimpleAuthSinaWeiboWebLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthSinaWeiboWebLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Alexander Schuch on 17/02/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthSinaWeiboWebLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pod/Providers/FoursquareWeb/SimpleAuthFoursquareWebLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthFoursquareWebLoginViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Julien Seren-Rosso on 23/01/2014. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthFoursquareWebLoginViewController : SimpleAuthWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/SimpleAuth/Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/SimpleAuth/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SimpleAuthDemo 4 | // 5 | // Created by Caleb Davenport on 1/16/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SADAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SADAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Pod/Core/NSObject+SimpleAuthAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+SimpleAuthAdditions.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/20/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | static inline BOOL SimpleAuthClassIsSubclassOfClass(Class classOne, Class classTwo); 10 | 11 | @interface NSObject (SimpleAuthAdditions) 12 | 13 | + (void)SimpleAuth_enumerateSubclassesWithBlock:(void (^) (Class klass, BOOL *stop))block; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Pod/Core/ios/UIWindow+SimpleAuthAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIWindow+SimpleAuthAdditions.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/14/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "UIWindow+SimpleAuthAdditions.h" 10 | 11 | @implementation UIWindow (SimpleAuthAdditions) 12 | 13 | + (instancetype)SimpleAuth_mainWindow { 14 | return [[[UIApplication sharedApplication] delegate] window]; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Pod/Core/SimpleAuthDefines.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthDefines.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/30/14. 6 | // Copyright (c) 2013-2015 Caleb Davenport. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthDefines.h" 10 | 11 | NSString *const SimpleAuthErrorDomain = @"SimpleAuthErrorDomain"; 12 | NSString *const SimpleAuthErrorStatusCodeKey = @"SimpleAuthErrorStatusCode"; 13 | NSString *const SimpleAuthPresentInterfaceBlockKey = @"present_interface_block"; 14 | NSString *const SimpleAuthDismissInterfaceBlockKey = @"dismiss_interface_block"; 15 | NSString *const SimpleAuthRedirectURIKey = @"redirect_uri"; 16 | -------------------------------------------------------------------------------- /Pod/Core/SimpleAuthUtilities.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthUtilities.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 10/7/14. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthUtilities.h" 10 | #import "SimpleAuth.h" 11 | 12 | NSString *SimpleAuthLocalizedString(NSString *key) { 13 | NSBundle *mainBundle = [NSBundle bundleForClass:[SimpleAuth class]]; 14 | NSURL *resourcesBundleURL = [mainBundle URLForResource:@"SimpleAuth" withExtension:@"bundle"]; 15 | NSBundle *resourcesBundle = [NSBundle bundleWithURL:resourcesBundleURL]; 16 | return NSLocalizedStringFromTableInBundle(key, nil, resourcesBundle, nil); 17 | } 18 | -------------------------------------------------------------------------------- /Pod/Core/ios/UIViewController+SimpleAuthAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+SimpleAuthAdditions.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/14/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "UIViewController+SimpleAuthAdditions.h" 10 | #import "UIWindow+SimpleAuthAdditions.h" 11 | 12 | @implementation UIViewController (SimpleAuthAdditions) 13 | 14 | + (instancetype)SimpleAuth_presentedViewController { 15 | UIWindow *window = [UIWindow SimpleAuth_mainWindow]; 16 | UIViewController *controller = window.rootViewController; 17 | while (controller.presentedViewController) { 18 | controller = controller.presentedViewController; 19 | } 20 | return controller; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Example/SimpleAuth/Providers.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | twitter 6 | twitter-web 7 | facebook 8 | facebook-web 9 | instagram 10 | dropbox-web 11 | tumblr 12 | foursquare-web 13 | meetup 14 | linkedin-web 15 | sinaweibo-web 16 | google-web 17 | strava-web 18 | tripit 19 | trello-web 20 | box-web 21 | onedrive-web 22 | vkontakte-web 23 | 24 | 25 | -------------------------------------------------------------------------------- /Pod/Core/SimpleAuthProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthProvider.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/6/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuth.h" 10 | 11 | #import 12 | 13 | @interface SimpleAuthProvider : NSObject 14 | 15 | @property (nonatomic, readonly, copy) NSDictionary *options; 16 | @property (nonatomic, readonly) NSOperationQueue *operationQueue; 17 | 18 | + (NSString *)type; 19 | + (NSDictionary *)defaultOptions; 20 | 21 | - (instancetype)initWithOptions:(NSDictionary *)options; 22 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion; 23 | - (void)reAuthorizeWithToken:(NSString *)token completionHandler:(SimpleAuthRequestHandler)completion; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2014 Byliner, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Pod/Core/ACAccountStore+SimpleAuth.h: -------------------------------------------------------------------------------- 1 | // 2 | // ACAccountStore+SimpleAuth.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/25/14. 6 | // Copyright (c) 2014 Seesaw Decisions Corporation. All rights reserved. 7 | // 8 | 9 | @import Accounts; 10 | @class RACSignal; 11 | 12 | @interface ACAccountStore (SimpleAuth) 13 | 14 | /** 15 | Access a shared account store instance. 16 | 17 | @return A shared account store. 18 | */ 19 | + (instancetype)SimpleAuth_sharedAccountStore; 20 | 21 | /** 22 | Creates and returns a signal that sends next with all system accounts of the 23 | given type. This is a convenience wrapper for 24 | `-[ACAccountStore requestAccessToAccountsWithType:options:completion:]`. 25 | 26 | @return A signal that sends next with all system accounts of the given type. 27 | 28 | @param typeIdentifier Value passed to 29 | `-[ACAccountStore accountTypeWithAccountTypeIdentifier:]` 30 | @param options Value passed to 31 | `-[ACAccountStore requestAccessToAccountsWithType:options:completion:]`. 32 | */ 33 | + (RACSignal *)SimpleAuth_accountsWithTypeIdentifier:(NSString *)typeIdentifier options:(NSDictionary *)options; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Pod/Providers/Tumblr/SimpleAuthTumblrLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTumblrLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/16/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthTumblrLoginViewController.h" 10 | 11 | @implementation SimpleAuthTumblrLoginViewController 12 | 13 | #pragma mark - SimpleAuthWebViewController 14 | 15 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 16 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 17 | self.title = @"tumblr"; 18 | } 19 | return self; 20 | } 21 | 22 | 23 | - (NSURLRequest *)initialRequest { 24 | NSDictionary *parameters = @{ 25 | @"oauth_token" : self.requestToken[@"oauth_token"], 26 | }; 27 | NSString *URLString = [NSString stringWithFormat: 28 | @"http://www.tumblr.com/oauth/authorize?%@", 29 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 30 | NSURL *URL = [NSURL URLWithString:URLString]; 31 | 32 | return [NSURLRequest requestWithURL:URL]; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Pod/Providers/TwitterWeb/SimpleAuthTwitterWebLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTwitterWebLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/15/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthTwitterWebLoginViewController.h" 10 | 11 | @implementation SimpleAuthTwitterWebLoginViewController 12 | 13 | #pragma mark - SimpleAuthWebViewController 14 | 15 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 16 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 17 | self.title = @"Twitter"; 18 | } 19 | return self; 20 | } 21 | 22 | 23 | - (NSURLRequest *)initialRequest { 24 | NSDictionary *parameters = @{ 25 | @"oauth_token" : self.requestToken[@"oauth_token"], 26 | @"force_login": @"true" 27 | }; 28 | NSString *URLString = [NSString stringWithFormat: 29 | @"https://api.twitter.com/oauth/authenticate?%@", 30 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 31 | NSURL *URL = [NSURL URLWithString:URLString]; 32 | 33 | return [NSURLRequest requestWithURL:URL]; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Pod/Providers/TripIt/SimpleAuthTripItLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTripItLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Mark Krenek on 8/15/14. 6 | // Copyright (c) 2014 Mark Krenek. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthTripItLoginViewController.h" 10 | 11 | @implementation SimpleAuthTripItLoginViewController 12 | 13 | #pragma mark - SimpleAuthWebViewController 14 | 15 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 16 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 17 | self.title = @"TripIt"; 18 | } 19 | return self; 20 | } 21 | 22 | 23 | - (NSURLRequest *)initialRequest { 24 | NSDictionary *parameters = @{ 25 | @"oauth_token" : self.requestToken[@"oauth_token"], 26 | @"oauth_callback" : self.options[SimpleAuthRedirectURIKey], 27 | }; 28 | NSString *URLString = [NSString stringWithFormat: 29 | @"https://m.tripit.com/oauth/authorize?%@", 30 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 31 | NSURL *URL = [NSURL URLWithString:URLString]; 32 | 33 | return [NSURLRequest requestWithURL:URL]; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Example/SimpleAuth/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | me.calebd.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Pod/Providers/BoxWeb/SimpleAuthBoxWebLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthBoxWebLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by dkhamsing on 3/26/15. 6 | // Copyright (c) 2015 dkhamsing. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthBoxWebLoginViewController.h" 10 | 11 | @implementation SimpleAuthBoxWebLoginViewController 12 | 13 | #pragma mark - SimpleAuthWebViewController 14 | 15 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 16 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 17 | self.title = @"Box"; 18 | } 19 | return self; 20 | } 21 | 22 | 23 | - (NSURLRequest *)initialRequest { 24 | NSDictionary *parameters = @{ 25 | @"client_id" : self.options[@"client_id"], 26 | @"redirect_uri" : self.options[SimpleAuthRedirectURIKey], 27 | @"response_type" : @"code" 28 | }; 29 | NSString *URLString = [NSString stringWithFormat: 30 | @"https://api.box.com/oauth2/authorize?%@", 31 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 32 | NSURL *URL = [NSURL URLWithString:URLString]; 33 | 34 | return [NSURLRequest requestWithURL:URL]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Pod/Providers/DropboxWeb/SimpleAuthDropboxWebLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthDropboxWebLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/23/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthDropboxWebLoginViewController.h" 10 | 11 | @implementation SimpleAuthDropboxWebLoginViewController 12 | 13 | #pragma mark - SimpleAuthWebViewController 14 | 15 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 16 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 17 | self.title = @"Dropbox"; 18 | } 19 | return self; 20 | } 21 | 22 | 23 | - (NSURLRequest *)initialRequest { 24 | NSDictionary *parameters = @{ 25 | @"client_id" : self.options[@"client_id"], 26 | @"redirect_uri" : self.options[SimpleAuthRedirectURIKey], 27 | @"response_type" : @"token" 28 | }; 29 | NSString *URLString = [NSString stringWithFormat: 30 | @"https://www.dropbox.com/1/oauth2/authorize?%@", 31 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 32 | NSURL *URL = [NSURL URLWithString:URLString]; 33 | 34 | return [NSURLRequest requestWithURL:URL]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Example/SimpleAuth/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "3x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "3x" 27 | }, 28 | { 29 | "size" : "57x57", 30 | "idiom" : "iphone", 31 | "filename" : "Artboard 1.png", 32 | "scale" : "1x" 33 | }, 34 | { 35 | "size" : "57x57", 36 | "idiom" : "iphone", 37 | "filename" : "Artboard 2.png", 38 | "scale" : "2x" 39 | }, 40 | { 41 | "size" : "60x60", 42 | "idiom" : "iphone", 43 | "filename" : "Artboard 3.png", 44 | "scale" : "2x" 45 | }, 46 | { 47 | "size" : "60x60", 48 | "idiom" : "iphone", 49 | "filename" : "Artboard 4.png", 50 | "scale" : "3x" 51 | } 52 | ], 53 | "info" : { 54 | "version" : 1, 55 | "author" : "xcode" 56 | }, 57 | "properties" : { 58 | "pre-rendered" : true 59 | } 60 | } -------------------------------------------------------------------------------- /Pod/Providers/FoursquareWeb/SimpleAuthFoursquareWebLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthFoursquareWebLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Julien Seren-Rosso on 23/01/2014. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthFoursquareWebLoginViewController.h" 10 | 11 | @implementation SimpleAuthFoursquareWebLoginViewController 12 | 13 | #pragma mark - SimpleAuthWebViewController 14 | 15 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 16 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 17 | self.title = @"Foursquare"; 18 | } 19 | return self; 20 | } 21 | 22 | 23 | - (NSURLRequest *)initialRequest { 24 | NSDictionary *parameters = @{ 25 | @"client_id" : self.options[@"client_id"], 26 | @"redirect_uri" : self.options[SimpleAuthRedirectURIKey], 27 | @"response_type" : @"token" 28 | }; 29 | NSString *URLString = [NSString stringWithFormat: 30 | @"https://foursquare.com/oauth2/authenticate?%@", 31 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 32 | NSURL *URL = [NSURL URLWithString:URLString]; 33 | 34 | return [NSURLRequest requestWithURL:URL]; 35 | } 36 | @end 37 | -------------------------------------------------------------------------------- /Pod/Providers/Meetup/SimpleAuthMeetupLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthMeetupLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Mouhcine El Amine on 17/01/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthMeetupLoginViewController.h" 10 | 11 | @implementation SimpleAuthMeetupLoginViewController 12 | 13 | #pragma mark - SimpleAuthWebViewController 14 | 15 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 16 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 17 | self.title = @"Meetup"; 18 | } 19 | return self; 20 | } 21 | 22 | 23 | - (NSURLRequest *)initialRequest { 24 | NSDictionary *parameters = @{ 25 | @"client_id" : self.options[@"client_id"], 26 | @"redirect_uri" : self.options[SimpleAuthRedirectURIKey], 27 | @"response_type" : @"token", 28 | @"scope" : @"ageless" 29 | }; 30 | NSString *URLString = [NSString stringWithFormat: 31 | @"https://secure.meetup.com/oauth2/authorize?%@", 32 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 33 | NSURL *URL = [NSURL URLWithString:URLString]; 34 | 35 | return [NSURLRequest requestWithURL:URL]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Pod/Core/NSObject+SimpleAuthAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+SimpleAuthAdditions.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/20/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "NSObject+SimpleAuthAdditions.h" 10 | 11 | #import 12 | 13 | @implementation NSObject (SimpleAuthAdditions) 14 | 15 | + (void)SimpleAuth_enumerateSubclassesWithBlock:(void (^) (Class klass, BOOL *stop))block { 16 | int numberOfClasses = objc_getClassList(NULL, 0); 17 | Class allClasses[numberOfClasses]; 18 | objc_getClassList(allClasses, numberOfClasses); 19 | for (int i = 0; i < numberOfClasses; i++) { 20 | Class klass = allClasses[i]; 21 | if (SimpleAuthClassIsSubclassOfClass(klass, self)) { 22 | BOOL stop = NO; 23 | block(klass, &stop); 24 | if (stop) { 25 | return; 26 | } 27 | } 28 | } 29 | } 30 | 31 | @end 32 | 33 | static inline BOOL SimpleAuthClassIsSubclassOfClass(Class classOne, Class classTwo) { 34 | Class superclass = class_getSuperclass(classOne); 35 | if (superclass == classTwo) { 36 | return YES; 37 | } 38 | else if (superclass == Nil) { 39 | return NO; 40 | } 41 | else { 42 | return SimpleAuthClassIsSubclassOfClass(superclass, classTwo); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Pod/Providers/GoogleWeb/SimpleAuthGoogleWebLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthGoogleWebLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Ramon Vicente on 2/24/15. 6 | // Copyright (c) 2015 UMOBI. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthGoogleWebLoginViewController.h" 10 | 11 | @implementation SimpleAuthGoogleWebLoginViewController 12 | 13 | #pragma mark - SimpleAuthWebViewController 14 | 15 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 16 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 17 | self.title = @"Google +"; 18 | } 19 | return self; 20 | } 21 | 22 | 23 | - (NSURLRequest *)initialRequest { 24 | NSDictionary *parameters = @{ 25 | @"client_id" : self.options[@"client_id"], 26 | @"redirect_uri" : self.options[SimpleAuthRedirectURIKey], 27 | @"response_type" : @"code", 28 | @"scope" : self.options[@"scope"] 29 | }; 30 | NSString *URLString = [NSString stringWithFormat: 31 | @"https://accounts.google.com/o/oauth2/auth?%@", 32 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 33 | NSURL *URL = [NSURL URLWithString:URLString]; 34 | 35 | return [NSURLRequest requestWithURL:URL]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Pod/Providers/FacebookWeb/SimpleAuthFacebookWebLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthFacebookWebLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/22/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthFacebookWebLoginViewController.h" 10 | 11 | @implementation SimpleAuthFacebookWebLoginViewController 12 | 13 | #pragma mark - SimpleAuthWebViewController 14 | 15 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 16 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 17 | self.title = @"Facebook"; 18 | } 19 | return self; 20 | } 21 | 22 | 23 | - (NSURLRequest *)initialRequest { 24 | NSDictionary *parameters = @{ 25 | @"client_id" : self.options[@"app_id"], 26 | @"redirect_uri" : self.options[SimpleAuthRedirectURIKey], 27 | @"response_type" : @"token", 28 | @"scope" : [self.options[@"permissions"] componentsJoinedByString:@","] 29 | }; 30 | NSString *URLString = [NSString stringWithFormat: 31 | @"https://www.facebook.com/dialog/oauth?%@", 32 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 33 | NSURL *URL = [NSURL URLWithString:URLString]; 34 | 35 | return [NSURLRequest requestWithURL:URL]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Pod/Providers/VKontakteWeb/SimpleAuthVKontakteWebLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthVKontakteWebLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Mikhail Kupriyanov on 7/7/15. 6 | // 7 | 8 | #import "SimpleAuthVKontakteWebLoginViewController.h" 9 | 10 | @implementation SimpleAuthVKontakteWebLoginViewController 11 | 12 | #pragma mark - SimpleAuthWebViewController 13 | 14 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 15 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 16 | self.title = @"VKontakte"; 17 | } 18 | return self; 19 | } 20 | 21 | - (NSURLRequest *)initialRequest { 22 | NSDictionary *parameters = @{ 23 | @"client_id" : self.options[@"client_id"], 24 | @"redirect_uri" : self.options[SimpleAuthRedirectURIKey], 25 | @"response_type" : @"token", 26 | @"scope" : [self.options[@"permission"] componentsJoinedByString:@","], 27 | @"display" : @"mobile", 28 | @"v" : @"5.34" 29 | }; 30 | 31 | NSString *URLString = [NSString stringWithFormat: 32 | @"https://oauth.vk.com/authorize?%@", 33 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 34 | NSURL *URL = [NSURL URLWithString:URLString]; 35 | 36 | return [NSURLRequest requestWithURL:URL]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Pod/Providers/Strava/SimpleAuthStravaWebLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthStravaWebLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Ben Stahl on 7/27/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthStravaWebLoginViewController.h" 10 | 11 | @implementation SimpleAuthStravaWebLoginViewController 12 | 13 | 14 | #pragma mark - SimpleAuthWebViewController 15 | 16 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 17 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 18 | self.title = @"Strava"; 19 | } 20 | return self; 21 | } 22 | 23 | - (NSURLRequest *)initialRequest { 24 | 25 | NSMutableDictionary *parameters = [NSMutableDictionary new]; 26 | parameters[@"client_id"] = self.options[@"client_id"]; 27 | parameters[@"redirect_uri"] = self.options[SimpleAuthRedirectURIKey]; 28 | parameters[@"response_type"] = @"code"; 29 | if (self.options[@"scope"]) { 30 | parameters[@"scope"] = [self.options[@"scope"] componentsJoinedByString:@" "]; 31 | } 32 | NSString *URLString = [NSString stringWithFormat: 33 | @"https://www.strava.com/oauth/authorize?%@", 34 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 35 | NSURL *URL = [NSURL URLWithString:URLString]; 36 | 37 | return [NSURLRequest requestWithURL:URL]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Pod/Providers/LinkedIn/SimpleAuthLinkedInWebLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthLinkedInWebLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Abhishek Sheth on 24/01/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthLinkedInWebLoginViewController.h" 10 | 11 | @interface SimpleAuthLinkedInWebLoginViewController () 12 | 13 | @end 14 | 15 | @implementation SimpleAuthLinkedInWebLoginViewController 16 | 17 | #pragma mark - SimpleAuthWebViewController 18 | 19 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 20 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 21 | self.title = @"LinkedIn"; 22 | } 23 | return self; 24 | } 25 | 26 | 27 | - (NSURLRequest *)initialRequest { 28 | NSDictionary *parameters = @{ 29 | @"client_id" : self.options[@"client_id"], 30 | @"redirect_uri" : self.options[SimpleAuthRedirectURIKey], 31 | @"response_type" : @"code", 32 | @"state" : [[NSProcessInfo processInfo] globallyUniqueString] 33 | }; 34 | 35 | NSString *URLString = [NSString stringWithFormat: 36 | @"https://www.linkedin.com/uas/oauth2/authorization?%@", 37 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 38 | NSURL *URL = [NSURL URLWithString:URLString]; 39 | 40 | return [NSURLRequest requestWithURL:URL]; 41 | } 42 | 43 | 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Pod/Providers/Instagram/SimpleAuthInstagramLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthInstagramLoginViewController.m 3 | // SimpleAuthInstagram 4 | // 5 | // Created by Caleb Davenport on 11/7/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthInstagramLoginViewController.h" 10 | 11 | @implementation SimpleAuthInstagramLoginViewController 12 | 13 | #pragma mark - SimpleAuthWebViewController 14 | 15 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 16 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 17 | self.title = @"Instagram"; 18 | } 19 | return self; 20 | } 21 | 22 | 23 | - (NSURLRequest *)initialRequest { 24 | NSMutableDictionary *parameters = [NSMutableDictionary new]; 25 | parameters[@"client_id"] = self.options[@"client_id"]; 26 | parameters[@"redirect_uri"] = self.options[SimpleAuthRedirectURIKey]; 27 | parameters[@"response_type"] = @"token"; 28 | if (self.options[@"scope"]) { 29 | parameters[@"scope"] = [self.options[@"scope"] componentsJoinedByString:@" "]; 30 | } 31 | NSString *URLString = [NSString stringWithFormat: 32 | @"https://instagram.com/oauth/authorize/?%@", 33 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 34 | NSURL *URL = [NSURL URLWithString:URLString]; 35 | 36 | return [NSURLRequest requestWithURL:URL]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Pod/Providers/OneDriveWeb/SimpleAuthOneDriveWebLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthOneDriveWebLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by dkhamsing on 3/31/15. 6 | // Copyright (c) 2015 dkhamsing. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthOneDriveWebLoginViewController.h" 10 | 11 | @implementation SimpleAuthOneDriveWebLoginViewController 12 | 13 | #pragma mark - SimpleAuthWebViewController 14 | 15 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 16 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 17 | self.title = @"OneDrive"; 18 | } 19 | return self; 20 | } 21 | 22 | 23 | - (NSURLRequest *)initialRequest { 24 | NSDictionary *parameters = @{ 25 | @"client_id" : self.options[@"client_id"], 26 | @"response_type" : @"code", 27 | @"scope":self.options[@"scope"] 28 | }; 29 | NSString *URLString = [NSString stringWithFormat: 30 | @"https://login.live.com/oauth20_authorize.srf?%@", 31 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 32 | 33 | NSURL *URL = [NSURL URLWithString:URLString]; 34 | 35 | return [NSURLRequest requestWithURL:URL]; 36 | } 37 | 38 | 39 | - (BOOL)isTargetRedirectURL:(NSURL *)URL { 40 | NSRange range = [URL.absoluteString rangeOfString:@"?code=" options:NSCaseInsensitiveSearch]; 41 | return range.location != NSNotFound; 42 | } 43 | 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Pod/Core/SimpleAuthProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/6/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthProvider.h" 10 | 11 | @interface SimpleAuthProvider () 12 | 13 | @property (nonatomic, copy) NSDictionary *options; 14 | 15 | @end 16 | 17 | @implementation SimpleAuthProvider 18 | 19 | #pragma mark - Properties 20 | 21 | @synthesize operationQueue = _operationQueue; 22 | 23 | - (NSOperationQueue *)operationQueue { 24 | if (!_operationQueue) { 25 | _operationQueue = [[NSOperationQueue alloc] init]; 26 | } 27 | return _operationQueue; 28 | } 29 | 30 | 31 | #pragma mark - Initializers 32 | 33 | - (instancetype)initWithOptions:(NSDictionary *)options { 34 | if ((self = [super init])) { 35 | self.options = options; 36 | } 37 | return self; 38 | } 39 | 40 | 41 | #pragma mark - Public 42 | 43 | + (NSString *)type { 44 | [self doesNotRecognizeSelector:_cmd]; 45 | return nil; 46 | } 47 | 48 | + (NSDictionary *)defaultOptions { 49 | return @{}; 50 | } 51 | 52 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 53 | [self doesNotRecognizeSelector:_cmd]; 54 | } 55 | 56 | - (void)reAuthorizeWithToken:(NSString *)token completionHandler:(SimpleAuthRequestHandler)completion { 57 | // Provider doesn't have a re authorize token method setup revert back to standard authorization 58 | [self authorizeWithCompletion:completion]; 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /Pod/Providers/SinaWeiboWeb/SimpleAuthSinaWeiboWebLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthSinaWeiboWebLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Alexander Schuch on 17/02/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthSinaWeiboWebLoginViewController.h" 10 | 11 | @interface SimpleAuthSinaWeiboWebLoginViewController () 12 | 13 | @end 14 | 15 | @implementation SimpleAuthSinaWeiboWebLoginViewController 16 | 17 | #pragma mark - SimpleAuthWebViewController 18 | 19 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 20 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 21 | self.title = @"Sina Weibo"; 22 | } 23 | return self; 24 | } 25 | 26 | 27 | - (NSURLRequest *)initialRequest { 28 | NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0]; 29 | 30 | NSDictionary *parameters = @{ 31 | @"client_id" : self.options[@"client_id"], 32 | @"redirect_uri" : self.options[SimpleAuthRedirectURIKey], 33 | @"state" : [[NSProcessInfo processInfo] globallyUniqueString], 34 | @"display": @"mobile", 35 | @"language": language 36 | }; 37 | 38 | NSString *parameterString = [CMDQueryStringSerialization queryStringWithDictionary:parameters]; 39 | NSString *URLString = [NSString stringWithFormat:@"https://api.weibo.com/oauth2/authorize?%@", parameterString]; 40 | NSURL *URL = [NSURL URLWithString:URLString]; 41 | 42 | return [NSURLRequest requestWithURL:URL]; 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Pod/Providers/Trello/SimpleAuthTrelloLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTrelloLoginViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Damiano Buscemi on 22/08/14. 6 | // Copyright (c) 2014 Crispy Bacon, S.r.l. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthTrelloLoginViewController.h" 10 | 11 | @interface SimpleAuthTrelloLoginViewController () 12 | 13 | @end 14 | 15 | @implementation SimpleAuthTrelloLoginViewController 16 | 17 | #pragma mark - SimpleAuthWebViewController 18 | 19 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 20 | if ((self = [super initWithOptions:options requestToken:requestToken])) { 21 | self.title = @"Trello"; 22 | } 23 | return self; 24 | } 25 | 26 | 27 | - (NSURLRequest *)initialRequest { 28 | NSMutableDictionary *parameters = [NSMutableDictionary new]; 29 | parameters[@"key"] = self.options[@"key"]; 30 | parameters[@"response_type"] = @"token"; 31 | parameters[@"expiration"] = @"30days"; 32 | parameters[@"callback_method"] = @"fragment"; 33 | parameters[@"return_url"] = self.options[SimpleAuthRedirectURIKey]; 34 | parameters[@"name"] = self.options[@"name"]; 35 | if (self.options[@"scope"]) { 36 | parameters[@"scope"] = [self.options[@"scope"] componentsJoinedByString:@" "]; 37 | } 38 | NSString *URLString = [NSString stringWithFormat: 39 | @"https://trello.com/1/authorize/?%@", 40 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 41 | NSURL *URL = [NSURL URLWithString:URLString]; 42 | 43 | return [NSURLRequest requestWithURL:URL]; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Pod/Core/ios/SimpleAuthWebViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthWebViewController.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/7/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuth.h" 10 | 11 | #import 12 | 13 | typedef void (^SimpleAuthWebViewControllerCompletionHandler) (UIViewController *controller, NSURL *URL, NSError *error); 14 | 15 | @interface SimpleAuthWebViewController : UIViewController 16 | 17 | @property (nonatomic, readonly) UIWebView *webView; 18 | @property (nonatomic, readonly, copy) NSDictionary *options; 19 | @property (nonatomic, readonly, copy) NSDictionary *requestToken; 20 | @property (nonatomic, copy) SimpleAuthWebViewControllerCompletionHandler completion; 21 | 22 | /** 23 | Initializes a basic web login view controller. 24 | @param options Providers should pass their options along here. 25 | @see -initWithOptions:requestToken: 26 | */ 27 | - (instancetype)initWithOptions:(NSDictionary *)options; 28 | 29 | /** 30 | Initializes a web login view controller for an OAuth 1 style provider. 31 | @param options Providers should pass their options along here. 32 | @param requestToken Token obtained through the OAuth 1 flow. 33 | @see -initWithOptions: 34 | */ 35 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken; 36 | 37 | /** 38 | Subclasses should override this to provide the request that will be loaded the 39 | first time that the web view appears. 40 | @return A URL request. 41 | */ 42 | - (NSURLRequest *)initialRequest; 43 | 44 | /** 45 | Subclasses may override this to determine if the a given URL is the desired 46 | redirect URL. The default implementation of this method checks the given URL 47 | agains the value provided in options. 48 | @param URL The URL to inspect. 49 | @return `YES` if the URL is the desired redirect URL, `NO` if it is not. 50 | */ 51 | - (BOOL)isTargetRedirectURL:(NSURL *)URL; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Example/SimpleAuth/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Pod/Core/ACAccountStore+SimpleAuth.m: -------------------------------------------------------------------------------- 1 | // 2 | // ACAccountStore+SimpleAuth.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/25/14. 6 | // Copyright (c) 2014 Seesaw Decisions Corporation. All rights reserved. 7 | // 8 | 9 | #import "ACAccountStore+SimpleAuth.h" 10 | #import "SimpleAuthDefines.h" 11 | #import 12 | 13 | @implementation ACAccountStore (SimpleAuth) 14 | 15 | + (instancetype)SimpleAuth_sharedAccountStore { 16 | static dispatch_once_t token; 17 | static ACAccountStore *store; 18 | dispatch_once(&token, ^{ 19 | store = [ACAccountStore new]; 20 | }); 21 | return store; 22 | } 23 | 24 | 25 | + (RACSignal *)SimpleAuth_accountsWithTypeIdentifier:(NSString *)typeIdentifier options:(NSDictionary *)options { 26 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 27 | ACAccountStore *store = [self SimpleAuth_sharedAccountStore]; 28 | ACAccountType *type = [store accountTypeWithAccountTypeIdentifier:typeIdentifier]; 29 | [store requestAccessToAccountsWithType:type options:options completion:^(BOOL granted, NSError *accountsError) { 30 | if (granted) { 31 | NSArray *accounts = [store accountsWithAccountType:type]; 32 | NSUInteger numberOfAccounts = [accounts count]; 33 | if (numberOfAccounts == 0) { 34 | NSDictionary *dictionary = @{ 35 | NSUnderlyingErrorKey: accountsError ?: [[NSError alloc] initWithDomain:ACErrorDomain code:ACErrorAccountNotFound userInfo:nil] 36 | }; 37 | NSError *error = [NSError errorWithDomain:SimpleAuthErrorDomain code:SimpleAuthErrorAccounts userInfo:dictionary]; 38 | [subscriber sendError:error]; 39 | } 40 | else { 41 | [subscriber sendNext:accounts]; 42 | [subscriber sendCompleted]; 43 | } 44 | } 45 | else { 46 | NSDictionary *dictionary = @{ 47 | NSUnderlyingErrorKey: accountsError ?: [[NSError alloc] initWithDomain:ACErrorDomain code:ACErrorPermissionDenied userInfo:nil] 48 | }; 49 | NSError *error = [NSError errorWithDomain:SimpleAuthErrorDomain code:SimpleAuthErrorAccounts userInfo:dictionary]; 50 | [subscriber sendError:error]; 51 | } 52 | }]; 53 | return nil; 54 | }]; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /Pod/Core/SimpleAuthDefines.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthDefines.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/30/14. 6 | // Copyright (c) 2013-2015 Caleb Davenport. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | /** 12 | Authentication error domain. 13 | */ 14 | extern NSString *const SimpleAuthErrorDomain; 15 | 16 | /** 17 | The corresponding value is an HTTP staus code if the error was a network 18 | related error. 19 | */ 20 | extern NSString *const SimpleAuthErrorStatusCodeKey; 21 | 22 | /** 23 | Error codes for errors in the `SimpleAuthErrorDomain`. 24 | */ 25 | typedef NS_ENUM(NSUInteger, SimpleAuthError) { 26 | 27 | /** 28 | The user cancelled authentication. 29 | */ 30 | SimpleAuthErrorUserCancelled = 100, 31 | 32 | /* 33 | An error that occurred as the result of a failed network operation. 34 | */ 35 | SimpleAuthErrorNetwork, 36 | 37 | /** 38 | An error that originated in Accounts.framework. 39 | */ 40 | SimpleAuthErrorAccounts, 41 | 42 | /** 43 | Returned if SimpleAuth was able to parse response data. 44 | */ 45 | SimpleAuthErrorInvalidData 46 | }; 47 | 48 | /** 49 | Called when authorization either completes with a response or fails with an 50 | error. Should an error occur, response object will be nil. 51 | 52 | @param responseObject The authorization response, or nil if an error occurred. 53 | @param error An error. 54 | 55 | @see +authorize:completion: 56 | @see +authorize:options:completion: 57 | */ 58 | typedef void (^SimpleAuthRequestHandler) (id responseObject, NSError *error); 59 | 60 | extern NSString *const SimpleAuthPresentInterfaceBlockKey; 61 | extern NSString *const SimpleAuthDismissInterfaceBlockKey; 62 | 63 | /** 64 | Called when a user interface element must be presented to continue 65 | authorization. This could be a UIViewController for web login, or a 66 | UIActionSheet for system login. All providers will have default 67 | implementations for the appropriate callback types. You can customize provider 68 | behavior by providing your own blocks. This will be called on the main 69 | thread. 70 | 71 | @see SimpleAuthPresentInterfaceBlockKey 72 | @see SimpleAuthDismissInterfaceBlockKey 73 | @see +configuration 74 | @see +authorize:options:completion: 75 | 76 | @param userInterfaceElement An element that is about to be presented or 77 | dismissed. 78 | */ 79 | typedef void (^SimpleAuthInterfaceHandler) (id userInterfaceElement); 80 | 81 | /** 82 | Key used to define the redirect URI for OAuth style providers. 83 | 84 | @see +configuration 85 | @see +authorize:options:completion: 86 | */ 87 | extern NSString *const SimpleAuthRedirectURIKey; 88 | -------------------------------------------------------------------------------- /Example/SimpleAuth/SADProviderListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SADProviderListViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/16/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SADProviderListViewController.h" 10 | 11 | #import 12 | 13 | @interface SADProviderListViewController () 14 | 15 | @end 16 | 17 | @implementation SADProviderListViewController 18 | 19 | #pragma mark - NSObject 20 | 21 | - (instancetype)init { 22 | if ((self = [super initWithStyle:UITableViewStylePlain])) { 23 | self.title = @"SimpleAuth"; 24 | } 25 | return self; 26 | } 27 | 28 | 29 | #pragma mark - UIViewController 30 | 31 | - (void)viewDidLoad { 32 | [super viewDidLoad]; 33 | [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"]; 34 | self.tableView.rowHeight = 50.0; 35 | self.tableView.separatorInset = UIEdgeInsetsZero; 36 | } 37 | 38 | 39 | #pragma mark - Private 40 | 41 | + (NSArray *)providers { 42 | static dispatch_once_t token; 43 | static NSArray *array; 44 | dispatch_once(&token, ^{ 45 | NSURL *URL = [[NSBundle mainBundle] URLForResource:@"Providers" withExtension:@"plist"]; 46 | array = [NSArray arrayWithContentsOfURL:URL]; 47 | }); 48 | return array; 49 | } 50 | 51 | 52 | #pragma mark - UITableViewDataSource 53 | 54 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 55 | return 1; 56 | } 57 | 58 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 59 | return [[[self class] providers] count]; 60 | } 61 | 62 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 63 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; 64 | cell.textLabel.text = [[self class] providers][indexPath.row]; 65 | return cell; 66 | } 67 | 68 | 69 | #pragma mark - UITableViewDelegate 70 | 71 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 72 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 73 | 74 | NSString *provider = [[self class] providers][indexPath.row]; 75 | NSDictionary *configuration = SimpleAuth.configuration[provider]; 76 | if ([configuration count] == 0) { 77 | NSLog(@"It looks like you haven't configured the \"%@\" provider.\n" 78 | "Consider calling +[SimpleAuth configuration] in `application:willFinishLaunchingWithOptions: " 79 | "and providing all relevant options for the given provider.", 80 | provider); 81 | return; 82 | } 83 | 84 | [SimpleAuth authorize:provider completion:^(id responseObject, NSError *error) { 85 | NSLog(@"\nResponse: %@\nError:%@", responseObject, error); 86 | }]; 87 | } 88 | 89 | @end 90 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - CMDQueryStringSerialization (0.3.2): 3 | - ISO8601 4 | - cocoa-oauth (0.0.1): 5 | - NSData+Base64 (~> 1.0) 6 | - ISO8601 (0.1.3) 7 | - NSData+Base64 (1.0.0) 8 | - ReactiveCocoa (2.5): 9 | - ReactiveCocoa/UI (= 2.5) 10 | - ReactiveCocoa/Core (2.5): 11 | - ReactiveCocoa/no-arc 12 | - ReactiveCocoa/no-arc (2.5) 13 | - ReactiveCocoa/UI (2.5): 14 | - ReactiveCocoa/Core 15 | - SimpleAuth (0.3.9): 16 | - SimpleAuth/BoxWeb (= 0.3.9) 17 | - SimpleAuth/Core (= 0.3.9) 18 | - SimpleAuth/DropboxWeb (= 0.3.9) 19 | - SimpleAuth/Facebook (= 0.3.9) 20 | - SimpleAuth/FacebookWeb (= 0.3.9) 21 | - SimpleAuth/FoursquareWeb (= 0.3.9) 22 | - SimpleAuth/GoogleWeb (= 0.3.9) 23 | - SimpleAuth/Instagram (= 0.3.9) 24 | - SimpleAuth/LinkedInWeb (= 0.3.9) 25 | - SimpleAuth/Meetup (= 0.3.9) 26 | - SimpleAuth/OneDriveWeb (= 0.3.9) 27 | - SimpleAuth/SinaWeiboWeb (= 0.3.9) 28 | - SimpleAuth/Strava (= 0.3.9) 29 | - SimpleAuth/Trello (= 0.3.9) 30 | - SimpleAuth/TripIt (= 0.3.9) 31 | - SimpleAuth/Tumblr (= 0.3.9) 32 | - SimpleAuth/Twitter (= 0.3.9) 33 | - SimpleAuth/TwitterWeb (= 0.3.9) 34 | - SimpleAuth/VKontakteWeb (= 0.3.9) 35 | - SimpleAuth/BoxWeb (0.3.9): 36 | - SimpleAuth/Core 37 | - SimpleAuth/Core (0.3.9): 38 | - CMDQueryStringSerialization 39 | - ReactiveCocoa 40 | - SimpleAuth/DropboxWeb (0.3.9): 41 | - SimpleAuth/Core 42 | - SimpleAuth/Facebook (0.3.9): 43 | - SimpleAuth/Core 44 | - SimpleAuth/FacebookWeb (0.3.9): 45 | - SimpleAuth/Core 46 | - SimpleAuth/FoursquareWeb (0.3.9): 47 | - SimpleAuth/Core 48 | - SimpleAuth/GoogleWeb (0.3.9): 49 | - SimpleAuth/Core 50 | - SimpleAuth/Instagram (0.3.9): 51 | - SimpleAuth/Core 52 | - SimpleAuth/LinkedInWeb (0.3.9): 53 | - SimpleAuth/Core 54 | - SimpleAuth/Meetup (0.3.9): 55 | - SimpleAuth/Core 56 | - SimpleAuth/OneDriveWeb (0.3.9): 57 | - SimpleAuth/Core 58 | - SimpleAuth/SinaWeiboWeb (0.3.9): 59 | - SimpleAuth/Core 60 | - SimpleAuth/Strava (0.3.9): 61 | - SimpleAuth/Core 62 | - SimpleAuth/Trello (0.3.9): 63 | - SimpleAuth/Core 64 | - SimpleAuth/TripIt (0.3.9): 65 | - cocoa-oauth 66 | - SimpleAuth/Core 67 | - SimpleAuth/Tumblr (0.3.9): 68 | - cocoa-oauth 69 | - SimpleAuth/Core 70 | - SimpleAuth/Twitter (0.3.9): 71 | - cocoa-oauth 72 | - SimpleAuth/Core 73 | - SimpleAuth/TwitterWeb (0.3.9): 74 | - cocoa-oauth 75 | - SimpleAuth/Core 76 | - SimpleAuth/VKontakteWeb (0.3.9): 77 | - SimpleAuth/Core 78 | 79 | DEPENDENCIES: 80 | - SimpleAuth (from `..`) 81 | 82 | EXTERNAL SOURCES: 83 | SimpleAuth: 84 | :path: .. 85 | 86 | SPEC CHECKSUMS: 87 | CMDQueryStringSerialization: 03c5d9847a4eaa2b3e4e439ce1ae24f914cc7fe1 88 | cocoa-oauth: 1200a2170276a62a975f2786d505dab6e2db1fa8 89 | ISO8601: 8805b6cd6b2d0f7e594f7c5b50e8b00b51695ac0 90 | NSData+Base64: 4e84902c4db907a15673474677e57763ef3903e4 91 | ReactiveCocoa: e2db045570aa97c695e7aa97c2bcab222ae51f4a 92 | SimpleAuth: 84c0a98a8797f3b9400d699f3a2c7e3be5dde1ca 93 | 94 | COCOAPODS: 0.37.2 95 | -------------------------------------------------------------------------------- /Pod/Core/SimpleAuth.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuth.h 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/6/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | #import "SimpleAuthDefines.h" 11 | 12 | @interface SimpleAuth : NSObject 13 | 14 | /** 15 | Set options used to configure each provider. Things like access tokens and 16 | OAuth redirect URLs should be set here. Every provider should document the 17 | options that it accepts. These options override a provider's default options, 18 | and options passed to +authorize:options:completion: likewise override these. 19 | 20 | @return A mutable dictionary whose string keys correspond to provider types 21 | and values are dictionaries that are passed on to a provider during an 22 | authorization operation. 23 | 24 | @see +authorize:options:completion: 25 | */ 26 | + (NSMutableDictionary *)configuration; 27 | 28 | /** 29 | Perform authorization with the given provider and all previously configured 30 | and default provider options. 31 | 32 | @param completion Called on the main queue when the operation is complete. 33 | 34 | @see +authorize:options:completion: 35 | */ 36 | + (void)authorize:(NSString *)provider completion:(SimpleAuthRequestHandler)completion; 37 | 38 | /** 39 | Perform an authorization with the given provider. Options provided here will 40 | be applied on top of any configured or default provider options. 41 | 42 | @param completion Called on the main queue when the operation is complete. 43 | 44 | @see +configuration 45 | @see +authorize:completion: 46 | */ 47 | + (void)authorize:(NSString *)provider options:(NSDictionary *)options completion:(SimpleAuthRequestHandler)completion; 48 | 49 | /** 50 | Perform re-authorization with the given provider and all previously configured 51 | and default provider options. This is for providers where the token expires and you 52 | want to renew the non expired token. 53 | 54 | @param token the unexpired token recieved from the service 55 | @param completion Called on the main queue when the operation is complete. 56 | 57 | @see +authorize:options:completion: 58 | */ 59 | + (void)reAuthorize:(NSString *)provider token:(NSString *)token completion:(SimpleAuthRequestHandler)completion; 60 | 61 | /** 62 | Perform re-authorization with the given provider and all previously configured 63 | and default provider options. This is for providers where the token expires and you 64 | want to renew the non expired token. 65 | 66 | @param token the unexpired token recieved from the service 67 | @param completion Called on the main queue when the operation is complete. 68 | 69 | @see +authorize:options:completion: 70 | */ 71 | + (void)reAuthorize:(NSString *)type options:(NSDictionary *)options token:(NSString *)token completion:(SimpleAuthRequestHandler)completion; 72 | 73 | /** 74 | Determine whether the provider can handle the callback URL or not. 75 | 76 | @return A boolean specifying if the provider handles the specified URL. 77 | 78 | @param url The callback URL. 79 | */ 80 | + (BOOL)handleCallback:(NSURL *)url; 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /Example/SimpleAuth.xcodeproj/xcshareddata/xcschemes/SimpleAuth.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /Example/SimpleAuth/SADAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SADAppDelegate.m 3 | // SimpleAuthDemo 4 | // 5 | // Created by Caleb Davenport on 1/16/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SADAppDelegate.h" 10 | #import "SADProviderListViewController.h" 11 | 12 | #import 13 | 14 | @implementation SADAppDelegate 15 | 16 | @synthesize window = _window; 17 | 18 | #pragma mark - Accessors 19 | 20 | - (UIWindow *)window { 21 | if (!_window) { 22 | UIScreen *screen = [UIScreen mainScreen]; 23 | 24 | _window = [UIWindow new]; 25 | _window.screen = screen; 26 | _window.frame = screen.bounds; 27 | 28 | SADProviderListViewController *providers = [SADProviderListViewController new]; 29 | UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:providers]; 30 | _window.rootViewController = navigation; 31 | } 32 | return _window; 33 | } 34 | 35 | 36 | - (void)setWindow:(UIWindow *)window { 37 | // Do nothing 38 | } 39 | 40 | 41 | #pragma mark - Private 42 | 43 | - (void)configureAuthorizaionProviders { 44 | 45 | // consumer_key and consumer_secret are required 46 | SimpleAuth.configuration[@"twitter"] = @{}; 47 | SimpleAuth.configuration[@"twitter-web"] = @{}; 48 | 49 | // client_id and redirect_uri are required 50 | SimpleAuth.configuration[@"instagram"] = @{}; 51 | 52 | // app_id is required 53 | SimpleAuth.configuration[@"facebook"] = @{}; 54 | // app_secret optional required for re-authorization of token 55 | SimpleAuth.configuration[@"facebook-web"] = @{}; 56 | 57 | // client_id and redirect_uri are required 58 | SimpleAuth.configuration[@"meetup"] = @{}; 59 | 60 | // consumer_key and consumer_secret are required 61 | SimpleAuth.configuration[@"tumblr"] = @{}; 62 | 63 | // client_id and redirect_uri are required 64 | SimpleAuth.configuration[@"foursquare-web"] = @{}; 65 | 66 | // client_id and redirect_uri are required 67 | SimpleAuth.configuration[@"dropbox-web"] = @{}; 68 | 69 | // client_id, client_secret, and redirect_uri are required 70 | SimpleAuth.configuration[@"linkedin-web"] = @{}; 71 | 72 | // client_id, client_secret, and redirect_uri are required 73 | SimpleAuth.configuration[@"trello-web"] = @{}; 74 | 75 | // client_id and client_secret are required 76 | SimpleAuth.configuration[@"sinaweibo-web"] = @{}; 77 | 78 | // client_id and client_secret are required 79 | SimpleAuth.configuration[@"google-web"] = @{}; 80 | 81 | // client_id, client_secret and redirect_uri are required 82 | SimpleAuth.configuration[@"strava-web"] = @{}; 83 | 84 | // consumer_key and consumer_secret are required 85 | SimpleAuth.configuration[@"tripit"] = @{}; 86 | 87 | // client_id and client_secret are required 88 | SimpleAuth.configuration[@"box-web"] = @{}; 89 | 90 | // client_id and client_secret are required 91 | SimpleAuth.configuration[@"onedrive-web"] = @{}; 92 | 93 | // client_id is required 94 | SimpleAuth.configuration[@"vkontakte-web"] = @{}; 95 | } 96 | 97 | 98 | #pragma mark - UIApplicationDelegate 99 | 100 | - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 101 | [self configureAuthorizaionProviders]; 102 | [self.window makeKeyAndVisible]; 103 | return YES; 104 | } 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /Readme.markdown: -------------------------------------------------------------------------------- 1 | # SimpleAuth 2 | 3 | SimpleAuth is designed to do the hard work of social account login on iOS. It has a small set of public APIs backed by a set of "providers" that implement the functionality needed to communicate with various social services. 4 | 5 | SimpleAuth currently has the following providers: 6 | 7 | - [Twitter](https://github.com/calebd/SimpleAuth/wiki/Twitter) 8 | - [Facebook](https://github.com/calebd/SimpleAuth/wiki/Facebook) 9 | - [Instagram](https://github.com/calebd/SimpleAuth/wiki/Instagram) 10 | - [Tumblr](https://github.com/calebd/SimpleAuth/wiki/Tumblr) 11 | - [Dropbox](https://github.com/calebd/SimpleAuth/wiki/Dropbox) 12 | - [Foursquare](https://github.com/calebd/SimpleAuth/wiki/Foursquare) 13 | - [Meetup](https://github.com/calebd/SimpleAuth/wiki/Meetup) 14 | - [LinkedIn](https://github.com/calebd/SimpleAuth/wiki/LinkedIn) 15 | - [Sina Weibo](https://github.com/calebd/SimpleAuth/wiki/SinaWeibo) 16 | - [Google](https://github.com/calebd/SimpleAuth/wiki/Google) 17 | - [Box](https://github.com/calebd/SimpleAuth/wiki/Box) 18 | - [OneDrive](https://github.com/calebd/SimpleAuth/wiki/OneDrive) 19 | - [VKontakte](https://github.com/calebd/SimpleAuth/wiki/VKontakte) 20 | 21 | ## Installing 22 | 23 | Install SimpleAuth with CocoaPods. For example, to use Facebook and Twitter authentication, add 24 | 25 | ```ruby 26 | pod 'SimpleAuth/Facebook' 27 | pod 'SimpleAuth/Twitter' 28 | ``` 29 | 30 | to your `Podfile`. 31 | 32 | ## Usage 33 | 34 | Configuring and using SimpleAuth is easy: 35 | 36 | ````swift 37 | // Somewhere in your app boot process 38 | SimpleAuth.configuration()["twitter"] = [ 39 | "consumer_key": "KEY", 40 | "consumer_secret": "SECRET" 41 | ] 42 | ```` 43 | 44 | ````swift 45 | // Authorize 46 | func loginWithTwitter() { 47 | SimpleAuth.authorize("twitter", completion: { responseObject, error in 48 | println("Twitter login response: \(responseObject)") 49 | }) 50 | } 51 | ```` 52 | 53 | ## Implementing a Provider 54 | 55 | The API for creating providers is pretty simple. Be sure to look at `SimpleAuthProvider` and `SimpleAuthWebLoginViewController`. These classes will help you simplify your authentiction process. Providers should be stored in `Pod/Providers/` and have an appropriately named folder and sub spec. All providers are automatically registered with the framework. There are a handful of methods you'll need to implement: 56 | 57 | Let SimpleAuth know what type of provider you are registering: 58 | 59 | ````objc 60 | + (NSString *)type { 61 | return @"facebook"; 62 | } 63 | ```` 64 | 65 | Optionally, you may return a set of default options for all authorization options to use: 66 | 67 | ````objc 68 | + (NSDictionary *)defaultOptions { 69 | return @{ 70 | @"permissions" : @[ @"email" ] 71 | }; 72 | } 73 | ```` 74 | 75 | Finally, provide a method for handling authorization: 76 | 77 | ````objc 78 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 79 | // Use values in self.options to customize behavior 80 | // Perform authentication 81 | // Call the completion 82 | } 83 | ```` 84 | 85 | The rest is up to you! I welcome contributions to SimpleAuth, both improvements to the library itself and new providers. 86 | 87 | ## License 88 | 89 | SimpleAuth is released under the MIT license. 90 | 91 | ## Thanks 92 | 93 | Special thanks to my friend [@soffes](https://twitter.com/soffes) for advising on the SimpleAuth API design. 94 | 95 | ### Contributors 96 | 97 | - [kornifex](https://github.com/kornifex): Foursquare provider 98 | - [mouhcine](https://github.com/mouhcine): Meetup provider 99 | - [iamabhiee](https://github.com/iamabhiee): LinkedIn provider 100 | - [aschuch](https://github.com/aschuch): Sina Weibo provider 101 | - [Mikhail_Kupriyanov](https://github.com/MikhailKupriyanov): VKontakte provider 102 | -------------------------------------------------------------------------------- /Pod/Core/ios/SimpleAuthWebViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthWebViewController.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/7/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthWebViewController.h" 10 | 11 | @interface SimpleAuthWebViewController () 12 | 13 | @property (nonatomic, copy) NSDictionary *options; 14 | @property (nonatomic, copy) NSDictionary *requestToken; 15 | 16 | @end 17 | 18 | @implementation SimpleAuthWebViewController { 19 | BOOL _hasInitialLoad; 20 | } 21 | 22 | @synthesize webView = _webView; 23 | 24 | #pragma mark - UIViewController 25 | 26 | - (void)viewDidLoad { 27 | [super viewDidLoad]; 28 | 29 | self.webView.frame = self.view.bounds; 30 | [self.view addSubview:self.webView]; 31 | } 32 | 33 | 34 | - (void)viewDidAppear:(BOOL)animated { 35 | [super viewDidAppear:animated]; 36 | 37 | if (!_hasInitialLoad) { 38 | _hasInitialLoad = YES; 39 | NSURLRequest *request = [self initialRequest]; 40 | request = [[self class] canonicalRequestForRequest:request]; 41 | [self.webView loadRequest:request]; 42 | } 43 | } 44 | 45 | 46 | #pragma mark - Public 47 | 48 | - (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken { 49 | if ((self = [super init])) { 50 | self.options = options; 51 | self.requestToken = requestToken; 52 | self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] 53 | initWithBarButtonSystemItem:UIBarButtonSystemItemCancel 54 | target:self 55 | action:@selector(cancel)]; 56 | } 57 | return self; 58 | } 59 | 60 | 61 | - (instancetype)initWithOptions:(NSDictionary *)options { 62 | self = [self initWithOptions:options requestToken:nil]; 63 | return self; 64 | } 65 | 66 | 67 | - (BOOL)isTargetRedirectURL:(NSURL *)URL { 68 | NSString *targetURLString = [self.options[SimpleAuthRedirectURIKey] lowercaseString]; 69 | NSString *actualURLString = [[URL absoluteString] lowercaseString]; 70 | return [actualURLString hasPrefix:targetURLString]; 71 | } 72 | 73 | 74 | - (id)responseObjectFromRedirectURL:(NSURL *)URL { 75 | return nil; 76 | } 77 | 78 | 79 | - (void)cancel { 80 | NSError *error = [NSError errorWithDomain:SimpleAuthErrorDomain code:SimpleAuthErrorUserCancelled userInfo:nil]; 81 | self.completion(self, nil, error); 82 | } 83 | 84 | 85 | - (NSURLRequest *)initialRequest { 86 | [self doesNotRecognizeSelector:_cmd]; 87 | return nil; 88 | } 89 | 90 | 91 | #pragma mark - Private 92 | 93 | + (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request { 94 | NSMutableURLRequest *mutableRequest = [request mutableCopy]; 95 | [mutableRequest setCachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData]; 96 | return mutableRequest; 97 | } 98 | 99 | 100 | #pragma mark - Accessors 101 | 102 | - (UIWebView *)webView { 103 | if (!_webView) { 104 | _webView = [UIWebView new]; 105 | _webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); 106 | _webView.delegate = self; 107 | } 108 | return _webView; 109 | } 110 | 111 | 112 | #pragma mark - UIWebViewDelegate 113 | 114 | - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { 115 | webView.delegate = nil; 116 | self.completion(self, nil, error); 117 | } 118 | 119 | 120 | - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)type { 121 | NSURL *URL = [request URL]; 122 | if ([self isTargetRedirectURL:URL]) { 123 | webView.delegate = nil; 124 | self.completion(self, URL, nil); 125 | return NO; 126 | } 127 | return YES; 128 | } 129 | 130 | @end 131 | -------------------------------------------------------------------------------- /SimpleAuth.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'SimpleAuth' 3 | s.version = '0.3.9' 4 | s.summary = 'Simple social authentication for iOS.' 5 | s.homepage = 'https://github.com/calebd/SimpleAuth' 6 | s.license = { :type => 'MIT', :file => 'LICENSE' } 7 | s.author = { 'Caleb Davenport' => 'calebmdavenport@gmail.com' } 8 | s.source = { :git => 'https://github.com/calebd/SimpleAuth.git', :tag => "v#{s.version}" } 9 | s.requires_arc = true 10 | s.platform = :ios, '6.0' 11 | 12 | s.subspec 'Core' do |ss| 13 | ss.source_files = 'Pod/Core' 14 | ss.public_header_files = 'Pod/Core/SimpleAuth.h', 'Pod/Core/SimpleAuthDefines.h' 15 | ss.dependency 'ReactiveCocoa', '~>2.5' 16 | ss.dependency 'CMDQueryStringSerialization' 17 | 18 | ss.ios.frameworks = 'UIKit' 19 | ss.ios.source_files = 'Pod/Core/ios' 20 | ss.ios.resource_bundle = { 'SimpleAuth' => [ 'Pod/Resources/*.lproj' ] } 21 | end 22 | 23 | s.subspec 'Twitter' do |ss| 24 | ss.dependency 'SimpleAuth/Core' 25 | ss.dependency 'cocoa-oauth' 26 | ss.frameworks = 'Accounts', 'Social' 27 | ss.source_files = 'Pod/Providers/Twitter' 28 | ss.private_header_files = 'Pod/Providers/Twitter/*.h' 29 | end 30 | 31 | s.subspec 'Facebook' do |ss| 32 | ss.dependency 'SimpleAuth/Core' 33 | ss.frameworks = 'Accounts', 'Social' 34 | ss.source_files = 'Pod/Providers/Facebook' 35 | ss.private_header_files = 'Pod/Providers/Facebook/*.h' 36 | end 37 | 38 | s.subspec 'FacebookWeb' do |ss| 39 | ss.dependency 'SimpleAuth/Core' 40 | ss.source_files = 'Pod/Providers/FacebookWeb' 41 | ss.private_header_files = 'Pod/Providers/FacebookWeb/*.h' 42 | end 43 | 44 | s.subspec 'Instagram' do |ss| 45 | ss.dependency 'SimpleAuth/Core' 46 | ss.source_files = 'Pod/Providers/Instagram' 47 | ss.private_header_files = 'Pod/Providers/Instagram/*.h' 48 | end 49 | 50 | s.subspec 'TwitterWeb' do |ss| 51 | ss.dependency 'SimpleAuth/Core' 52 | ss.dependency 'cocoa-oauth' 53 | ss.source_files = 'Pod/Providers/TwitterWeb' 54 | ss.private_header_files = 'Pod/Providers/TwitterWeb/*.h' 55 | end 56 | 57 | s.subspec 'Meetup' do |ss| 58 | ss.dependency 'SimpleAuth/Core' 59 | ss.source_files = 'Pod/Providers/Meetup' 60 | ss.private_header_files = 'Pod/Providers/Meetup/*.h' 61 | end 62 | 63 | s.subspec 'Tumblr' do |ss| 64 | ss.dependency 'SimpleAuth/Core' 65 | ss.dependency 'cocoa-oauth' 66 | ss.source_files = 'Pod/Providers/Tumblr' 67 | ss.private_header_files = 'Pod/Providers/Tumblr/*.h' 68 | end 69 | 70 | s.subspec 'FoursquareWeb' do |ss| 71 | ss.dependency 'SimpleAuth/Core' 72 | ss.source_files = 'Pod/Providers/FoursquareWeb' 73 | ss.private_header_files = 'Pod/Providers/FoursquareWeb/*.h' 74 | end 75 | 76 | s.subspec 'DropboxWeb' do |ss| 77 | ss.dependency 'SimpleAuth/Core' 78 | ss.source_files = 'Pod/Providers/DropboxWeb' 79 | ss.private_header_files = 'Pod/Providers/DropboxWeb/*.h' 80 | end 81 | 82 | s.subspec 'LinkedInWeb' do |ss| 83 | ss.dependency 'SimpleAuth/Core' 84 | ss.source_files = 'Pod/Providers/LinkedIn' 85 | ss.private_header_files = 'Pod/Providers/LinkedIn/*.h' 86 | end 87 | 88 | s.subspec 'SinaWeiboWeb' do |ss| 89 | ss.dependency 'SimpleAuth/Core' 90 | ss.source_files = 'Pod/Providers/SinaWeiboWeb' 91 | ss.private_header_files = 'Pod/Providers/SinaWeiboWeb/*.h' 92 | end 93 | 94 | s.subspec 'GoogleWeb' do |ss| 95 | ss.dependency 'SimpleAuth/Core' 96 | ss.source_files = 'Pod/Providers/GoogleWeb' 97 | ss.private_header_files = 'Pod/Providers/GoogleWeb/*.h' 98 | end 99 | 100 | s.subspec 'TripIt' do |ss| 101 | ss.dependency 'SimpleAuth/Core' 102 | ss.dependency 'cocoa-oauth' 103 | ss.source_files = 'Pod/Providers/TripIt' 104 | ss.private_header_files = 'Pod/Providers/TripIt/*.h' 105 | end 106 | 107 | s.subspec 'Trello' do |ss| 108 | ss.dependency 'SimpleAuth/Core' 109 | ss.source_files = 'Pod/Providers/Trello' 110 | ss.private_header_files = 'Pod/Providers/Trello/*.h' 111 | end 112 | 113 | s.subspec 'Strava' do |ss| 114 | ss.dependency 'SimpleAuth/Core' 115 | ss.source_files = 'Pod/Providers/Strava' 116 | ss.private_header_files = 'Pod/Providers/Strava/*.h' 117 | end 118 | 119 | s.subspec 'BoxWeb' do |ss| 120 | ss.dependency 'SimpleAuth/Core' 121 | ss.source_files = 'Pod/Providers/BoxWeb' 122 | ss.private_header_files = 'Pod/Providers/BoxWeb/*.h' 123 | end 124 | 125 | s.subspec 'OneDriveWeb' do |ss| 126 | ss.dependency 'SimpleAuth/Core' 127 | ss.source_files = 'Pod/Providers/OneDriveWeb' 128 | ss.private_header_files = 'Pod/Providers/OneDriveWeb/*.h' 129 | end 130 | 131 | s.subspec 'VKontakteWeb' do |ss| 132 | ss.dependency 'SimpleAuth/Core' 133 | ss.source_files = 'Pod/Providers/VKontakteWeb' 134 | ss.private_header_files = 'Pod/Providers/VKontakteWeb/*.h' 135 | end 136 | 137 | end 138 | -------------------------------------------------------------------------------- /Pod/Core/SimpleAuth.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuth.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/6/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuth.h" 10 | #import "SimpleAuthProvider.h" 11 | #import "SimpleAuthSingleSignOnProvider.h" 12 | #import "NSObject+SimpleAuthAdditions.h" 13 | 14 | static SimpleAuthProvider *__currentProvider = nil; 15 | 16 | @implementation SimpleAuth 17 | 18 | #pragma mark - NSObject 19 | 20 | + (void)initialize { 21 | [self loadProviders]; 22 | } 23 | 24 | 25 | #pragma mark - Public 26 | 27 | + (NSMutableDictionary *)configuration { 28 | static dispatch_once_t token; 29 | static NSMutableDictionary *configuration; 30 | dispatch_once(&token, ^{ 31 | configuration = [NSMutableDictionary new]; 32 | }); 33 | return configuration; 34 | } 35 | 36 | 37 | + (void)authorize:(NSString *)type completion:(SimpleAuthRequestHandler)completion { 38 | [self authorize:type options:nil completion:completion]; 39 | } 40 | 41 | 42 | + (void)authorize:(NSString *)type options:(NSDictionary *)options completion:(SimpleAuthRequestHandler)completion { 43 | 44 | // Load the provider class 45 | Class klass = [self providers][type]; 46 | NSAssert(klass, @"There is no class registered to handle %@ requests.", type); 47 | 48 | // Create options dictionary 49 | NSDictionary *defaultOptions = [klass defaultOptions]; 50 | NSDictionary *registeredOptions = [self configuration][type]; 51 | NSMutableDictionary *resolvedOptions = [NSMutableDictionary new]; 52 | [resolvedOptions addEntriesFromDictionary:defaultOptions]; 53 | [resolvedOptions addEntriesFromDictionary:registeredOptions]; 54 | [resolvedOptions addEntriesFromDictionary:options]; 55 | 56 | // Create the provider and run authorization 57 | __currentProvider = [(SimpleAuthProvider *)[klass alloc] initWithOptions:resolvedOptions]; 58 | [__currentProvider authorizeWithCompletion:^(id responseObject, NSError *error) { 59 | dispatch_async(dispatch_get_main_queue(), ^{ 60 | completion(responseObject, error); 61 | }); 62 | }]; 63 | } 64 | 65 | + (void)reAuthorize:(NSString *)type token:(NSString *)token completion:(SimpleAuthRequestHandler)completion { 66 | [self reAuthorize:type options:nil token:token completion:completion]; 67 | } 68 | 69 | 70 | + (void)reAuthorize:(NSString *)type options:(NSDictionary *)options token:(NSString *)token completion:(SimpleAuthRequestHandler)completion{ 71 | // Load the provider class 72 | Class klass = [self providers][type]; 73 | NSAssert(klass, @"There is no class registered to handle %@ requests.", type); 74 | 75 | // Create options dictionary 76 | NSDictionary *defaultOptions = [klass defaultOptions]; 77 | NSDictionary *registeredOptions = [self configuration][type]; 78 | NSMutableDictionary *resolvedOptions = [NSMutableDictionary new]; 79 | [resolvedOptions addEntriesFromDictionary:defaultOptions]; 80 | [resolvedOptions addEntriesFromDictionary:registeredOptions]; 81 | [resolvedOptions addEntriesFromDictionary:options]; 82 | 83 | // Create the provider and run authorization 84 | SimpleAuthProvider *provider = [(SimpleAuthProvider *)[klass alloc] initWithOptions:resolvedOptions]; 85 | [provider reAuthorizeWithToken:token completionHandler:^(id responseObject, NSError *error) { 86 | dispatch_async(dispatch_get_main_queue(), ^{ 87 | completion(responseObject, error); 88 | }); 89 | [provider class]; // Kepp the provider around until the callback is complete 90 | }]; 91 | } 92 | 93 | + (BOOL)handleCallback:(NSURL *)URL { 94 | NSParameterAssert(URL != nil); 95 | 96 | NSAssert(__currentProvider != nil, @"There is no provider waiting for single sign on callback."); 97 | NSAssert([__currentProvider conformsToProtocol:@protocol(SimpleAuthSingleSignOnProvider)], @"The current provider does not handle single sign on."); 98 | 99 | return [(id)__currentProvider handleCallback:URL]; 100 | } 101 | 102 | 103 | #pragma mark - Internal 104 | 105 | + (void)registerProviderClass:(Class)klass { 106 | NSMutableDictionary *providers = [self providers]; 107 | NSString *type = [klass type]; 108 | if (providers[type]) { 109 | NSLog(@"[SimpleAuth] Warning: multiple attempts to register provider for type: %@", type); 110 | return; 111 | } 112 | providers[type] = klass; 113 | } 114 | 115 | 116 | #pragma mark - Private 117 | 118 | + (NSMutableDictionary *)providers { 119 | static dispatch_once_t token; 120 | static NSMutableDictionary *providers; 121 | dispatch_once(&token, ^{ 122 | providers = [NSMutableDictionary new]; 123 | }); 124 | return providers; 125 | } 126 | 127 | 128 | + (void)loadProviders { 129 | [SimpleAuthProvider SimpleAuth_enumerateSubclassesWithBlock:^(Class klass, BOOL *stop) { 130 | [self registerProviderClass:klass]; 131 | }]; 132 | } 133 | 134 | @end 135 | -------------------------------------------------------------------------------- /Pod/Providers/Meetup/SimpleAuthMeetupProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthMeetupProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by Mouhcine El Amine on 17/01/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthMeetupProvider.h" 10 | #import "SimpleAuthMeetupLoginViewController.h" 11 | 12 | #import "UIViewController+SimpleAuthAdditions.h" 13 | 14 | @implementation SimpleAuthMeetupProvider 15 | 16 | #pragma mark - SimpleAuthProvider 17 | 18 | + (NSString *)type { 19 | return @"meetup"; 20 | } 21 | 22 | + (NSDictionary *)defaultOptions { 23 | 24 | // Default present block 25 | SimpleAuthInterfaceHandler presentBlock = ^(UIViewController *controller) { 26 | UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller]; 27 | navigationController.modalPresentationStyle = UIModalPresentationFormSheet; 28 | UIViewController *presentedViewController = [UIViewController SimpleAuth_presentedViewController]; 29 | [presentedViewController presentViewController:navigationController 30 | animated:YES 31 | completion:nil]; 32 | }; 33 | 34 | // Default dismiss block 35 | SimpleAuthInterfaceHandler dismissBlock = ^(id viewController) { 36 | [viewController dismissViewControllerAnimated:YES 37 | completion:nil]; 38 | }; 39 | 40 | NSMutableDictionary *options = [NSMutableDictionary dictionaryWithDictionary:[super defaultOptions]]; 41 | options[SimpleAuthPresentInterfaceBlockKey] = presentBlock; 42 | options[SimpleAuthDismissInterfaceBlockKey] = dismissBlock; 43 | return options; 44 | } 45 | 46 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 47 | dispatch_async(dispatch_get_main_queue(), ^{ 48 | SimpleAuthMeetupLoginViewController *loginViewController = [[SimpleAuthMeetupLoginViewController alloc] initWithOptions:self.options]; 49 | loginViewController.completion = ^(UIViewController *viewController, NSURL *URL, NSError *error) { 50 | SimpleAuthInterfaceHandler dismissBlock = self.options[SimpleAuthDismissInterfaceBlockKey]; 51 | dismissBlock(viewController); 52 | 53 | NSString *fragment = [URL fragment]; 54 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:fragment]; 55 | NSString *token = dictionary[@"access_token"]; 56 | if ([token length] > 0) { 57 | NSDictionary *credentials = @{@"token": token, 58 | @"type" : @"bearer", 59 | @"expireDate" : [NSDate dateWithTimeIntervalSinceNow:[dictionary[@"expires_in"] doubleValue]]}; 60 | [self userWithCredentials:credentials 61 | completion:completion]; 62 | } else { 63 | completion(nil, error); 64 | } 65 | }; 66 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthPresentInterfaceBlockKey]; 67 | block(loginViewController); 68 | }); 69 | } 70 | 71 | #pragma mark - Private 72 | 73 | - (void)userWithCredentials:(NSDictionary *)credentials completion:(SimpleAuthRequestHandler)completion { 74 | NSDictionary *parameters = @{ @"member_id" : @"self" }; 75 | NSString *query = [CMDQueryStringSerialization queryStringWithDictionary:parameters]; 76 | NSString *URLString = [NSString stringWithFormat:@"https://api.meetup.com/2/members?%@", query]; 77 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URLString]]; 78 | [request setValue:[NSString stringWithFormat:@"Bearer %@", credentials[@"token"]] forHTTPHeaderField:@"Authorization"]; 79 | [NSURLConnection sendAsynchronousRequest:request 80 | queue:self.operationQueue 81 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 82 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 83 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 84 | if ([indexSet containsIndex:statusCode] && data) { 85 | NSError *parseError; 86 | NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data 87 | options:kNilOptions 88 | error:&parseError]; 89 | if (responseDictionary) { 90 | NSDictionary *rawInfo = [responseDictionary[@"results"] firstObject]; 91 | completion ([self dictionaryWithAccount:rawInfo credentials:credentials], nil); 92 | } else { 93 | completion(nil, parseError); 94 | } 95 | } else { 96 | completion(nil, connectionError); 97 | } 98 | }]; 99 | } 100 | 101 | - (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account 102 | credentials:(NSDictionary *)credentials 103 | { 104 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 105 | dictionary[@"provider"] = [[self class] type]; 106 | dictionary[@"credentials"] = [NSDictionary dictionaryWithDictionary:credentials]; 107 | dictionary[@"uid"] = account[@"id"]; 108 | dictionary[@"raw_info"] = account; 109 | NSMutableDictionary *user = [NSMutableDictionary dictionary]; 110 | user[@"name"] = account[@"name"]; 111 | NSDictionary *photoDictionary = account[@"photo"]; 112 | if (photoDictionary) { 113 | user[@"image"] = photoDictionary[@"photo_link"]; 114 | } 115 | return dictionary; 116 | } 117 | 118 | @end 119 | -------------------------------------------------------------------------------- /Pod/Providers/Instagram/SimpleAuthInstagramProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthInstagramProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/7/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthInstagramProvider.h" 10 | #import "SimpleAuthInstagramLoginViewController.h" 11 | 12 | #import "UIViewController+SimpleAuthAdditions.h" 13 | #import 14 | 15 | @implementation SimpleAuthInstagramProvider 16 | 17 | #pragma mark - SimpleAuthProvider 18 | 19 | + (NSString *)type { 20 | return @"instagram"; 21 | } 22 | 23 | 24 | + (NSDictionary *)defaultOptions { 25 | 26 | // Default present block 27 | SimpleAuthInterfaceHandler presentBlock = ^(UIViewController *controller) { 28 | UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller]; 29 | navigation.modalPresentationStyle = UIModalPresentationFormSheet; 30 | UIViewController *presented = [UIViewController SimpleAuth_presentedViewController]; 31 | [presented presentViewController:navigation animated:YES completion:nil]; 32 | }; 33 | 34 | // Default dismiss block 35 | SimpleAuthInterfaceHandler dismissBlock = ^(id controller) { 36 | [controller dismissViewControllerAnimated:YES completion:nil]; 37 | }; 38 | 39 | NSMutableDictionary *options = [NSMutableDictionary dictionaryWithDictionary:[super defaultOptions]]; 40 | options[SimpleAuthPresentInterfaceBlockKey] = presentBlock; 41 | options[SimpleAuthDismissInterfaceBlockKey] = dismissBlock; 42 | return options; 43 | } 44 | 45 | 46 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 47 | [[[self accessToken] 48 | flattenMap:^RACStream *(NSString *response) { 49 | NSArray *signals = @[ 50 | [self accountWithAccessToken:response], 51 | [RACSignal return:response] 52 | ]; 53 | return [self rac_liftSelector:@selector(dictionaryWithAccount:accessToken:) withSignalsFromArray:signals]; 54 | }] 55 | subscribeNext:^(NSDictionary *response) { 56 | completion(response, nil); 57 | } 58 | error:^(NSError *error) { 59 | completion(nil, error); 60 | }]; 61 | } 62 | 63 | 64 | #pragma mark - Private 65 | 66 | - (RACSignal *)accessToken { 67 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 68 | dispatch_async(dispatch_get_main_queue(), ^{ 69 | SimpleAuthInstagramLoginViewController *login = [[SimpleAuthInstagramLoginViewController alloc] initWithOptions:self.options]; 70 | login.completion = ^(UIViewController *login, NSURL *URL, NSError *error) { 71 | SimpleAuthInterfaceHandler dismissBlock = self.options[SimpleAuthDismissInterfaceBlockKey]; 72 | dismissBlock(login); 73 | 74 | // Parse URL 75 | NSString *fragment = [URL fragment]; 76 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:fragment]; 77 | NSString *token = dictionary[@"access_token"]; 78 | 79 | // Check for error 80 | if (![token length]) { 81 | [subscriber sendError:error]; 82 | return; 83 | } 84 | 85 | // Send completion 86 | [subscriber sendNext:token]; 87 | [subscriber sendCompleted]; 88 | }; 89 | 90 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthPresentInterfaceBlockKey]; 91 | block(login); 92 | }); 93 | return nil; 94 | }]; 95 | } 96 | 97 | 98 | - (RACSignal *)accountWithAccessToken:(NSString *)accessToken { 99 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 100 | NSDictionary *parameters = @{ @"access_token" : accessToken }; 101 | NSString *query = [CMDQueryStringSerialization queryStringWithDictionary:parameters]; 102 | NSString *URLString = [NSString stringWithFormat:@"https://api.instagram.com/v1/users/self?%@", query]; 103 | NSURL *URL = [NSURL URLWithString:URLString]; 104 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 105 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 106 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 107 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 108 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 109 | if ([indexSet containsIndex:statusCode] && data) { 110 | NSError *parseError = nil; 111 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 112 | if (dictionary) { 113 | [subscriber sendNext:dictionary]; 114 | [subscriber sendCompleted]; 115 | } 116 | else { 117 | [subscriber sendError:parseError]; 118 | } 119 | } 120 | else { 121 | [subscriber sendError:connectionError]; 122 | } 123 | }]; 124 | return nil; 125 | }]; 126 | } 127 | 128 | 129 | #pragma mark - Private 130 | 131 | - (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account accessToken:(NSString *)accessToken { 132 | NSMutableDictionary *dictionary = [NSMutableDictionary new]; 133 | NSDictionary *data = account[@"data"]; 134 | 135 | // Provider 136 | dictionary[@"provider"] = [[self class] type]; 137 | 138 | // Credentials 139 | dictionary[@"credentials"] = @{ 140 | @"token" : accessToken 141 | }; 142 | 143 | // User ID 144 | dictionary[@"uid"] = data[@"id"]; 145 | 146 | // Extra 147 | dictionary[@"extra"] = @{ 148 | @"raw_info" : account 149 | }; 150 | 151 | // User info 152 | NSMutableDictionary *user = [NSMutableDictionary new]; 153 | user[@"name"] = data[@"full_name"]; 154 | user[@"username"] = data[@"username"]; 155 | user[@"image"] = data[@"profile_picture"]; 156 | dictionary[@"user_info"] = user; 157 | 158 | return dictionary; 159 | } 160 | 161 | @end 162 | -------------------------------------------------------------------------------- /Pod/Providers/DropboxWeb/SimpleAuthDropboxWebProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthDropboxWebProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/23/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthDropboxWebProvider.h" 10 | #import "SimpleAuthDropboxWebLoginViewController.h" 11 | 12 | #import 13 | #import "UIViewController+SimpleAuthAdditions.h" 14 | 15 | @implementation SimpleAuthDropboxWebProvider 16 | 17 | #pragma mark - SimpleAuthProvider 18 | 19 | + (NSString *)type { 20 | return @"dropbox-web"; 21 | } 22 | 23 | 24 | + (NSDictionary *)defaultOptions { 25 | 26 | // Default present block 27 | SimpleAuthInterfaceHandler presentBlock = ^(UIViewController *controller) { 28 | UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller]; 29 | navigation.modalPresentationStyle = UIModalPresentationFormSheet; 30 | UIViewController *presented = [UIViewController SimpleAuth_presentedViewController]; 31 | [presented presentViewController:navigation animated:YES completion:nil]; 32 | }; 33 | 34 | // Default dismiss block 35 | SimpleAuthInterfaceHandler dismissBlock = ^(id controller) { 36 | [controller dismissViewControllerAnimated:YES completion:nil]; 37 | }; 38 | 39 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithDictionary:[super defaultOptions]]; 40 | dictionary[SimpleAuthPresentInterfaceBlockKey] = presentBlock; 41 | dictionary[SimpleAuthDismissInterfaceBlockKey] = dismissBlock; 42 | return dictionary; 43 | } 44 | 45 | 46 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 47 | [[[self accessToken] 48 | flattenMap:^(NSDictionary *response) { 49 | NSArray *signals = @[ 50 | [self accountWithAccessToken:response], 51 | [RACSignal return:response] 52 | ]; 53 | return [self rac_liftSelector:@selector(dictionaryWithAccount:accessToken:) withSignalsFromArray:signals]; 54 | }] 55 | subscribeNext:^(NSDictionary *response) { 56 | completion(response, nil); 57 | } 58 | error:^(NSError *error) { 59 | completion(nil, error); 60 | }]; 61 | } 62 | 63 | 64 | #pragma mark - Private 65 | 66 | - (RACSignal *)accessToken { 67 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 68 | dispatch_async(dispatch_get_main_queue(), ^{ 69 | SimpleAuthDropboxWebLoginViewController *login = [[SimpleAuthDropboxWebLoginViewController alloc] initWithOptions:self.options]; 70 | 71 | login.completion = ^(UIViewController *controller, NSURL *URL, NSError *error) { 72 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthDismissInterfaceBlockKey]; 73 | block(controller); 74 | 75 | // Parse URL 76 | NSString *fragment = [URL fragment]; 77 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:fragment]; 78 | id token = dictionary[@"access_token"]; 79 | 80 | // Check for error 81 | if (!token) { 82 | [subscriber sendError:error]; 83 | return; 84 | } 85 | 86 | // Send completion 87 | [subscriber sendNext:dictionary]; 88 | [subscriber sendCompleted]; 89 | }; 90 | 91 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthPresentInterfaceBlockKey]; 92 | block(login); 93 | }); 94 | return nil; 95 | }]; 96 | } 97 | 98 | 99 | - (RACSignal *)accountWithAccessToken:(NSDictionary *)accessToken { 100 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 101 | NSDictionary *parameters = @{ @"access_token" : accessToken[@"access_token"] }; 102 | NSString *URLString = [NSString stringWithFormat: 103 | @"https://api.dropbox.com/1/account/info?%@", 104 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 105 | NSURL *URL = [NSURL URLWithString:URLString]; 106 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 107 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 108 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 109 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 110 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 111 | if ([indexSet containsIndex:statusCode] && data) { 112 | NSError *parseError = nil; 113 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 114 | if (dictionary) { 115 | [subscriber sendNext:dictionary]; 116 | [subscriber sendCompleted]; 117 | } 118 | else { 119 | [subscriber sendError:parseError]; 120 | } 121 | } 122 | else { 123 | [subscriber sendError:connectionError]; 124 | } 125 | }]; 126 | return nil; 127 | }]; 128 | } 129 | 130 | 131 | - (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account accessToken:(NSDictionary *)accessToken { 132 | NSMutableDictionary *dictionary = [NSMutableDictionary new]; 133 | 134 | // Provider 135 | dictionary[@"provider"] = [[self class] type]; 136 | 137 | // Credentials 138 | dictionary[@"credentials"] = @{ 139 | @"token" : accessToken[@"access_token"], 140 | @"type" : accessToken[@"token_type"] 141 | }; 142 | 143 | // User ID 144 | dictionary[@"uid"] = account[@"uid"]; 145 | 146 | // Raw response 147 | dictionary[@"extra"] = @{ 148 | @"raw_info" : account 149 | }; 150 | 151 | // User info 152 | NSMutableDictionary *user = [NSMutableDictionary new]; 153 | user[@"email"] = account[@"email"]; 154 | user[@"name"] = account[@"display_name"]; 155 | dictionary[@"info"] = user; 156 | 157 | return dictionary; 158 | } 159 | 160 | @end 161 | -------------------------------------------------------------------------------- /Pod/Providers/Facebook/SimpleAuthFacebookProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthFacebookProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 11/6/13. 6 | // Copyright (c) 2013-2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthFacebookProvider.h" 10 | #import "ACAccountStore+SimpleAuth.h" 11 | #import 12 | @import Social; 13 | 14 | @implementation SimpleAuthFacebookProvider 15 | 16 | #pragma mark - SimpleAuthProvider 17 | 18 | + (NSString *)type { 19 | return @"facebook"; 20 | } 21 | 22 | + (NSDictionary *)defaultOptions { 23 | return @{ 24 | @"permissions" : @[ @"email" ], 25 | @"audience" : @[ ACFacebookAudienceOnlyMe ] 26 | }; 27 | } 28 | 29 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 30 | [[[[self systemAccount] 31 | flattenMap:^RACStream *(ACAccount *account) { 32 | NSArray *signals = @[ 33 | [self remoteAccountWithSystemAccount:account], 34 | [RACSignal return:account] 35 | ]; 36 | return [self rac_liftSelector:@selector(responseDictionaryWithRemoteAccount:systemAccount:) withSignalsFromArray:signals]; 37 | }] 38 | deliverOn:[RACScheduler mainThreadScheduler]] 39 | subscribeNext:^(NSDictionary *response) { 40 | completion(response, nil); 41 | } 42 | error:^(NSError *error) { 43 | completion(nil, error); 44 | }]; 45 | } 46 | 47 | 48 | #pragma mark - Private 49 | 50 | - (RACSignal *)allSystemAccounts { 51 | NSDictionary *options = @{ 52 | ACFacebookAppIdKey : self.options[@"app_id"], 53 | ACFacebookPermissionsKey : self.options[@"permissions"], 54 | ACFacebookAudienceKey: self.options[@"audience"] 55 | }; 56 | return [ACAccountStore SimpleAuth_accountsWithTypeIdentifier:ACAccountTypeIdentifierFacebook options:options]; 57 | } 58 | 59 | - (RACSignal *)systemAccount { 60 | return [[self allSystemAccounts] map:^(NSArray *accounts) { 61 | return [accounts lastObject]; 62 | }]; 63 | } 64 | 65 | - (RACSignal *)remoteAccountWithSystemAccount:(ACAccount *)account { 66 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 67 | NSURL *URL = [NSURL URLWithString:@"https://graph.facebook.com/me"]; 68 | NSDictionary *parameters = @{ 69 | @"fields" : @"name,first_name,last_name,verified,email,location,link" 70 | }; 71 | SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:URL parameters:parameters]; 72 | request.account = account; 73 | [request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *connectionError) { 74 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 75 | NSInteger statusCode = [response statusCode]; 76 | if ([indexSet containsIndex:statusCode] && data) { 77 | NSError *parseError = nil; 78 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 79 | if (dictionary) { 80 | [subscriber sendNext:dictionary]; 81 | [subscriber sendCompleted]; 82 | } 83 | else { 84 | NSMutableDictionary *dictionary = [NSMutableDictionary new]; 85 | if (parseError) { 86 | dictionary[NSUnderlyingErrorKey] = parseError; 87 | } 88 | NSError *error = [NSError errorWithDomain:SimpleAuthErrorDomain code:SimpleAuthErrorInvalidData userInfo:dictionary]; 89 | [subscriber sendNext:error]; 90 | } 91 | } 92 | else { 93 | NSMutableDictionary *dictionary = [NSMutableDictionary new]; 94 | if (connectionError) { 95 | dictionary[NSUnderlyingErrorKey] = connectionError; 96 | } 97 | dictionary[SimpleAuthErrorStatusCodeKey] = @(statusCode); 98 | NSError *error = [NSError errorWithDomain:SimpleAuthErrorDomain code:SimpleAuthErrorNetwork userInfo:dictionary]; 99 | [subscriber sendError:error]; 100 | } 101 | }]; 102 | return nil; 103 | }]; 104 | } 105 | 106 | - (NSDictionary *)responseDictionaryWithRemoteAccount:(NSDictionary *)remoteAccount systemAccount:(ACAccount *)systemAccount { 107 | return @{ 108 | @"provider": [[self class] type], 109 | @"credentials": [self credentialsDictionaryWithRemoteAccount:remoteAccount systemAccount:systemAccount], 110 | @"uid": remoteAccount[@"id"], 111 | @"extra": [self extraDictionaryWithRemoteAccount:remoteAccount systemAccount:systemAccount], 112 | @"info": [self infoDictionaryWithRemoteAccount:remoteAccount systemAccount:systemAccount] 113 | }; 114 | } 115 | 116 | - (NSDictionary *)credentialsDictionaryWithRemoteAccount:(NSDictionary *)remoteAccount systemAccount:(ACAccount *)systemAccount { 117 | return @{ 118 | @"token": systemAccount.credential.oauthToken 119 | }; 120 | } 121 | 122 | - (NSDictionary *)extraDictionaryWithRemoteAccount:(NSDictionary *)remoteAccount systemAccount:(ACAccount *)systemAccount { 123 | return @{ 124 | @"raw_info": remoteAccount, 125 | @"account": systemAccount 126 | }; 127 | } 128 | 129 | - (NSDictionary *)infoDictionaryWithRemoteAccount:(NSDictionary *)remoteAccount systemAccount:(ACAccount *)systemAccount { 130 | NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; 131 | 132 | dictionary[@"name"] = remoteAccount[@"name"]; 133 | dictionary[@"first_name"] = remoteAccount[@"first_name"]; 134 | dictionary[@"last_name"] = remoteAccount[@"last_name"]; 135 | dictionary[@"verified"] = remoteAccount[@"verified"] ?: @NO; 136 | 137 | id email = remoteAccount[@"email"]; 138 | if (email) { 139 | dictionary[@"email"] = email; 140 | } 141 | 142 | id location = remoteAccount[@"location"][@"name"]; 143 | if (location) { 144 | dictionary[@"location"] = location; 145 | } 146 | if (remoteAccount[@"verified"]) 147 | dictionary[@"verified"] = remoteAccount[@"verified"]; 148 | dictionary[@"urls"] = @{ 149 | @"Facebook": remoteAccount[@"link"] 150 | }; 151 | 152 | NSString *avatar = [NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=large", remoteAccount[@"id"]]; 153 | dictionary[@"image"] = avatar; 154 | 155 | return dictionary; 156 | } 157 | 158 | @end 159 | -------------------------------------------------------------------------------- /Pod/Providers/Trello/SimpleAuthTrelloProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTrelloProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by Damiano Buscemi on 22/08/14. 6 | // Copyright (c) 2014 Crispy Bacon, S.r.l. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthTrelloProvider.h" 10 | #import "SimpleAuthTrelloLoginViewController.h" 11 | 12 | #import 13 | #import "UIViewController+SimpleAuthAdditions.h" 14 | 15 | @implementation SimpleAuthTrelloProvider 16 | 17 | #pragma mark - SimpleAuthProvider 18 | 19 | + (NSString *)type { 20 | return @"trello-web"; 21 | } 22 | 23 | + (NSDictionary *)defaultOptions { 24 | 25 | // Default present block 26 | SimpleAuthInterfaceHandler presentBlock = ^(UIViewController *controller) { 27 | UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller]; 28 | navigation.modalPresentationStyle = UIModalPresentationFormSheet; 29 | UIViewController *presented = [UIViewController SimpleAuth_presentedViewController]; 30 | [presented presentViewController:navigation animated:YES completion:nil]; 31 | }; 32 | 33 | // Default dismiss block 34 | SimpleAuthInterfaceHandler dismissBlock = ^(id controller) { 35 | [controller dismissViewControllerAnimated:YES completion:nil]; 36 | }; 37 | 38 | NSMutableDictionary *options = [NSMutableDictionary dictionaryWithDictionary:[super defaultOptions]]; 39 | options[SimpleAuthPresentInterfaceBlockKey] = presentBlock; 40 | options[SimpleAuthDismissInterfaceBlockKey] = dismissBlock; 41 | options[SimpleAuthRedirectURIKey] = @"simple-auth://trello-web.auth"; 42 | return options; 43 | } 44 | 45 | 46 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 47 | [[[self accessToken] 48 | flattenMap:^RACStream *(NSString *response) { 49 | NSArray *signals = @[ 50 | [self accountWithAccessToken:response], 51 | [RACSignal return:response] 52 | ]; 53 | return [self rac_liftSelector:@selector(dictionaryWithAccount:accessToken:) withSignalsFromArray:signals]; 54 | }] 55 | subscribeNext:^(NSDictionary *response) { 56 | completion(response, nil); 57 | } 58 | error:^(NSError *error) { 59 | completion(nil, error); 60 | }]; 61 | } 62 | 63 | 64 | #pragma mark - Private 65 | 66 | - (RACSignal *)accessToken { 67 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 68 | dispatch_async(dispatch_get_main_queue(), ^{ 69 | SimpleAuthTrelloLoginViewController *login = [[SimpleAuthTrelloLoginViewController alloc] initWithOptions:self.options]; 70 | login.completion = ^(UIViewController *login, NSURL *URL, NSError *error) { 71 | SimpleAuthInterfaceHandler dismissBlock = self.options[SimpleAuthDismissInterfaceBlockKey]; 72 | dismissBlock(login); 73 | 74 | // Parse URL 75 | NSString *fragment = [URL fragment]; 76 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:fragment]; 77 | NSString *token = dictionary[@"token"]; 78 | 79 | // Check for error 80 | if (![token length]) { 81 | [subscriber sendError:error]; 82 | return; 83 | } 84 | 85 | // Send completion 86 | [subscriber sendNext:token]; 87 | [subscriber sendCompleted]; 88 | }; 89 | 90 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthPresentInterfaceBlockKey]; 91 | block(login); 92 | }); 93 | return nil; 94 | }]; 95 | } 96 | 97 | 98 | - (RACSignal *)accountWithAccessToken:(NSString *)accessToken { 99 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 100 | NSDictionary *parameters = @{ @"token" : accessToken , @"key" : self.options[@"key"] }; 101 | NSString *query = [CMDQueryStringSerialization queryStringWithDictionary:parameters]; 102 | NSString *URLString = [NSString stringWithFormat:@"https://trello.com/1/members/me?%@", query]; 103 | NSURL *URL = [NSURL URLWithString:URLString]; 104 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 105 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 106 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 107 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 108 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 109 | if ([indexSet containsIndex:statusCode] && data) { 110 | NSError *parseError = nil; 111 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 112 | if (dictionary) { 113 | [subscriber sendNext:dictionary]; 114 | [subscriber sendCompleted]; 115 | } 116 | else { 117 | [subscriber sendError:parseError]; 118 | } 119 | } 120 | else { 121 | [subscriber sendError:connectionError]; 122 | } 123 | }]; 124 | return nil; 125 | }]; 126 | } 127 | 128 | 129 | #pragma mark - Private 130 | 131 | - (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account accessToken:(NSString *)accessToken { 132 | NSMutableDictionary *dictionary = [NSMutableDictionary new]; 133 | NSDictionary *data = account; 134 | 135 | // Provider 136 | dictionary[@"provider"] = [[self class] type]; 137 | 138 | // Credentials 139 | dictionary[@"credentials"] = @{ 140 | @"token" : accessToken 141 | }; 142 | 143 | // User ID 144 | dictionary[@"uid"] = data[@"id"]; 145 | 146 | // Extra 147 | dictionary[@"extra"] = @{ 148 | @"raw_info" : account 149 | }; 150 | 151 | // User info 152 | NSMutableDictionary *user = [NSMutableDictionary new]; 153 | user[@"name"] = data[@"fullName"]; 154 | user[@"username"] = data[@"username"]; 155 | user[@"avatarHash"] = data[@"avatarHash"]; 156 | dictionary[@"user_info"] = user; 157 | 158 | return dictionary; 159 | } 160 | 161 | @end 162 | -------------------------------------------------------------------------------- /Pod/Providers/FoursquareWeb/SimpleAuthFoursquareWebProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthFoursquareWebProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by Julien Seren-Rosso on 23/01/2014. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthFoursquareWebProvider.h" 10 | #import "SimpleAuthFoursquareWebLoginViewController.h" 11 | 12 | #import 13 | #import "UIViewController+SimpleAuthAdditions.h" 14 | 15 | @implementation SimpleAuthFoursquareWebProvider 16 | 17 | #pragma mark - SimpleAuthProvider 18 | 19 | + (NSString *)type { 20 | return @"foursquare-web"; 21 | } 22 | 23 | 24 | + (NSDictionary *)defaultOptions { 25 | 26 | // Default present block 27 | SimpleAuthInterfaceHandler presentBlock = ^(UIViewController *controller) { 28 | UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller]; 29 | navigation.modalPresentationStyle = UIModalPresentationFormSheet; 30 | UIViewController *presented = [UIViewController SimpleAuth_presentedViewController]; 31 | [presented presentViewController:navigation animated:YES completion:nil]; 32 | }; 33 | 34 | // Default dismiss block 35 | SimpleAuthInterfaceHandler dismissBlock = ^(id controller) { 36 | [controller dismissViewControllerAnimated:YES completion:nil]; 37 | }; 38 | 39 | NSMutableDictionary *options = [NSMutableDictionary dictionaryWithDictionary:[super defaultOptions]]; 40 | options[SimpleAuthPresentInterfaceBlockKey] = presentBlock; 41 | options[SimpleAuthDismissInterfaceBlockKey] = dismissBlock; 42 | return options; 43 | } 44 | 45 | 46 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 47 | [[[self accessToken] 48 | flattenMap:^RACStream *(NSString *response) { 49 | NSArray *signals = @[ 50 | [self accountWithAccessToken:response], 51 | [RACSignal return:response] 52 | ]; 53 | return [self rac_liftSelector:@selector(dictionaryWithAccount:accessToken:) withSignalsFromArray:signals]; 54 | }] 55 | subscribeNext:^(NSDictionary *response) { 56 | completion(response, nil); 57 | } 58 | error:^(NSError *error) { 59 | completion(nil, error); 60 | }]; 61 | } 62 | 63 | #pragma mark - Private 64 | 65 | - (RACSignal *)accessToken { 66 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 67 | dispatch_async(dispatch_get_main_queue(), ^{ 68 | SimpleAuthFoursquareWebLoginViewController *login = [[SimpleAuthFoursquareWebLoginViewController alloc] initWithOptions:self.options]; 69 | login.completion = ^(UIViewController *login, NSURL *URL, NSError *error) { 70 | SimpleAuthInterfaceHandler dismissBlock = self.options[SimpleAuthDismissInterfaceBlockKey]; 71 | dismissBlock(login); 72 | 73 | // Parse URL 74 | NSString *fragment = [URL fragment]; 75 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:fragment]; 76 | NSString *token = dictionary[@"access_token"]; 77 | 78 | // Check for error 79 | if (![token length]) { 80 | [subscriber sendError:error]; 81 | return; 82 | } 83 | 84 | // Send completion 85 | [subscriber sendNext:token]; 86 | [subscriber sendCompleted]; 87 | }; 88 | 89 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthPresentInterfaceBlockKey]; 90 | block(login); 91 | }); 92 | return nil; 93 | }]; 94 | } 95 | 96 | 97 | - (RACSignal *)accountWithAccessToken:(NSString *)accessToken { 98 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 99 | NSDictionary *parameters = @{ @"oauth_token" : accessToken }; 100 | NSString *query = [CMDQueryStringSerialization queryStringWithDictionary:parameters]; 101 | NSString *URLString = [NSString stringWithFormat:@"https://api.foursquare.com/v2/users/self?v=20140210&%@", query]; 102 | NSURL *URL = [NSURL URLWithString:URLString]; 103 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 104 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 105 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 106 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 107 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 108 | if ([indexSet containsIndex:statusCode] && data) { 109 | NSError *parseError = nil; 110 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 111 | if (dictionary) { 112 | [subscriber sendNext:dictionary]; 113 | [subscriber sendCompleted]; 114 | } 115 | else { 116 | [subscriber sendError:parseError]; 117 | } 118 | } 119 | else { 120 | [subscriber sendError:connectionError]; 121 | } 122 | }]; 123 | return nil; 124 | }]; 125 | } 126 | 127 | 128 | - (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account accessToken:(NSString *)accessToken { 129 | NSMutableDictionary *dictionary = [NSMutableDictionary new]; 130 | NSDictionary *userData = account[@"response"][@"user"]; 131 | 132 | // Provider 133 | dictionary[@"provider"] = [[self class] type]; 134 | 135 | // Credentials 136 | dictionary[@"credentials"] = @{ 137 | @"token" : accessToken 138 | }; 139 | 140 | // User ID 141 | dictionary[@"uid"] = userData[@"id"]; 142 | 143 | // Raw response 144 | dictionary[@"extra"] = @{ 145 | @"raw_info" : userData 146 | }; 147 | 148 | // User info 149 | NSMutableDictionary *user = [NSMutableDictionary new]; 150 | if (userData[@"contact"][@"email"]) { 151 | user[@"email"] = userData[@"contact"][@"email"]; 152 | } 153 | 154 | if (userData[@"firstName"]) { 155 | user[@"first_name"] = userData[@"firstName"]; 156 | } 157 | 158 | if (userData[@"lastName"]) { 159 | user[@"last_name"] = userData[@"lastName"]; 160 | } 161 | 162 | user[@"name"] = [NSString stringWithFormat:@"%@ %@", user[@"first_name"], user[@"last_name"]]; 163 | 164 | user[@"gender"] = userData[@"gender"]; 165 | 166 | if ([userData[@"photo"] isKindOfClass:NSDictionary.class]) { 167 | user[@"image"] = [NSString stringWithFormat:@"%@500x500%@", userData[@"photo"][@"prefix"], userData[@"photo"][@"suffix"]]; 168 | } else if ([userData[@"photo"] isKindOfClass:NSString.class]) { 169 | user[@"image"] = userData[@"photo"]; 170 | } 171 | 172 | if (userData[@"photo"]) { 173 | user[@"photo"] = userData[@"photo"]; 174 | } 175 | if (userData[@"homeCity"]) { 176 | NSString *homecity = [[userData[@"homeCity"] componentsSeparatedByString:@","] firstObject]; 177 | user[@"location"] = homecity; 178 | } 179 | user[@"urls"] = @{ 180 | @"Foursquare" : [NSString stringWithFormat:@"https://foursquare.com/user/%@", userData[@"id"]], 181 | }; 182 | dictionary[@"info"] = user; 183 | 184 | return dictionary; 185 | } 186 | 187 | 188 | @end 189 | -------------------------------------------------------------------------------- /Pod/Providers/VKontakteWeb/SimpleAuthVKontakteWebProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthVKontakteWebProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by Mikhail Kupriyanov on 7/7/15. 6 | // 7 | 8 | #import "SimpleAuthVKontakteWebProvider.h" 9 | #import "SimpleAuthVKontakteWebLoginViewController.h" 10 | 11 | #import "UIViewController+SimpleAuthAdditions.h" 12 | #import 13 | 14 | static const NSString *kVersion_api = @"5.34"; 15 | 16 | @implementation SimpleAuthVKontakteWebProvider 17 | 18 | #pragma mark - SimpleAuthProvider 19 | 20 | + (NSString *)type { 21 | return @"vkontakte-web"; 22 | } 23 | 24 | 25 | + (NSDictionary *)defaultOptions { 26 | 27 | // Default present block 28 | SimpleAuthInterfaceHandler presentBlock = ^(UIViewController *controller) { 29 | UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller]; 30 | navigation.modalPresentationStyle = UIModalPresentationFormSheet; 31 | UIViewController *presented = [UIViewController SimpleAuth_presentedViewController]; 32 | [presented presentViewController:navigation animated:YES completion:nil]; 33 | }; 34 | 35 | // Default dismiss block 36 | SimpleAuthInterfaceHandler dismissBlock = ^(id controller) { 37 | [controller dismissViewControllerAnimated:YES completion:nil]; 38 | }; 39 | 40 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithDictionary:[super defaultOptions]]; 41 | dictionary[SimpleAuthPresentInterfaceBlockKey] = presentBlock; 42 | dictionary[SimpleAuthDismissInterfaceBlockKey] = dismissBlock; 43 | dictionary[SimpleAuthRedirectURIKey] = @"https://oauth.vk.com/blank.html"; 44 | dictionary[@"permission"] = @[ @"email, offline" ]; 45 | dictionary[@"v"] = [kVersion_api copy]; 46 | return dictionary; 47 | } 48 | 49 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 50 | [[[self accessToken] 51 | flattenMap:^RACStream *(NSString *response) { 52 | NSArray *signals = @[ 53 | [self accountWithAccessToken:response], 54 | [RACSignal return:response] 55 | ]; 56 | return [self rac_liftSelector:@selector(dictionaryWithAccount:accessToken:) withSignalsFromArray:signals]; 57 | }] 58 | subscribeNext:^(NSDictionary *response) { 59 | completion(response, nil); 60 | } 61 | error:^(NSError *error) { 62 | completion(nil, error); 63 | }]; 64 | } 65 | 66 | 67 | #pragma mark - Private 68 | 69 | - (RACSignal *)accessToken { 70 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 71 | dispatch_async(dispatch_get_main_queue(), ^{ 72 | SimpleAuthVKontakteWebLoginViewController *login = [[SimpleAuthVKontakteWebLoginViewController alloc] initWithOptions:self.options]; 73 | login.completion = ^(UIViewController *login, NSURL *URL, NSError *error) { 74 | SimpleAuthInterfaceHandler dismissBlock = self.options[SimpleAuthDismissInterfaceBlockKey]; 75 | dismissBlock(login); 76 | 77 | // Parse URL 78 | NSString *fragment = [URL fragment]; 79 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:fragment]; 80 | NSString *access_token = dictionary[@"access_token"]; 81 | 82 | // Check for error 83 | if (![access_token length]) { 84 | [subscriber sendError:error]; 85 | return; 86 | } 87 | 88 | // Send completion 89 | [subscriber sendNext:dictionary]; 90 | [subscriber sendCompleted]; 91 | }; 92 | 93 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthPresentInterfaceBlockKey]; 94 | block(login); 95 | }); 96 | return nil; 97 | }]; 98 | } 99 | 100 | 101 | - (RACSignal *)accountWithAccessToken:(NSDictionary *) dictionaryWithAccessToken { 102 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 103 | NSString *accessToken = dictionaryWithAccessToken[@"access_token"]; 104 | NSString *user_id = dictionaryWithAccessToken[@"user_id"]; 105 | NSString *fields = @"sex, bdate, city, country, photo_50, photo_100, photo_200_orig, photo_200, photo_400_orig, photo_max, photo_max_orig, photo_id, online, online_mobile, domain, has_mobile, contacts, connections, site, education, universities, schools, can_post, can_see_all_posts, can_see_audio, can_write_private_message, status, last_seen, common_count, relation, relatives, counters, screen_name, maiden_name, timezone, occupation,activities, interests, music, movies, tv, books, games, about, quotes, personal, friend_status"; 106 | 107 | NSDictionary *parameters = @{ @"access_token" : accessToken , @"user_id" : user_id, @"fields" : fields, @"v" : self.options[@"v"] }; 108 | NSString *query = [CMDQueryStringSerialization queryStringWithDictionary:parameters]; 109 | NSString *URLString = [NSString stringWithFormat:@"https://api.vk.com/method/users.get?%@", query]; 110 | NSURL *URL = [NSURL URLWithString:URLString]; 111 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 112 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 113 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 114 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 115 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 116 | if ([indexSet containsIndex:statusCode] && data) { 117 | NSError *parseError = nil; 118 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 119 | if (dictionary) { 120 | [subscriber sendNext:dictionary]; 121 | [subscriber sendCompleted]; 122 | } 123 | else { 124 | [subscriber sendError:parseError]; 125 | } 126 | } 127 | else { 128 | [subscriber sendError:connectionError]; 129 | } 130 | }]; 131 | return nil; 132 | }]; 133 | } 134 | 135 | 136 | #pragma mark - Private 137 | 138 | - (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account accessToken:(NSDictionary *)accessToken{ 139 | NSMutableDictionary *dictionary = [NSMutableDictionary new]; 140 | NSArray *dataArray = (NSArray *) account[@"response"]; 141 | NSDictionary *data = dataArray.lastObject; 142 | // Provider 143 | dictionary[@"provider"] = [[self class] type]; 144 | 145 | // Credentials 146 | dictionary[@"credentials"] = @{ 147 | @"access_token" : accessToken[@"access_token"], 148 | @"expires_in" : accessToken[@"expires_in"] 149 | }; 150 | 151 | // User ID 152 | dictionary[@"user_id"] = accessToken[@"user_id"];; 153 | 154 | // Raw response 155 | dictionary[@"extra"] = @{ 156 | @"raw_info" : data 157 | }; 158 | 159 | // User info 160 | NSMutableDictionary *user = [NSMutableDictionary new]; 161 | user[@"first_name"] = data[@"first_name"]; 162 | user[@"last_name"] = data[@"last_name"]; 163 | user[@"photo_max_orig"] = data[@"photo_max_orig"]; 164 | 165 | dictionary[@"user_info"] = user; 166 | 167 | return dictionary; 168 | } 169 | @end 170 | -------------------------------------------------------------------------------- /Pod/Providers/Strava/SimpleAuthStravaWebProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthStravaWebProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by Ben Stahl on 7/27/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthStravaWebProvider.h" 10 | #import "SimpleAuthStravaWebLoginViewController.h" 11 | 12 | #import 13 | #import "UIViewController+SimpleAuthAdditions.h" 14 | 15 | @implementation SimpleAuthStravaWebProvider 16 | 17 | #pragma mark - SimpleAuthProvider 18 | 19 | + (NSString *)type { 20 | return @"strava-web"; 21 | } 22 | 23 | + (NSDictionary *)defaultOptions { 24 | 25 | // Default present block 26 | SimpleAuthInterfaceHandler presentBlock = ^(UIViewController *controller) { 27 | UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller]; 28 | navigation.modalPresentationStyle = UIModalPresentationFormSheet; 29 | UIViewController *presented = [UIViewController SimpleAuth_presentedViewController]; 30 | [presented presentViewController:navigation animated:YES completion:nil]; 31 | }; 32 | 33 | // Default dismiss block 34 | SimpleAuthInterfaceHandler dismissBlock = ^(id controller) { 35 | [controller dismissViewControllerAnimated:YES completion:nil]; 36 | }; 37 | 38 | NSMutableDictionary *options = [NSMutableDictionary dictionaryWithDictionary:[super defaultOptions]]; 39 | options[SimpleAuthPresentInterfaceBlockKey] = presentBlock; 40 | options[SimpleAuthDismissInterfaceBlockKey] = dismissBlock; 41 | options[SimpleAuthRedirectURIKey] = @"http://"; 42 | 43 | return options; 44 | } 45 | 46 | 47 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 48 | [[[self accessToken] 49 | flattenMap:^(id responseObject) { 50 | NSArray *signals = @[ 51 | [self accountWithAccessToken:responseObject], 52 | [RACSignal return:responseObject] 53 | ]; 54 | return [self rac_liftSelector:@selector(dictionaryWithAccount:accessToken:) withSignalsFromArray:signals]; 55 | }] 56 | subscribeNext:^(id responseObject) { 57 | completion(responseObject, nil); 58 | } 59 | error:^(NSError *error) { 60 | completion(nil, error); 61 | }]; 62 | } 63 | 64 | #pragma mark - Private 65 | 66 | - (RACSignal *)authorizationCode { 67 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 68 | dispatch_async(dispatch_get_main_queue(), ^{ 69 | SimpleAuthStravaWebLoginViewController *login = [[SimpleAuthStravaWebLoginViewController alloc] initWithOptions:self.options]; 70 | login.completion = ^(UIViewController *login, NSURL *URL, NSError *error) { 71 | SimpleAuthInterfaceHandler dismissBlock = self.options[SimpleAuthDismissInterfaceBlockKey]; 72 | dismissBlock(login); 73 | 74 | // Parse URL 75 | NSString *fragment = [URL query]; 76 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:fragment]; 77 | NSString *code = dictionary[@"code"]; 78 | 79 | // Check for error 80 | if (![code length]) { 81 | [subscriber sendError:error]; 82 | return; 83 | } 84 | 85 | // Send completion 86 | [subscriber sendNext:code]; 87 | [subscriber sendCompleted]; 88 | }; 89 | 90 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthPresentInterfaceBlockKey]; 91 | block(login); 92 | }); 93 | return nil; 94 | }]; 95 | } 96 | 97 | 98 | - (RACSignal *)accessTokenWithAuthorizationCode:(NSString *)code { 99 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 100 | 101 | // Build request 102 | NSDictionary *parameters = @{ 103 | @"code" : code, 104 | @"client_id" : self.options[@"client_id"], 105 | @"client_secret" : self.options[@"client_secret"], 106 | @"redirect_uri" : self.options[SimpleAuthRedirectURIKey], 107 | }; 108 | NSString *query = [CMDQueryStringSerialization queryStringWithDictionary:parameters]; 109 | NSURL *URL = [NSURL URLWithString:@"https://www.strava.com/oauth/token"]; 110 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; 111 | request.HTTPMethod = @"POST"; 112 | request.HTTPBody = [query dataUsingEncoding:NSUTF8StringEncoding]; 113 | 114 | // Run request 115 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 116 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 117 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 118 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 119 | if ([indexSet containsIndex:statusCode] && data) { 120 | NSError *parseError = nil; 121 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 122 | if (dictionary) { 123 | [subscriber sendNext:dictionary]; 124 | [subscriber sendCompleted]; 125 | } 126 | else { 127 | [subscriber sendError:parseError]; 128 | } 129 | } 130 | else { 131 | [subscriber sendError:connectionError]; 132 | } 133 | }]; 134 | 135 | return nil; 136 | }]; 137 | } 138 | 139 | 140 | - (RACSignal *)accessToken { 141 | return [[self authorizationCode] flattenMap:^(id responseObject) { 142 | return [self accessTokenWithAuthorizationCode:responseObject]; 143 | }]; 144 | } 145 | 146 | - (RACSignal *)accountWithAccessToken:(NSDictionary *)accessToken { 147 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 148 | NSDictionary *parameters = @{ 149 | @"access_token" : accessToken[@"access_token"], 150 | }; 151 | NSString *URLString = [NSString stringWithFormat:@"https://www.strava.com/api/v3/athlete?%@", 152 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 153 | NSURL *URL = [NSURL URLWithString:URLString]; 154 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 155 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 156 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 157 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 158 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 159 | if ([indexSet containsIndex:statusCode] && data) { 160 | NSError *parseError = nil; 161 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 162 | if (dictionary) { 163 | [subscriber sendNext:dictionary]; 164 | [subscriber sendCompleted]; 165 | } 166 | else { 167 | [subscriber sendError:parseError]; 168 | } 169 | } 170 | else { 171 | [subscriber sendError:connectionError]; 172 | } 173 | }]; 174 | return nil; 175 | }]; 176 | } 177 | 178 | 179 | - (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account accessToken:(NSDictionary *)accessToken { 180 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 181 | 182 | // Provider 183 | dictionary[@"provider"] = [[self class] type]; 184 | 185 | // Credentials 186 | dictionary[@"credentials"] = @{@"token" : accessToken[@"access_token"]}; 187 | 188 | // User ID 189 | dictionary[@"uid"] = account[@"id"]; 190 | 191 | // Raw response 192 | dictionary[@"raw_info"] = account; 193 | 194 | // User info 195 | NSMutableDictionary *user = [NSMutableDictionary new]; 196 | user[@"email"] = account[@"email"]; 197 | if (user[@"firstName"]) { 198 | user[@"first_name"] = user[@"firstname"]; 199 | } 200 | if (user[@"lastName"]) { 201 | user[@"last_name"] = user[@"lastname"]; 202 | } 203 | user[@"gender"] = account[@"sex"]; 204 | user[@"image"] = account[@"profile"]; 205 | user[@"location"] = account[@"city"]; 206 | dictionary[@"info"] = user; 207 | 208 | return dictionary; 209 | } 210 | 211 | 212 | @end 213 | -------------------------------------------------------------------------------- /Pod/Providers/SinaWeiboWeb/SimpleAuthSinaWeiboWebProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthSinaWeiboWebProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by Alexander Schuch on 17/02/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthSinaWeiboWebProvider.h" 10 | #import "SimpleAuthSinaWeiboWebLoginViewController.h" 11 | 12 | #import 13 | #import "UIViewController+SimpleAuthAdditions.h" 14 | 15 | @implementation SimpleAuthSinaWeiboWebProvider 16 | 17 | #pragma mark - SimpleAuthProvider 18 | 19 | + (NSString *)type { 20 | return @"sinaweibo-web"; 21 | } 22 | 23 | + (NSDictionary *)defaultOptions { 24 | 25 | // Default present block 26 | SimpleAuthInterfaceHandler presentBlock = ^(UIViewController *controller) { 27 | UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller]; 28 | navigation.modalPresentationStyle = UIModalPresentationFormSheet; 29 | UIViewController *presented = [UIViewController SimpleAuth_presentedViewController]; 30 | [presented presentViewController:navigation animated:YES completion:nil]; 31 | }; 32 | 33 | // Default dismiss block 34 | SimpleAuthInterfaceHandler dismissBlock = ^(id controller) { 35 | [controller dismissViewControllerAnimated:YES completion:nil]; 36 | }; 37 | 38 | NSMutableDictionary *options = [NSMutableDictionary dictionaryWithDictionary:[super defaultOptions]]; 39 | options[SimpleAuthPresentInterfaceBlockKey] = presentBlock; 40 | options[SimpleAuthDismissInterfaceBlockKey] = dismissBlock; 41 | options[SimpleAuthRedirectURIKey] = @"http://"; 42 | 43 | return options; 44 | } 45 | 46 | 47 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 48 | [[[self accessToken] 49 | flattenMap:^(id responseObject) { 50 | NSArray *signals = @[ 51 | [self accountWithAccessToken:responseObject], 52 | [RACSignal return:responseObject] 53 | ]; 54 | return [self rac_liftSelector:@selector(dictionaryWithAccount:accessToken:) withSignalsFromArray:signals]; 55 | }] 56 | subscribeNext:^(id responseObject) { 57 | completion(responseObject, nil); 58 | } 59 | error:^(NSError *error) { 60 | completion(nil, error); 61 | }]; 62 | } 63 | 64 | #pragma mark - Private 65 | 66 | - (RACSignal *)authorizationCode { 67 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 68 | dispatch_async(dispatch_get_main_queue(), ^{ 69 | SimpleAuthSinaWeiboWebLoginViewController *login = [[SimpleAuthSinaWeiboWebLoginViewController alloc] initWithOptions:self.options]; 70 | login.completion = ^(UIViewController *login, NSURL *URL, NSError *error) { 71 | SimpleAuthInterfaceHandler dismissBlock = self.options[SimpleAuthDismissInterfaceBlockKey]; 72 | dismissBlock(login); 73 | 74 | // Parse URL 75 | NSString *fragment = [URL query]; 76 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:fragment]; 77 | NSString *code = dictionary[@"code"]; 78 | 79 | // Check for error 80 | if (![code length]) { 81 | [subscriber sendError:error]; 82 | return; 83 | } 84 | 85 | // Send completion 86 | [subscriber sendNext:code]; 87 | [subscriber sendCompleted]; 88 | }; 89 | 90 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthPresentInterfaceBlockKey]; 91 | block(login); 92 | }); 93 | return nil; 94 | }]; 95 | } 96 | 97 | 98 | - (RACSignal *)accessTokenWithAuthorizationCode:(NSString *)code { 99 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 100 | 101 | // Build request 102 | NSDictionary *parameters = @{ 103 | @"code" : code, 104 | @"client_id" : self.options[@"client_id"], 105 | @"client_secret" : self.options[@"client_secret"], 106 | @"redirect_uri" : self.options[SimpleAuthRedirectURIKey], 107 | @"grant_type" : @"authorization_code" 108 | }; 109 | NSString *query = [CMDQueryStringSerialization queryStringWithDictionary:parameters]; 110 | NSURL *URL = [NSURL URLWithString:@"https://api.weibo.com/oauth2/access_token"]; 111 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; 112 | request.HTTPMethod = @"POST"; 113 | request.HTTPBody = [query dataUsingEncoding:NSUTF8StringEncoding]; 114 | 115 | // Run request 116 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 117 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 118 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 119 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 120 | if ([indexSet containsIndex:statusCode] && data) { 121 | NSError *parseError = nil; 122 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 123 | if (dictionary) { 124 | [subscriber sendNext:dictionary]; 125 | [subscriber sendCompleted]; 126 | } 127 | else { 128 | [subscriber sendError:parseError]; 129 | } 130 | } 131 | else { 132 | [subscriber sendError:connectionError]; 133 | } 134 | }]; 135 | 136 | return nil; 137 | }]; 138 | } 139 | 140 | 141 | - (RACSignal *)accessToken { 142 | return [[self authorizationCode] flattenMap:^(id responseObject) { 143 | return [self accessTokenWithAuthorizationCode:responseObject]; 144 | }]; 145 | } 146 | 147 | 148 | - (RACSignal *)accountWithAccessToken:(NSDictionary *)accessToken { 149 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 150 | NSDictionary *parameters = @{ 151 | @"access_token" : accessToken[@"access_token"], 152 | @"uid": accessToken[@"uid"] 153 | }; 154 | NSString *URLString = [NSString stringWithFormat:@"https://api.weibo.com/2/users/show.json?%@", 155 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 156 | NSURL *URL = [NSURL URLWithString:URLString]; 157 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 158 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 159 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 160 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 161 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 162 | if ([indexSet containsIndex:statusCode] && data) { 163 | NSError *parseError = nil; 164 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 165 | if (dictionary) { 166 | [subscriber sendNext:dictionary]; 167 | [subscriber sendCompleted]; 168 | } 169 | else { 170 | [subscriber sendError:parseError]; 171 | } 172 | } 173 | else { 174 | [subscriber sendError:connectionError]; 175 | } 176 | }]; 177 | return nil; 178 | }]; 179 | } 180 | 181 | 182 | - (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account accessToken:(NSDictionary *)accessToken { 183 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 184 | 185 | // Provider 186 | dictionary[@"provider"] = [[self class] type]; 187 | 188 | // Credentials 189 | NSTimeInterval expiresAtInterval = [accessToken[@"expires_in"] doubleValue]; 190 | NSDate *expiresAtDate = [NSDate dateWithTimeIntervalSinceNow:expiresAtInterval]; 191 | dictionary[@"credentials"] = @{ 192 | @"token" : accessToken[@"access_token"], 193 | @"expires_at" : expiresAtDate 194 | }; 195 | 196 | // User ID 197 | dictionary[@"uid"] = account[@"id"]; 198 | 199 | // Raw response 200 | dictionary[@"raw_info"] = account; 201 | 202 | // User info 203 | NSMutableDictionary *user = [NSMutableDictionary new]; 204 | user[@"screen_name"] = account[@"screen_name"]; 205 | user[@"name"] = account[@"name"]; 206 | user[@"location"] = account[@"location"]; 207 | user[@"description"] = account[@"description"]; 208 | user[@"gender"] = account[@"gender"]; 209 | user[@"image"] = account[@"avatar_large"]; 210 | dictionary[@"user_info"] = user; 211 | 212 | return dictionary; 213 | } 214 | 215 | @end 216 | -------------------------------------------------------------------------------- /Pod/Providers/BoxWeb/SimpleAuthBoxWebProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthBoxWebProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by dkhamsing on 3/26/15. 6 | // Copyright (c) 2015 dkhamsing. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthBoxWebProvider.h" 10 | #import "SimpleAuthBoxWebLoginViewController.h" 11 | 12 | #import 13 | #import "UIViewController+SimpleAuthAdditions.h" 14 | 15 | @implementation SimpleAuthBoxWebProvider 16 | 17 | #pragma mark - Initializers 18 | 19 | - (instancetype)initWithOptions:(NSDictionary *)options { 20 | NSMutableDictionary *mutableOptions = [NSMutableDictionary dictionaryWithDictionary:options]; 21 | mutableOptions[SimpleAuthRedirectURIKey] = [NSString stringWithFormat:@"boxsdk-%@://boxsdkoauth2redirect", options[@"client_id"]]; 22 | self = [super initWithOptions:[mutableOptions copy]]; 23 | return self; 24 | } 25 | 26 | 27 | #pragma mark - SimpleAuthProvider 28 | 29 | + (NSString *)type { 30 | return @"box-web"; 31 | } 32 | 33 | 34 | + (NSDictionary *)defaultOptions { 35 | 36 | // Default present block 37 | SimpleAuthInterfaceHandler presentBlock = ^(UIViewController *controller) { 38 | UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller]; 39 | navigation.modalPresentationStyle = UIModalPresentationFormSheet; 40 | UIViewController *presented = [UIViewController SimpleAuth_presentedViewController]; 41 | [presented presentViewController:navigation animated:YES completion:nil]; 42 | }; 43 | 44 | // Default dismiss block 45 | SimpleAuthInterfaceHandler dismissBlock = ^(id controller) { 46 | [controller dismissViewControllerAnimated:YES completion:nil]; 47 | }; 48 | 49 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithDictionary:[super defaultOptions]]; 50 | dictionary[SimpleAuthPresentInterfaceBlockKey] = presentBlock; 51 | dictionary[SimpleAuthDismissInterfaceBlockKey] = dismissBlock; 52 | return dictionary; 53 | } 54 | 55 | 56 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 57 | [[[self accessToken] 58 | flattenMap:^(NSDictionary *response) { 59 | NSArray *signals = @[ 60 | [self accountWithAccessToken:response], 61 | [RACSignal return:response] 62 | ]; 63 | return [self rac_liftSelector:@selector(dictionaryWithAccount:accessToken:) withSignalsFromArray:signals]; 64 | }] 65 | subscribeNext:^(NSDictionary *response) { 66 | completion(response, nil); 67 | } 68 | error:^(NSError *error) { 69 | completion(nil, error); 70 | }]; 71 | } 72 | 73 | 74 | #pragma mark - Private 75 | 76 | - (RACSignal *)authorizationCode { 77 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 78 | dispatch_async(dispatch_get_main_queue(), ^{ 79 | SimpleAuthBoxWebLoginViewController *login = [[SimpleAuthBoxWebLoginViewController alloc] initWithOptions:self.options]; 80 | login.completion = ^(UIViewController *login, NSURL *URL, NSError *error) { 81 | SimpleAuthInterfaceHandler dismissBlock = self.options[SimpleAuthDismissInterfaceBlockKey]; 82 | dismissBlock(login); 83 | 84 | // Parse URL 85 | NSString *fragment = [URL query]; 86 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:fragment]; 87 | NSString *code = dictionary[@"code"]; 88 | 89 | // Check for error 90 | if (![code length]) { 91 | [subscriber sendError:error]; 92 | return; 93 | } 94 | 95 | // Send completion 96 | [subscriber sendNext:code]; 97 | [subscriber sendCompleted]; 98 | }; 99 | 100 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthPresentInterfaceBlockKey]; 101 | block(login); 102 | }); 103 | return nil; 104 | }]; 105 | } 106 | 107 | 108 | - (RACSignal *)accessTokenWithAuthorizationCode:(NSString *)code { 109 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 110 | 111 | // Build parameters 112 | NSDictionary *parameters = @{ 113 | @"code" : code, 114 | @"client_id" : self.options[@"client_id"], 115 | @"client_secret" : self.options[@"client_secret"], 116 | @"redirect_uri" : self.options[SimpleAuthRedirectURIKey], 117 | @"grant_type" : @"authorization_code" 118 | }; 119 | 120 | // Build request 121 | NSString *query = [CMDQueryStringSerialization queryStringWithDictionary:parameters]; 122 | NSURL *URL = [NSURL URLWithString:@"https://api.box.com/oauth2/token"]; 123 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; 124 | [request setHTTPMethod:@"POST"]; 125 | [request setValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 126 | [request setHTTPBody:[query dataUsingEncoding:NSUTF8StringEncoding]]; 127 | 128 | // Run request 129 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 130 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 131 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 132 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 133 | if ([indexSet containsIndex:statusCode] && data) { 134 | NSError *parseError = nil; 135 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 136 | if (dictionary) { 137 | [subscriber sendNext:dictionary]; 138 | [subscriber sendCompleted]; 139 | } 140 | else { 141 | [subscriber sendError:parseError]; 142 | } 143 | } 144 | else { 145 | [subscriber sendError:connectionError]; 146 | } 147 | }]; 148 | return nil; 149 | }]; 150 | } 151 | 152 | 153 | - (RACSignal *)accessToken { 154 | return [[self authorizationCode] flattenMap:^(id responseObject) { 155 | return [self accessTokenWithAuthorizationCode:responseObject]; 156 | }]; 157 | } 158 | 159 | 160 | - (RACSignal *)accountWithAccessToken:(NSDictionary *)accessToken { 161 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 162 | NSDictionary *parameters = @{ @"access_token" : accessToken[@"access_token"] }; 163 | NSString *URLString = [NSString stringWithFormat: 164 | @"https://api.box.com/2.0/users/me?%@", 165 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 166 | NSURL *URL = [NSURL URLWithString:URLString]; 167 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 168 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 169 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 170 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 171 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 172 | if ([indexSet containsIndex:statusCode] && data) { 173 | NSError *parseError = nil; 174 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 175 | if (dictionary) { 176 | [subscriber sendNext:dictionary]; 177 | [subscriber sendCompleted]; 178 | } 179 | else { 180 | [subscriber sendError:parseError]; 181 | } 182 | } 183 | else { 184 | [subscriber sendError:connectionError]; 185 | } 186 | }]; 187 | return nil; 188 | }]; 189 | } 190 | 191 | 192 | - (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account accessToken:(NSDictionary *)accessToken { 193 | NSMutableDictionary *dictionary = [NSMutableDictionary new]; 194 | 195 | // Provider 196 | dictionary[@"provider"] = [[self class] type]; 197 | 198 | // Credentials 199 | dictionary[@"credentials"] = @{ 200 | @"token" : accessToken[@"access_token"], 201 | @"type" : accessToken[@"token_type"], 202 | @"expires_in": accessToken[@"expires_in"], 203 | @"refresh_token": accessToken[@"refresh_token"], 204 | }; 205 | 206 | // User ID 207 | dictionary[@"id"] = account[@"id"]; 208 | 209 | // Raw response 210 | dictionary[@"extra"] = @{ 211 | @"raw_info" : account 212 | }; 213 | 214 | // User info 215 | NSMutableDictionary *user = [NSMutableDictionary new]; 216 | user[@"login"] = account[@"login"]; 217 | user[@"name"] = account[@"name"]; 218 | dictionary[@"info"] = user; 219 | 220 | return dictionary; 221 | } 222 | 223 | @end 224 | -------------------------------------------------------------------------------- /Pod/Providers/LinkedIn/SimpleAuthLinkedInWebProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthLinkedInProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by Abhishek Sheth on 24/01/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthLinkedInWebProvider.h" 10 | #import "SimpleAuthLinkedInWebLoginViewController.h" 11 | 12 | #import 13 | #import "UIViewController+SimpleAuthAdditions.h" 14 | 15 | @implementation SimpleAuthLinkedInWebProvider 16 | 17 | #pragma mark - SimpleAuthProvider 18 | 19 | + (NSString *)type { 20 | return @"linkedin-web"; 21 | } 22 | 23 | 24 | + (NSDictionary *)defaultOptions { 25 | 26 | // Default present block 27 | SimpleAuthInterfaceHandler presentBlock = ^(UIViewController *controller) { 28 | UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller]; 29 | navigation.modalPresentationStyle = UIModalPresentationFormSheet; 30 | UIViewController *presented = [UIViewController SimpleAuth_presentedViewController]; 31 | [presented presentViewController:navigation animated:YES completion:nil]; 32 | }; 33 | 34 | // Default dismiss block 35 | SimpleAuthInterfaceHandler dismissBlock = ^(id controller) { 36 | [controller dismissViewControllerAnimated:YES completion:nil]; 37 | }; 38 | 39 | NSMutableDictionary *options = [NSMutableDictionary dictionaryWithDictionary:[super defaultOptions]]; 40 | options[SimpleAuthPresentInterfaceBlockKey] = presentBlock; 41 | options[SimpleAuthDismissInterfaceBlockKey] = dismissBlock; 42 | return options; 43 | } 44 | 45 | 46 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 47 | [[[self accessToken] 48 | flattenMap:^(id responseObject) { 49 | NSArray *signals = @[ 50 | [self accountWithAccessToken:responseObject], 51 | [RACSignal return:responseObject] 52 | ]; 53 | return [self rac_liftSelector:@selector(dictionaryWithAccount:accessToken:) withSignalsFromArray:signals]; 54 | }] 55 | subscribeNext:^(id responseObject) { 56 | completion(responseObject, nil); 57 | } 58 | error:^(NSError *error) { 59 | completion(nil, error); 60 | }]; 61 | } 62 | 63 | #pragma mark - Private 64 | 65 | - (RACSignal *)authorizationCode { 66 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 67 | dispatch_async(dispatch_get_main_queue(), ^{ 68 | SimpleAuthLinkedInWebLoginViewController *login = [[SimpleAuthLinkedInWebLoginViewController alloc] initWithOptions:self.options]; 69 | login.completion = ^(UIViewController *login, NSURL *URL, NSError *error) { 70 | SimpleAuthInterfaceHandler dismissBlock = self.options[SimpleAuthDismissInterfaceBlockKey]; 71 | dismissBlock(login); 72 | 73 | // Parse URL 74 | NSString *fragment = [URL query]; 75 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:fragment]; 76 | NSString *code = dictionary[@"code"]; 77 | 78 | // Check for error 79 | if (![code length]) { 80 | [subscriber sendError:error]; 81 | return; 82 | } 83 | 84 | // Send completion 85 | [subscriber sendNext:code]; 86 | [subscriber sendCompleted]; 87 | }; 88 | 89 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthPresentInterfaceBlockKey]; 90 | block(login); 91 | }); 92 | return nil; 93 | }]; 94 | } 95 | 96 | 97 | - (RACSignal *)accessTokenWithAuthorizationCode:(NSString *)code { 98 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 99 | 100 | // Build request 101 | NSDictionary *parameters = @{ 102 | @"code" : code, 103 | @"client_id" : self.options[@"client_id"], 104 | @"client_secret" : self.options[@"client_secret"], 105 | @"redirect_uri" : self.options[@"redirect_uri"], 106 | @"grant_type" : @"authorization_code" 107 | }; 108 | NSString *query = [CMDQueryStringSerialization queryStringWithDictionary:parameters]; 109 | NSURL *URL = [NSURL URLWithString:@"https://api.linkedin.com/uas/oauth2/accessToken"]; 110 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; 111 | [request setHTTPMethod:@"POST"]; 112 | [request setValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 113 | [request setHTTPBody:[query dataUsingEncoding:NSUTF8StringEncoding]]; 114 | 115 | // Run request 116 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 117 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 118 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 119 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 120 | if ([indexSet containsIndex:statusCode] && data) { 121 | NSError *parseError = nil; 122 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 123 | if (dictionary) { 124 | [subscriber sendNext:dictionary]; 125 | [subscriber sendCompleted]; 126 | } 127 | else { 128 | [subscriber sendError:parseError]; 129 | } 130 | } 131 | else { 132 | [subscriber sendError:connectionError]; 133 | } 134 | }]; 135 | 136 | return nil; 137 | }]; 138 | } 139 | 140 | 141 | - (RACSignal *)accessToken { 142 | return [[self authorizationCode] flattenMap:^(id responseObject) { 143 | return [self accessTokenWithAuthorizationCode:responseObject]; 144 | }]; 145 | } 146 | 147 | 148 | - (RACSignal *)accountWithAccessToken:(NSDictionary *)accessToken { 149 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 150 | NSDictionary *parameters = @{ 151 | @"oauth2_access_token" : accessToken[@"access_token"], 152 | @"format" : @"json" 153 | }; 154 | // field_selectors control the fields that LinkedIn returns for the user object. If none specified, LinkedIn returns a minimal set. 155 | NSString *URLString; 156 | if (self.options[@"field_selectors"]) 157 | { 158 | URLString = [NSString stringWithFormat: 159 | @"https://api.linkedin.com/v1/people/~:(%@)?%@", 160 | [self.options[@"field_selectors"] componentsJoinedByString:@","], 161 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 162 | } 163 | else 164 | { 165 | URLString = [NSString stringWithFormat: 166 | @"https://api.linkedin.com/v1/people/~?%@", 167 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 168 | } 169 | NSURL *URL = [NSURL URLWithString:URLString]; 170 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 171 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 172 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 173 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 174 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 175 | if ([indexSet containsIndex:statusCode] && data) { 176 | NSError *parseError = nil; 177 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 178 | if (dictionary) { 179 | [subscriber sendNext:dictionary]; 180 | [subscriber sendCompleted]; 181 | } 182 | else { 183 | [subscriber sendError:parseError]; 184 | } 185 | } 186 | else { 187 | [subscriber sendError:connectionError]; 188 | } 189 | }]; 190 | return nil; 191 | }]; 192 | } 193 | 194 | 195 | - (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account accessToken:(NSDictionary *)accessToken { 196 | NSMutableDictionary *dictionary = [NSMutableDictionary new]; 197 | 198 | // Provider 199 | dictionary[@"provider"] = [[self class] type]; 200 | 201 | // Credentials 202 | NSTimeInterval expiresAtInterval = [accessToken[@"expires_in"] doubleValue]; 203 | NSDate *expiresAtDate = [NSDate dateWithTimeIntervalSinceNow:expiresAtInterval]; 204 | dictionary[@"credentials"] = @{ 205 | @"token" : accessToken[@"access_token"], 206 | @"expires_at" : expiresAtDate 207 | }; 208 | 209 | // User ID 210 | //dictionary[@"uid"] = account[@"id"]; 211 | 212 | // Raw response 213 | dictionary[@"raw_info"] = account; 214 | 215 | // User info 216 | NSMutableDictionary *user = [NSMutableDictionary new]; 217 | user[@"first_name"] = account[@"firstName"]; 218 | user[@"last_name"] = account[@"lastName"]; 219 | user[@"headline"] = account[@"headline"]; 220 | dictionary[@"user_info"] = user; 221 | 222 | return dictionary; 223 | } 224 | 225 | @end 226 | -------------------------------------------------------------------------------- /Pod/Providers/OneDriveWeb/SimpleAuthOneDriveWebProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthOneDriveWebProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by dkhamsing on 3/31/15. 6 | // Copyright (c) 2015 dkhamsing. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthOneDriveWebProvider.h" 10 | #import "SimpleAuthOneDriveWebLoginViewController.h" 11 | 12 | #import 13 | #import "UIViewController+SimpleAuthAdditions.h" 14 | 15 | @implementation SimpleAuthOneDriveWebProvider 16 | 17 | - (instancetype)initWithOptions:(NSDictionary *)options { 18 | NSMutableDictionary *mutableOptions = [NSMutableDictionary dictionaryWithDictionary:options]; 19 | mutableOptions[SimpleAuthRedirectURIKey] = @""; 20 | self = [super initWithOptions:[mutableOptions copy]]; 21 | return self; 22 | } 23 | 24 | #pragma mark - SimpleAuthProvider 25 | 26 | + (NSString *)type { 27 | return @"onedrive-web"; 28 | } 29 | 30 | 31 | + (NSDictionary *)defaultOptions { 32 | 33 | // Default present block 34 | SimpleAuthInterfaceHandler presentBlock = ^(UIViewController *controller) { 35 | UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller]; 36 | navigation.modalPresentationStyle = UIModalPresentationFormSheet; 37 | UIViewController *presented = [UIViewController SimpleAuth_presentedViewController]; 38 | [presented presentViewController:navigation animated:YES completion:nil]; 39 | }; 40 | 41 | // Default dismiss block 42 | SimpleAuthInterfaceHandler dismissBlock = ^(id controller) { 43 | [controller dismissViewControllerAnimated:YES completion:nil]; 44 | }; 45 | 46 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithDictionary:[super defaultOptions]]; 47 | dictionary[SimpleAuthPresentInterfaceBlockKey] = presentBlock; 48 | dictionary[SimpleAuthDismissInterfaceBlockKey] = dismissBlock; 49 | dictionary[@"scope"] = @"wl.signin wl.offline_access onedrive.readwrite"; 50 | return dictionary; 51 | } 52 | 53 | 54 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 55 | [[[self accessToken] 56 | flattenMap:^(NSDictionary *response) { 57 | NSArray *signals = @[ 58 | [self accountWithAccessToken:response], 59 | [RACSignal return:response] 60 | ]; 61 | return [self rac_liftSelector:@selector(dictionaryWithAccount:accessToken:) withSignalsFromArray:signals]; 62 | }] 63 | subscribeNext:^(NSDictionary *response) { 64 | completion(response, nil); 65 | } 66 | error:^(NSError *error) { 67 | completion(nil, error); 68 | }]; 69 | } 70 | 71 | 72 | #pragma mark - Private 73 | 74 | - (RACSignal *)authorizationCode { 75 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 76 | dispatch_async(dispatch_get_main_queue(), ^{ 77 | SimpleAuthOneDriveWebLoginViewController *login = [[SimpleAuthOneDriveWebLoginViewController alloc] initWithOptions:self.options]; 78 | login.completion = ^(UIViewController *login, NSURL *URL, NSError *error) { 79 | SimpleAuthInterfaceHandler dismissBlock = self.options[SimpleAuthDismissInterfaceBlockKey]; 80 | dismissBlock(login); 81 | 82 | // Parse URL 83 | NSString *fragment = [URL query]; 84 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:fragment]; 85 | NSString *code = dictionary[@"code"]; 86 | 87 | // Check for error 88 | if (![code length]) { 89 | [subscriber sendError:error]; 90 | return; 91 | } 92 | 93 | // Send completion 94 | [subscriber sendNext:code]; 95 | [subscriber sendCompleted]; 96 | }; 97 | 98 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthPresentInterfaceBlockKey]; 99 | block(login); 100 | }); 101 | return nil; 102 | }]; 103 | } 104 | 105 | 106 | - (RACSignal *)accessTokenWithAuthorizationCode:(NSString *)code { 107 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 108 | 109 | // Build request 110 | NSDictionary *parameters = @{ 111 | @"code" : code, 112 | @"client_id" : self.options[@"client_id"], 113 | @"client_secret" : self.options[@"client_secret"], 114 | @"redirect_uri": @"", 115 | @"grant_type" : @"authorization_code" 116 | }; 117 | 118 | NSString *query = [CMDQueryStringSerialization queryStringWithDictionary:parameters]; 119 | NSURL *URL = [NSURL URLWithString:@"https://login.live.com/oauth20_token.srf"]; 120 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; 121 | [request setHTTPMethod:@"POST"]; 122 | [request setValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 123 | [request setHTTPBody:[query dataUsingEncoding:NSUTF8StringEncoding]]; 124 | 125 | // Run request 126 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 127 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 128 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 129 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 130 | if ([indexSet containsIndex:statusCode] && data) { 131 | NSError *parseError = nil; 132 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 133 | if (dictionary) { 134 | [subscriber sendNext:dictionary]; 135 | [subscriber sendCompleted]; 136 | } 137 | else { 138 | [subscriber sendError:parseError]; 139 | } 140 | } 141 | else { 142 | [subscriber sendError:connectionError]; 143 | } 144 | }]; 145 | 146 | return nil; 147 | }]; 148 | } 149 | 150 | 151 | - (RACSignal *)accessToken { 152 | return [[self authorizationCode] flattenMap:^(id responseObject) { 153 | return [self accessTokenWithAuthorizationCode:responseObject]; 154 | }]; 155 | } 156 | 157 | 158 | - (RACSignal *)accountWithAccessToken:(NSDictionary *)accessToken { 159 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 160 | NSDictionary *parameters = @{ @"access_token" : accessToken[@"access_token"] }; 161 | NSString *URLString = [NSString stringWithFormat: 162 | @"https://apis.live.net/v5.0/me?%@", 163 | [CMDQueryStringSerialization queryStringWithDictionary:parameters]]; 164 | NSURL *URL = [NSURL URLWithString:URLString]; 165 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 166 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 167 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 168 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 169 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 170 | if ([indexSet containsIndex:statusCode] && data) { 171 | NSError *parseError = nil; 172 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 173 | if (dictionary) { 174 | [subscriber sendNext:dictionary]; 175 | [subscriber sendCompleted]; 176 | } 177 | else { 178 | [subscriber sendError:parseError]; 179 | } 180 | } 181 | else { 182 | [subscriber sendError:connectionError]; 183 | } 184 | }]; 185 | return nil; 186 | }]; 187 | } 188 | 189 | 190 | - (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account accessToken:(NSDictionary *)accessToken { 191 | NSMutableDictionary *dictionary = [NSMutableDictionary new]; 192 | 193 | // Provider 194 | dictionary[@"provider"] = [[self class] type]; 195 | 196 | // Credentials 197 | dictionary[@"credentials"] = @{ 198 | @"token" : accessToken[@"access_token"], 199 | @"type" : accessToken[@"token_type"], 200 | @"expires_in": accessToken[@"expires_in"], 201 | @"refresh_token": accessToken[@"refresh_token"], 202 | @"user_id": accessToken[@"user_id"], 203 | }; 204 | 205 | // User ID 206 | dictionary[@"id"] = account[@"id"]; 207 | 208 | // Raw response 209 | dictionary[@"extra"] = @{ 210 | @"raw_info" : account 211 | }; 212 | 213 | // User info 214 | NSMutableDictionary *user = [NSMutableDictionary new]; 215 | user[@"name"] = account[@"name"]; 216 | dictionary[@"info"] = user; 217 | 218 | return dictionary; 219 | } 220 | 221 | @end 222 | -------------------------------------------------------------------------------- /Pod/Providers/GoogleWeb/SimpleAuthGoogleWebProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthGoogleWebProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by Ramon Vicente on 2/24/15. 6 | // Copyright (c) 2015 UMOBI. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthGoogleWebProvider.h" 10 | #import "SimpleAuthGoogleWebLoginViewController.h" 11 | 12 | #import "UIViewController+SimpleAuthAdditions.h" 13 | 14 | @implementation SimpleAuthGoogleWebProvider 15 | 16 | #pragma mark - SimpleAuthProvider 17 | 18 | + (NSString *)type { 19 | return @"google-web"; 20 | } 21 | 22 | + (NSDictionary *)defaultOptions { 23 | 24 | // Default present block 25 | SimpleAuthInterfaceHandler presentBlock = ^(UIViewController *controller) { 26 | UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller]; 27 | navigationController.modalPresentationStyle = UIModalPresentationFormSheet; 28 | UIViewController *presentedViewController = [UIViewController SimpleAuth_presentedViewController]; 29 | [presentedViewController presentViewController:navigationController 30 | animated:YES 31 | completion:nil]; 32 | }; 33 | 34 | // Default dismiss block 35 | SimpleAuthInterfaceHandler dismissBlock = ^(id viewController) { 36 | [viewController dismissViewControllerAnimated:YES 37 | completion:nil]; 38 | }; 39 | 40 | NSMutableDictionary *options = [NSMutableDictionary dictionaryWithDictionary:[super defaultOptions]]; 41 | options[SimpleAuthPresentInterfaceBlockKey] = presentBlock; 42 | options[SimpleAuthDismissInterfaceBlockKey] = dismissBlock; 43 | options[SimpleAuthRedirectURIKey] = @"http://localhost"; 44 | options[@"scope"] = @"email openid profile"; 45 | return options; 46 | } 47 | 48 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 49 | dispatch_async(dispatch_get_main_queue(), ^{ 50 | SimpleAuthGoogleWebLoginViewController *loginViewController = [[SimpleAuthGoogleWebLoginViewController alloc] initWithOptions:self.options]; 51 | loginViewController.completion = ^(UIViewController *viewController, NSURL *URL, NSError *error) { 52 | SimpleAuthInterfaceHandler dismissBlock = self.options[SimpleAuthDismissInterfaceBlockKey]; 53 | dismissBlock(viewController); 54 | 55 | NSString *query = [URL query]; 56 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:query]; 57 | NSString *code = dictionary[@"code"]; 58 | if ([code length] > 0) { 59 | [self userWithCode:code 60 | completion:completion]; 61 | } else { 62 | completion(nil, error); 63 | } 64 | }; 65 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthPresentInterfaceBlockKey]; 66 | block(loginViewController); 67 | }); 68 | } 69 | 70 | #pragma mark - Private 71 | - (void)userWithCode:(NSString *)code completion:(SimpleAuthRequestHandler)completion 72 | { 73 | NSDictionary *parameters = @{ @"code" : code, 74 | @"client_id" : self.options[@"client_id"], 75 | @"client_secret" : self.options[@"client_secret"], 76 | @"redirect_uri": self.options[@"redirect_uri"], 77 | @"grant_type": @"authorization_code"}; 78 | 79 | NSString *data = [CMDQueryStringSerialization queryStringWithDictionary:parameters]; 80 | 81 | NSString *URLString = [NSString stringWithFormat:@"https://accounts.google.com/o/oauth2/token"]; 82 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URLString]]; 83 | [request setHTTPMethod:@"POST"]; 84 | [request setHTTPBody:[data dataUsingEncoding:NSUTF8StringEncoding]]; 85 | 86 | [NSURLConnection sendAsynchronousRequest:request 87 | queue:self.operationQueue 88 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 89 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 90 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 91 | if ([indexSet containsIndex:statusCode] && data) { 92 | NSError *parseError; 93 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data 94 | options:kNilOptions 95 | error:&parseError]; 96 | NSString *token = dictionary[@"access_token"]; 97 | if ([token length] > 0) { 98 | 99 | NSDictionary *credentials = @{ 100 | @"access_token" : token, 101 | @"expires" : [NSDate dateWithTimeIntervalSinceNow:[dictionary[@"expires_in"] doubleValue]], 102 | @"token_type" : @"bearer", 103 | @"id_token": dictionary[@"id_token"] 104 | }; 105 | 106 | [self userWithCredentials:credentials 107 | completion:completion]; 108 | } else { 109 | completion(nil, parseError); 110 | } 111 | 112 | } else { 113 | completion(nil, connectionError); 114 | } 115 | }]; 116 | } 117 | 118 | - (void)userWithCredentials:(NSDictionary *)credentials completion:(SimpleAuthRequestHandler)completion { 119 | 120 | NSString *URLString = [NSString stringWithFormat:@"https://www.googleapis.com/userinfo/v2/me"]; 121 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URLString]]; 122 | 123 | [request setValue:[NSString stringWithFormat:@"Bearer %@", credentials[@"access_token"]] forHTTPHeaderField:@"Authorization"]; 124 | 125 | [NSURLConnection sendAsynchronousRequest:request 126 | queue:self.operationQueue 127 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 128 | 129 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 130 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 131 | if ([indexSet containsIndex:statusCode] && data) { 132 | NSError *parseError; 133 | NSDictionary *userInfo = [NSJSONSerialization JSONObjectWithData:data 134 | options:kNilOptions 135 | error:&parseError]; 136 | if (userInfo) { 137 | completion ([self dictionaryWithAccount:userInfo credentials:credentials], nil); 138 | } else { 139 | completion(nil, parseError); 140 | } 141 | } else { 142 | completion(nil, connectionError); 143 | } 144 | }]; 145 | } 146 | 147 | - (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account 148 | credentials:(NSDictionary *)credentials 149 | { 150 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 151 | 152 | // Provider 153 | dictionary[@"provider"] = [[self class] type]; 154 | 155 | // Credentials 156 | dictionary[@"credentials"] = @{ 157 | @"token" : credentials[@"access_token"], 158 | @"expires_at" : credentials[@"expires"] 159 | }; 160 | 161 | // User ID 162 | dictionary[@"uid"] = account[@"id"]; 163 | 164 | // Raw response 165 | dictionary[@"extra"] = @{ 166 | @"raw_info" : account 167 | }; 168 | 169 | // Location 170 | NSString *location = account[@"location"][@"name"]; 171 | 172 | // User info 173 | NSMutableDictionary *user = [NSMutableDictionary new]; 174 | if (account[@"email"]) { 175 | user[@"email"] = account[@"email"]; 176 | } 177 | user[@"name"] = account[@"name"]; 178 | user[@"first_name"] = account[@"given_name"]; 179 | user[@"last_name"] = account[@"family_name"]; 180 | user[@"gender"] = account[@"gender"]; 181 | 182 | user[@"image"] = account[@"picture"]; 183 | if (location) { 184 | user[@"location"] = location; 185 | } 186 | user[@"verified"] = account[@"verified_email"] ? @YES : @NO; 187 | user[@"urls"] = @{ 188 | @"Google +" : account[@"link"], 189 | }; 190 | 191 | dictionary[@"info"] = user; 192 | 193 | return dictionary; 194 | } 195 | 196 | @end 197 | -------------------------------------------------------------------------------- /Pod/Providers/Tumblr/SimpleAuthTumblrProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleAuthTumblrProvider.m 3 | // SimpleAuth 4 | // 5 | // Created by Caleb Davenport on 1/16/14. 6 | // Copyright (c) 2014 Byliner, Inc. All rights reserved. 7 | // 8 | 9 | #import "SimpleAuthTumblrProvider.h" 10 | #import "SimpleAuthTumblrLoginViewController.h" 11 | 12 | #import "UIViewController+SimpleAuthAdditions.h" 13 | #import 14 | #import 15 | 16 | @implementation SimpleAuthTumblrProvider 17 | 18 | #pragma mark - SimpleAuthProvider 19 | 20 | + (NSString *)type { 21 | return @"tumblr"; 22 | } 23 | 24 | 25 | + (NSDictionary *)defaultOptions { 26 | 27 | // Default present block 28 | SimpleAuthInterfaceHandler presentBlock = ^(UIViewController *controller) { 29 | UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller]; 30 | navigation.modalPresentationStyle = UIModalPresentationFormSheet; 31 | UIViewController *presented = [UIViewController SimpleAuth_presentedViewController]; 32 | [presented presentViewController:navigation animated:YES completion:nil]; 33 | }; 34 | 35 | // Default dismiss block 36 | SimpleAuthInterfaceHandler dismissBlock = ^(id controller) { 37 | [controller dismissViewControllerAnimated:YES completion:nil]; 38 | }; 39 | 40 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithDictionary:[super defaultOptions]]; 41 | dictionary[SimpleAuthPresentInterfaceBlockKey] = presentBlock; 42 | dictionary[SimpleAuthDismissInterfaceBlockKey] = dismissBlock; 43 | dictionary[SimpleAuthRedirectURIKey] = @"simple-auth://tumblr.auth"; 44 | return dictionary; 45 | } 46 | 47 | 48 | - (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion { 49 | [[[[[self requestToken] 50 | flattenMap:^(NSDictionary *response) { 51 | NSArray *signals = @[ 52 | [RACSignal return:response], 53 | [self authenticateWithRequestToken:response] 54 | ]; 55 | return [RACSignal zip:signals]; 56 | }] 57 | flattenMap:^(RACTuple *response) { 58 | return [self accessTokenWithRequestToken:response.first authenticationResponse:response.second]; 59 | }] 60 | flattenMap:^(NSDictionary *response) { 61 | NSArray *signals = @[ 62 | [self accountWithAccessToken:response], 63 | [RACSignal return:response] 64 | ]; 65 | return [self rac_liftSelector:@selector(dictionaryWithAccount:accessToken:) withSignalsFromArray:signals]; 66 | }] 67 | subscribeNext:^(NSDictionary *response) { 68 | completion(response, nil); 69 | } 70 | error:^(NSError *error) { 71 | completion(nil, error); 72 | }]; 73 | } 74 | 75 | 76 | #pragma mark - Private 77 | 78 | - (RACSignal *)requestToken { 79 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 80 | NSDictionary *parameters = @{ @"oauth_callback" : self.options[SimpleAuthRedirectURIKey] }; 81 | NSURLRequest *request = [GCOAuth 82 | URLRequestForPath:@"/oauth/request_token" 83 | POSTParameters:parameters 84 | scheme:@"https" 85 | host:@"www.tumblr.com" 86 | consumerKey:self.options[@"consumer_key"] 87 | consumerSecret:self.options[@"consumer_secret"] 88 | accessToken:nil 89 | tokenSecret:nil]; 90 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 91 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 92 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 93 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 94 | if ([indexSet containsIndex:statusCode] && data) { 95 | NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 96 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:string]; 97 | [subscriber sendNext:dictionary]; 98 | [subscriber sendCompleted]; 99 | } 100 | else { 101 | [subscriber sendError:connectionError]; 102 | } 103 | }]; 104 | return nil; 105 | }]; 106 | } 107 | 108 | 109 | - (RACSignal *)authenticateWithRequestToken:(NSDictionary *)requestToken { 110 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 111 | dispatch_async(dispatch_get_main_queue(), ^{ 112 | SimpleAuthTumblrLoginViewController *login = [[SimpleAuthTumblrLoginViewController alloc] initWithOptions:self.options requestToken:requestToken]; 113 | 114 | login.completion = ^(UIViewController *controller, NSURL *URL, NSError *error) { 115 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthDismissInterfaceBlockKey]; 116 | block(controller); 117 | 118 | // Parse URL 119 | NSString *query = [URL query]; 120 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:query]; 121 | NSString *token = dictionary[@"oauth_token"]; 122 | NSString *verifier = dictionary[@"oauth_verifier"]; 123 | 124 | // Check for error 125 | if (![token length] || ![verifier length]) { 126 | [subscriber sendError:error]; 127 | return; 128 | } 129 | 130 | // Send completion 131 | [subscriber sendNext:dictionary]; 132 | [subscriber sendCompleted]; 133 | }; 134 | 135 | SimpleAuthInterfaceHandler block = self.options[SimpleAuthPresentInterfaceBlockKey]; 136 | block(login); 137 | }); 138 | return nil; 139 | }]; 140 | } 141 | 142 | 143 | - (RACSignal *)accessTokenWithRequestToken:(NSDictionary *)requestToken authenticationResponse:(NSDictionary *)authenticationResponse { 144 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 145 | NSDictionary *parameters = @{ @"oauth_verifier" : authenticationResponse[@"oauth_verifier"] }; 146 | NSURLRequest *request = [GCOAuth 147 | URLRequestForPath:@"/oauth/access_token" 148 | POSTParameters:parameters 149 | scheme:@"https" 150 | host:@"www.tumblr.com" 151 | consumerKey:self.options[@"consumer_key"] 152 | consumerSecret:self.options[@"consumer_secret"] 153 | accessToken:authenticationResponse[@"oauth_token"] 154 | tokenSecret:requestToken[@"oauth_token_secret"]]; 155 | [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue 156 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 157 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 158 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 159 | if ([indexSet containsIndex:statusCode] && data) { 160 | NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 161 | NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:string]; 162 | [subscriber sendNext:dictionary]; 163 | [subscriber sendCompleted]; 164 | } 165 | else { 166 | [subscriber sendError:connectionError]; 167 | } 168 | }]; 169 | return nil; 170 | }]; 171 | } 172 | 173 | 174 | - (RACSignal *)accountWithAccessToken:(NSDictionary *)accessToken { 175 | return [RACSignal createSignal:^RACDisposable *(id subscriber) { 176 | NSURLRequest *request = [GCOAuth 177 | URLRequestForPath:@"/v2/user/info" 178 | GETParameters:nil 179 | scheme:@"https" 180 | host:@"api.tumblr.com" 181 | consumerKey:self.options[@"consumer_key"] 182 | consumerSecret:self.options[@"consumer_secret"] 183 | accessToken:accessToken[@"oauth_token"] 184 | tokenSecret:accessToken[@"oauth_token_secret"]]; 185 | [NSURLConnection 186 | sendAsynchronousRequest:request 187 | queue:self.operationQueue 188 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 189 | NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)]; 190 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; 191 | if ([indexSet containsIndex:statusCode] && data) { 192 | NSError *parseError = nil; 193 | NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError]; 194 | if (dictionary) { 195 | dictionary = dictionary[@"response"][@"user"]; 196 | [subscriber sendNext:dictionary]; 197 | [subscriber sendCompleted]; 198 | } 199 | else { 200 | [subscriber sendError:parseError]; 201 | } 202 | } 203 | else { 204 | [subscriber sendError:connectionError]; 205 | } 206 | }]; 207 | return nil; 208 | }]; 209 | } 210 | 211 | 212 | - (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account accessToken:(NSDictionary *)accessToken { 213 | NSMutableDictionary *dictionary = [NSMutableDictionary new]; 214 | 215 | // Provider 216 | dictionary[@"provider"] = [[self class] type]; 217 | 218 | // Credentials 219 | dictionary[@"credentials"] = @{ 220 | @"token" : accessToken[@"oauth_token"], 221 | @"secret" : accessToken[@"oauth_token_secret"] 222 | }; 223 | 224 | // User ID 225 | dictionary[@"uid"] = account[@"name"]; 226 | 227 | // Extra 228 | dictionary[@"extra"] = @{ 229 | @"raw_info" : account, 230 | }; 231 | 232 | // Blogs 233 | NSArray *blogs = account[@"blogs"]; 234 | blogs = [[blogs.rac_sequence map:^(NSDictionary *dictionary) { 235 | return [dictionary dictionaryWithValuesForKeys:@[ @"name", @"url", @"title" ]]; 236 | }] array]; 237 | 238 | // Profile image 239 | NSString *blogURLString = blogs[0][@"url"]; 240 | NSURL *blogURL = [NSURL URLWithString:blogURLString]; 241 | NSString *host = [blogURL host]; 242 | NSString *avatar = [NSString stringWithFormat:@"https://api.tumblr.com/v2/blog/%@/avatar", host]; 243 | 244 | // User info 245 | NSMutableDictionary *user = [NSMutableDictionary new]; 246 | user[@"nickname"] = account[@"name"]; 247 | user[@"name"] = account[@"name"]; 248 | user[@"blogs"] = blogs; 249 | user[@"image"] = avatar; 250 | dictionary[@"info"] = user; 251 | 252 | return dictionary; 253 | } 254 | 255 | @end 256 | --------------------------------------------------------------------------------