forked from jessegrosjean/NOTTaskPaperForIOS
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDBSession+iOS.m
More file actions
executable file
·148 lines (118 loc) · 5.56 KB
/
Copy pathDBSession+iOS.m
File metadata and controls
executable file
·148 lines (118 loc) · 5.56 KB
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
//
// DBSession+iOS.m
// DropboxSDK
//
// Created by Brian Smith on 3/7/12.
// Copyright (c) 2012 Dropbox. All rights reserved.
//
#import "DBSession+iOS.h"
#import <CommonCrypto/CommonDigest.h>
#import "DBConnectController.h"
#import "DBLog.h"
static NSString *kDBProtocolDropbox = @"dbapi-2";
/* A key to keep track of the nonce for the current link flow */
static NSString *kDBLinkNonce = @"dropbox.sync.nonce";
@implementation DBSession (iOS)
+ (NSDictionary*)parseURLParams:(NSString *)query {
NSArray *pairs = [query componentsSeparatedByString:@"&"];
NSMutableDictionary *params = [[[NSMutableDictionary alloc] init] autorelease];
for (NSString *pair in pairs) {
NSArray *kv = [pair componentsSeparatedByString:@"="];
NSString *val =
[[kv objectAtIndex:1]
stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[params setObject:val forKey:[kv objectAtIndex:0]];
}
return params;
}
- (NSString *)appScheme {
NSString *consumerKey = [baseCredentials objectForKey:kMPOAuthCredentialConsumerKey];
return [NSString stringWithFormat:@"db-%@", consumerKey];
}
- (BOOL)appConformsToScheme {
NSString *appScheme = [self appScheme];
NSDictionary *loadedPlist = [[NSBundle mainBundle] infoDictionary];
NSArray *urlTypes = [loadedPlist objectForKey:@"CFBundleURLTypes"];
for (NSDictionary *urlType in urlTypes) {
NSArray *schemes = [urlType objectForKey:@"CFBundleURLSchemes"];
for (NSString *scheme in schemes) {
if ([scheme isEqual:appScheme]) {
return YES;
}
}
}
return NO;
}
- (void)linkUserId:(NSString *)userId fromController:(UIViewController *)rootController {
if (![self appConformsToScheme]) {
DBLogError(@"DropboxSDK: unable to link; app isn't registered for correct URL scheme (%@)", [self appScheme]);
return;
}
extern NSString *kDBDropboxUnknownUserId;
NSString *userIdStr = @"";
if (userId && ![userId isEqual:kDBDropboxUnknownUserId]) {
userIdStr = [NSString stringWithFormat:@"&u=%@", userId];
}
NSString *consumerKey = [baseCredentials objectForKey:kMPOAuthCredentialConsumerKey];
NSData *consumerSecret =
[[baseCredentials objectForKey:kMPOAuthCredentialConsumerSecret] dataUsingEncoding:NSUTF8StringEncoding];
unsigned char md[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(consumerSecret.bytes, [consumerSecret length], md);
NSUInteger sha_32 = htonl(((NSUInteger *)md)[CC_SHA1_DIGEST_LENGTH/sizeof(NSUInteger) - 1]);
NSString *secret = [NSString stringWithFormat:@"%x", sha_32];
CFUUIDRef uuid = CFUUIDCreate(NULL);
CFStringRef uuid_str = CFUUIDCreateString(NULL, uuid);
CFRelease(uuid);
NSString *nonce = [(NSString *)uuid_str autorelease];
[[NSUserDefaults standardUserDefaults] setObject:nonce forKey:kDBLinkNonce];
[[NSUserDefaults standardUserDefaults] synchronize];
NSString *urlStr = nil;
NSURL *dbURL =
[NSURL URLWithString:[NSString stringWithFormat:@"%@://%@/connect", kDBProtocolDropbox, kDBDropboxAPIVersion]];
if ([[UIApplication sharedApplication] canOpenURL:dbURL]) {
urlStr = [NSString stringWithFormat:@"%@?k=%@&s=%@&state=%@%@",
dbURL, consumerKey, secret, nonce, userIdStr];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlStr]];
} else {
urlStr = [NSString stringWithFormat:@"%@://%@/%@/connect_login?k=%@&s=%@&state=%@&easl=1%@",
kDBProtocolHTTPS, kDBDropboxWebHost, kDBDropboxAPIVersion,
consumerKey, secret, nonce, userIdStr];
UIViewController *connectController = [[[DBConnectController alloc] initWithUrl:[NSURL URLWithString:urlStr] fromController:rootController session:self] autorelease];
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:connectController] autorelease];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
connectController.modalPresentationStyle = UIModalPresentationFormSheet;
navController.modalPresentationStyle = UIModalPresentationFormSheet;
}
[rootController presentModalViewController:navController animated:YES];
}
}
- (void)linkFromController:(UIViewController *)rootController {
[self linkUserId:nil fromController:rootController];
}
- (BOOL)handleOpenURL:(NSURL *)url {
NSString *expected = [NSString stringWithFormat:@"%@://%@/", [self appScheme], kDBDropboxAPIVersion];
if (![[url absoluteString] hasPrefix:expected]) {
return NO;
}
NSArray *components = [[url path] pathComponents];
NSString *methodName = [components count] > 1 ? [components objectAtIndex:1] : nil;
if ([methodName isEqual:@"connect"]) {
NSDictionary *params = [DBSession parseURLParams:[url query]];
NSString *token = [params objectForKey:@"oauth_token"];
NSString *secret = [params objectForKey:@"oauth_token_secret"];
NSString *userId = [params objectForKey:@"uid"];
NSString *state = [params objectForKey:@"state"];
NSString *nonce = [[NSUserDefaults standardUserDefaults] objectForKey:kDBLinkNonce];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kDBLinkNonce];
[[NSUserDefaults standardUserDefaults] synchronize];
if (![nonce isEqual:state]) {
DBLogError(@"unable to verify link request");
return NO;
}
[self updateAccessToken:token accessTokenSecret:secret forUserId:userId];
} else if ([methodName isEqual:@"cancel"]) {
DBLogInfo(@"DropboxSDK: user cancelled Dropbox link");
}
return YES;
}
@end