diff --git a/Example/Podfile.lock b/Example/Podfile.lock
index 826f91f..1f2e363 100644
--- a/Example/Podfile.lock
+++ b/Example/Podfile.lock
@@ -15,6 +15,7 @@ PODS:
- SimpleAuth (0.3.9):
- SimpleAuth/BoxWeb (= 0.3.9)
- SimpleAuth/Core (= 0.3.9)
+ - SimpleAuth/ConstantContact (= 0.3.9)
- SimpleAuth/DropboxWeb (= 0.3.9)
- SimpleAuth/Facebook (= 0.3.9)
- SimpleAuth/FacebookWeb (= 0.3.9)
@@ -36,6 +37,8 @@ PODS:
- SimpleAuth/Core (0.3.9):
- CMDQueryStringSerialization
- ReactiveCocoa
+ - SimpleAuth/ConstantContact (0.3.9):
+ - SimpleAuth/Core
- SimpleAuth/DropboxWeb (0.3.9):
- SimpleAuth/Core
- SimpleAuth/Facebook (0.3.9):
diff --git a/Example/SimpleAuth/Providers.plist b/Example/SimpleAuth/Providers.plist
index efa2451..4765ea8 100644
--- a/Example/SimpleAuth/Providers.plist
+++ b/Example/SimpleAuth/Providers.plist
@@ -19,5 +19,6 @@
trello-web
box-web
onedrive-web
+ constantcontact
diff --git a/Example/SimpleAuth/SADAppDelegate.m b/Example/SimpleAuth/SADAppDelegate.m
index 98a5cb2..bf8a34f 100644
--- a/Example/SimpleAuth/SADAppDelegate.m
+++ b/Example/SimpleAuth/SADAppDelegate.m
@@ -88,6 +88,9 @@ - (void)configureAuthorizaionProviders {
// client_id and client_secret are required
SimpleAuth.configuration[@"onedrive-web"] = @{};
+
+ // client_id, redirect_uri are required
+ SimpleAuth.configuration[@"constantcontact"] = @{};
}
diff --git a/Pod/Providers/ConstantContact/SimpleAuthConstantContactConstants.h b/Pod/Providers/ConstantContact/SimpleAuthConstantContactConstants.h
new file mode 100644
index 0000000..37ec970
--- /dev/null
+++ b/Pod/Providers/ConstantContact/SimpleAuthConstantContactConstants.h
@@ -0,0 +1,15 @@
+//
+// SimpleAuthConstantContactConstants.h
+// SimpleAuth
+//
+// Created by Tal Kain .
+// Copyright (c) 2015 Fire Place Inc. All rights reserved.
+//
+
+#ifndef SimpleAuthConstantContactConstants_h
+#define SimpleAuthConstantContactConstants_h
+
+FOUNDATION_EXPORT NSString *const CONSTANT_CONTACT_AUTHORIZE_URI;
+FOUNDATION_EXPORT NSString *const CONSTANT_CONTACT_INFO_END_POINT_URI;
+
+#endif /* SimpleAuthConstantContactConstants_h */
diff --git a/Pod/Providers/ConstantContact/SimpleAuthConstantContactConstants.m b/Pod/Providers/ConstantContact/SimpleAuthConstantContactConstants.m
new file mode 100644
index 0000000..af5ee94
--- /dev/null
+++ b/Pod/Providers/ConstantContact/SimpleAuthConstantContactConstants.m
@@ -0,0 +1,12 @@
+//
+// SimpleAuthConstantContactConstants.m
+// SimpleAuth
+//
+// Created by Tal Kain .
+// Copyright (c) 2015 Fire Place Inc. All rights reserved.
+//
+
+// Based on https://developer.constantcontact.com/docs/authentication/oauth-2.0-client-flow.html
+
+NSString *const CONSTANT_CONTACT_AUTHORIZE_URI = @"https://oauth2.constantcontact.com/oauth2/oauth/siteowner/authorize";
+NSString *const CONSTANT_CONTACT_INFO_END_POINT_URI = @"https://api.constantcontact.com/v2/account/info";
diff --git a/Pod/Providers/ConstantContact/SimpleAuthConstantContactLoginViewController.h b/Pod/Providers/ConstantContact/SimpleAuthConstantContactLoginViewController.h
new file mode 100644
index 0000000..e528d68
--- /dev/null
+++ b/Pod/Providers/ConstantContact/SimpleAuthConstantContactLoginViewController.h
@@ -0,0 +1,14 @@
+//
+// SimpleAuthConstantContactLoginViewController.h
+// SimpleAuth
+//
+// Created by Tal Kain .
+// Based on BoxWeb's provider created by dkhamsing and FoursquareWeb's provider created by Julien Seren-Rosso
+// Copyright (c) 2015 Fire Place Inc. All rights reserved.
+//
+
+#import "SimpleAuthWebViewController.h"
+
+@interface SimpleAuthConstantContactLoginViewController : SimpleAuthWebViewController
+
+@end
diff --git a/Pod/Providers/ConstantContact/SimpleAuthConstantContactLoginViewController.m b/Pod/Providers/ConstantContact/SimpleAuthConstantContactLoginViewController.m
new file mode 100644
index 0000000..049dbb5
--- /dev/null
+++ b/Pod/Providers/ConstantContact/SimpleAuthConstantContactLoginViewController.m
@@ -0,0 +1,38 @@
+//
+// SimpleAuthConstantContactLoginViewController.m
+// SimpleAuth
+//
+// Created by Tal Kain .
+// Based on BoxWeb's provider created by dkhamsing and FoursquareWeb's provider created by Julien Seren-Rosso
+// Copyright (c) 2015 Fire Place Inc. All rights reserved.
+//
+
+#import "SimpleAuthConstantContactLoginViewController.h"
+#import "SimpleAuthConstantContactConstants.h"
+
+@implementation SimpleAuthConstantContactLoginViewController
+
+#pragma mark - SimpleAuthWebViewController
+
+- (instancetype)initWithOptions:(NSDictionary *)options requestToken:(NSDictionary *)requestToken {
+ if ((self = [super initWithOptions:options requestToken:requestToken])) {
+ self.title = @"ConstantContact";
+ }
+ return self;
+}
+
+- (NSURLRequest *)initialRequest {
+ NSDictionary *parameters = @{
+ @"client_id" : self.options[@"client_id"],
+ @"redirect_uri" : self.options[SimpleAuthRedirectURIKey],
+ @"response_type" : @"token"
+ };
+ NSString *URLString = [NSString stringWithFormat:@"%@?%@",
+ CONSTANT_CONTACT_AUTHORIZE_URI,
+ [CMDQueryStringSerialization queryStringWithDictionary:parameters]];
+ NSURL *URL = [NSURL URLWithString:URLString];
+
+ return [NSURLRequest requestWithURL:URL];
+}
+
+@end
diff --git a/Pod/Providers/ConstantContact/SimpleAuthConstantContactProvider.h b/Pod/Providers/ConstantContact/SimpleAuthConstantContactProvider.h
new file mode 100644
index 0000000..3561045
--- /dev/null
+++ b/Pod/Providers/ConstantContact/SimpleAuthConstantContactProvider.h
@@ -0,0 +1,14 @@
+//
+// SimpleAuthConstantContactProvider.h
+// SimpleAuth
+//
+// Created by Tal Kain .
+// Based on BoxWeb's provider created by dkhamsing and FoursquareWeb's provider created by Julien Seren-Rosso
+// Copyright (c) 2015 Fire Place Inc. All rights reserved.
+//
+
+#import "SimpleAuthProvider.h"
+
+@interface SimpleAuthConstantContactProvider : SimpleAuthProvider
+
+@end
diff --git a/Pod/Providers/ConstantContact/SimpleAuthConstantContactProvider.m b/Pod/Providers/ConstantContact/SimpleAuthConstantContactProvider.m
new file mode 100644
index 0000000..9331597
--- /dev/null
+++ b/Pod/Providers/ConstantContact/SimpleAuthConstantContactProvider.m
@@ -0,0 +1,162 @@
+//
+// SimpleAuthConstantContactProvider.m
+// SimpleAuth
+//
+// Created by Tal Kain .
+// Based on BoxWeb's provider created by dkhamsing and FoursquareWeb's provider created by Julien Seren-Rosso
+// Copyright (c) 2015 Fire Place Inc. All rights reserved.
+//
+
+#import "SimpleAuthConstantContactProvider.h"
+#import "SimpleAuthConstantContactLoginViewController.h"
+#import "SimpleAuthConstantContactConstants.h"
+
+#import
+#import "UIViewController+SimpleAuthAdditions.h"
+
+@implementation SimpleAuthConstantContactProvider
+
+#pragma mark - SimpleAuthProvider
+
++ (NSString *)type {
+ return @"constantcontact";
+}
+
+
++ (NSDictionary *)defaultOptions {
+
+ // Default present block
+ SimpleAuthInterfaceHandler presentBlock = ^(UIViewController *controller) {
+ UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:controller];
+ navigation.modalPresentationStyle = UIModalPresentationFormSheet;
+ UIViewController *presented = [UIViewController SimpleAuth_presentedViewController];
+ [presented presentViewController:navigation animated:YES completion:nil];
+ };
+
+ // Default dismiss block
+ SimpleAuthInterfaceHandler dismissBlock = ^(id controller) {
+ [controller dismissViewControllerAnimated:YES completion:nil];
+ };
+
+ NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithDictionary:[super defaultOptions]];
+ dictionary[SimpleAuthPresentInterfaceBlockKey] = presentBlock;
+ dictionary[SimpleAuthDismissInterfaceBlockKey] = dismissBlock;
+ return dictionary;
+}
+
+
+- (void)authorizeWithCompletion:(SimpleAuthRequestHandler)completion {
+ [[[self accessToken]
+ flattenMap:^(NSDictionary *response) {
+ NSArray *signals = @[
+ [self accountWithAccessToken:response],
+ [RACSignal return:response]
+ ];
+ return [self rac_liftSelector:@selector(dictionaryWithAccount:accessToken:) withSignalsFromArray:signals];
+ }]
+ subscribeNext:^(NSDictionary *response) {
+ completion(response, nil);
+ }
+ error:^(NSError *error) {
+ completion(nil, error);
+ }];
+}
+
+#pragma mark - Private
+
+
+- (RACSignal *)accessToken {
+ return [RACSignal createSignal:^RACDisposable *(id subscriber) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ SimpleAuthConstantContactLoginViewController *login = [[SimpleAuthConstantContactLoginViewController alloc] initWithOptions:self.options];
+ login.completion = ^(UIViewController *login, NSURL *URL, NSError *error) {
+ SimpleAuthInterfaceHandler dismissBlock = self.options[SimpleAuthDismissInterfaceBlockKey];
+ dismissBlock(login);
+
+ // Parse URL
+ NSString *fragment = [URL fragment];
+ NSDictionary *dictionary = [CMDQueryStringSerialization dictionaryWithQueryString:fragment];
+ NSString *token = dictionary[@"access_token"];
+
+ // Check for error
+ if (![token length]) {
+ [subscriber sendError:error];
+ return;
+ }
+
+ // Send completion
+ [subscriber sendNext:token];
+ [subscriber sendCompleted];
+ };
+
+ SimpleAuthInterfaceHandler block = self.options[SimpleAuthPresentInterfaceBlockKey];
+ block(login);
+ });
+ return nil;
+ }];
+}
+
+- (RACSignal *)accountWithAccessToken:(NSDictionary *)accessToken {
+ return [RACSignal createSignal:^RACDisposable *(id subscriber) {
+ NSDictionary *parameters = @{ @"api_key" : self.options[@"client_id"] };
+ NSString *query = [CMDQueryStringSerialization queryStringWithDictionary:parameters];
+ NSString *URLString = [NSString stringWithFormat:@"%@?%@", CONSTANT_CONTACT_INFO_END_POINT_URI, query];
+
+ NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URLString]];
+ NSString *oauthCode = [NSString stringWithFormat:@"Bearer %@", accessToken];
+ [request setValue:oauthCode forHTTPHeaderField:@"Authorization"];
+ [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue
+ completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
+ NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 99)];
+ NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
+ if ([indexSet containsIndex:statusCode] && data) {
+ NSError *parseError = nil;
+ NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError];
+ if (dictionary) {
+ [subscriber sendNext:dictionary];
+ [subscriber sendCompleted];
+ }
+ else {
+ [subscriber sendError:parseError];
+ }
+ }
+ else {
+ [subscriber sendError:connectionError];
+ }
+ }];
+ return nil;
+ }];
+}
+
+
+- (NSDictionary *)dictionaryWithAccount:(NSDictionary *)account accessToken:(NSDictionary *)accessToken {
+ NSMutableDictionary *dictionary = [NSMutableDictionary new];
+
+ // Provider
+ dictionary[@"provider"] = [[self class] type];
+
+ // Credentials
+ dictionary[@"credentials"] = @{
+ @"token" : accessToken,
+ @"type" : @"token",
+ };
+
+ // User ID
+ dictionary[@"id"] = account[@"email"];
+
+ // Raw response
+ dictionary[@"extra"] = @{
+ @"raw_info" : account
+ };
+
+ // User info
+ NSMutableDictionary *user = [NSMutableDictionary new];
+ user[@"login"] = account[@"email"];
+ user[@"name"] = [NSString stringWithFormat:@"%@ %@", account[@"first_name"], account[@"last_name"]];
+ user[@"phone"] = account[@"phone"];
+ dictionary[@"info"] = user;
+
+ return dictionary;
+}
+
+@end
diff --git a/SimpleAuth.podspec b/SimpleAuth.podspec
index 6125ab9..685ef4c 100755
--- a/SimpleAuth.podspec
+++ b/SimpleAuth.podspec
@@ -128,4 +128,9 @@ Pod::Spec.new do |s|
ss.private_header_files = 'Pod/Providers/OneDriveWeb/*.h'
end
+ s.subspec 'ConstantContact' do |ss|
+ ss.dependency 'SimpleAuth/Core'
+ ss.source_files = 'Pod/Providers/ConstantContact'
+ ss.private_header_files = 'Pod/Providers/ConstantContact/*.h'
+ end
end