Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: remoting/client/ios/facade/remoting_authentication.mm

Issue 2854273002: [CRD iOS] Implementing save to keychain and user defaults for login info. Refactor remoting service. (Closed)
Patch Set: Cleanup on self review. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #if !defined(__has_feature) || !__has_feature(objc_arc)
6 #error "This file requires ARC support."
7 #endif
8
9 #import "remoting/client/ios/facade/remoting_authentication.h"
10
11 #import <Foundation/Foundation.h>
12 #import <Security/Security.h>
13
14 #import "base/mac/bind_objc_block.h"
15 #import "remoting/client/ios/facade/host_info.h"
16 #import "remoting/client/ios/facade/host_list_fetcher.h"
17 #import "remoting/client/ios/facade/ios_client_runtime_delegate.h"
18 #import "remoting/client/ios/facade/remoting_service.h"
19 #import "remoting/client/ios/keychain_wrapper.h"
20
21 #include "base/logging.h"
22 #include "base/strings/sys_string_conversions.h"
23 #include "net/url_request/url_request_context_getter.h"
24 #include "remoting/base/oauth_token_getter.h"
25 #include "remoting/base/oauth_token_getter_impl.h"
26
27 static NSString* const kCRDAuthenticatedUserEmailKey =
28 @"kCRDAuthenticatedUserEmailKey";
29
30 const char kOauthRedirectUrl[] =
Yuwei 2017/05/04 05:10:14 Put const and functions below inside an empty name
nicholss 2017/05/08 17:08:10 you get that for free inside a obj-c file.
31 "https://chromoting-oauth.talkgadget."
32 "google.com/talkgadget/oauth/chrome-remote-desktop/dev";
33
34 std::unique_ptr<remoting::OAuthTokenGetter>
35 CreateOAuthTokenGetterWithAuthorizationCode(
36 const std::string& auth_code,
37 const remoting::OAuthTokenGetter::CredentialsUpdatedCallback&
38 on_credentials_update) {
39 std::unique_ptr<remoting::OAuthTokenGetter::OAuthIntermediateCredentials>
40 oauth_credentials(
41 new remoting::OAuthTokenGetter::OAuthIntermediateCredentials(
42 auth_code, /*is_service_account=*/false));
43 oauth_credentials->oauth_redirect_uri = kOauthRedirectUrl;
44
45 std::unique_ptr<remoting::OAuthTokenGetter> oauth_tokenGetter(
46 new remoting::OAuthTokenGetterImpl(
47 std::move(oauth_credentials), on_credentials_update,
48 [[RemotingService SharedInstance] runtime]->url_requester(),
Yuwei 2017/05/04 05:10:14 Now that runtime is a property, use .runtime inste
nicholss 2017/05/08 17:08:10 Done.
49 /*auto_refresh=*/true));
50 return oauth_tokenGetter;
51 }
52
53 std::unique_ptr<remoting::OAuthTokenGetter> CreateOAuthTokenWithRefreshToken(
54 const std::string& refresh_token,
55 const std::string& email) {
56 std::unique_ptr<remoting::OAuthTokenGetter::OAuthAuthorizationCredentials>
57 oauth_credentials(
58 new remoting::OAuthTokenGetter::OAuthAuthorizationCredentials(
59 email, refresh_token, /*is_service_account=*/false));
60
61 std::unique_ptr<remoting::OAuthTokenGetter> oauth_tokenGetter(
62 new remoting::OAuthTokenGetterImpl(
63 std::move(oauth_credentials),
64 [[RemotingService SharedInstance] runtime]->url_requester(),
65 /*auto_refresh=*/true));
66 return oauth_tokenGetter;
67 }
68
69 @interface RemotingAuthentication () {
70 std::unique_ptr<remoting::OAuthTokenGetter> _tokenGetter;
71 UserInfo* _user;
72 KeychainWrapper* _keychainWrapper;
73 BOOL _firstLoadUserAttempt;
74 }
75 @end
76
77 @implementation RemotingAuthentication
78
79 @synthesize user = _user;
80 @synthesize delegate = _delegate;
81
82 - (instancetype)init {
83 self = [super init];
84 if (self) {
85 _keychainWrapper = [[KeychainWrapper alloc] init];
86 _user = nil;
87 _firstLoadUserAttempt = YES;
88 }
89 return self;
90 }
91
92 #pragma mark - Property Overrides
93
94 - (UserInfo*)user {
95 if (_firstLoadUserAttempt && _user == nil) {
96 _firstLoadUserAttempt = NO;
97 [self setUser:[self loadUserInfo]];
98 }
99 return _user;
100 }
101
102 - (void)setUser:(UserInfo*)user {
Yuwei 2017/05/04 05:10:14 Is this only privately used? If so maybe mark |use
nicholss 2017/05/08 17:08:10 The private _user was cruft. Removed. also switche
103 _user = user;
104 [_delegate userDidUpdate:_user];
Yuwei 2017/05/04 05:10:14 This will be called with nil _user if loadUserInfo
nicholss 2017/05/08 17:08:10 yes it is.
105 }
106
107 #pragma mark - Class Implementation
108
109 - (void)authenticateWithAuthorizationCode:(NSString*)authorizationCode {
110 _tokenGetter = CreateOAuthTokenGetterWithAuthorizationCode(
111 std::string(base::SysNSStringToUTF8(authorizationCode)),
112 base::BindBlockArc(
113 ^(const std::string& user_email, const std::string& refresh_token) {
114 // TODO(nicholss): Do something with these new creds.
115 VLOG(1) << "New Creds: " << user_email << " " << refresh_token;
116 _user = [[UserInfo alloc] init];
117 _user.userEmail = base::SysUTF8ToNSString(user_email);
118 _user.refreshToken = base::SysUTF8ToNSString(refresh_token);
119 [self storeUserInfo:_user];
Yuwei 2017/05/04 05:10:14 Use weakSelf? |credentials_updated_callback_| in t
nicholss 2017/05/08 17:08:10 Done.
120 }));
121 // Stimulate the oAuth Token Getter to fetch and access token, this forces it
122 // to convert the authorization code into a refresh token, and saving the
123 // refresh token will happen automaticly in the above block.
124 [self callbackWithAccessToken:base::BindBlockArc(^(
125 remoting::OAuthTokenGetter::Status status,
126 const std::string& user_email,
127 const std::string& access_token) {
128 if (status == remoting::OAuthTokenGetter::Status::SUCCESS) {
129 VLOG(1) << "Success fetching access token from authorization code.";
130 } else {
131 LOG(ERROR)
132 << "Failed to fetch access token from authorization code. ("
133 << status << ")";
134 }
135 })];
136 }
137
138 - (void)authenticateWithRefreshToken:(NSString*)refreshToken
139 email:(NSString*)email {
140 _tokenGetter = CreateOAuthTokenWithRefreshToken(
Yuwei 2017/05/04 05:10:14 Update _user and store here?
nicholss 2017/05/08 17:08:10 The refresh token comes from an active _user objec
Yuwei 2017/05/08 19:00:58 Shall we make this private or add comment about th
nicholss 2017/05/08 21:16:04 Yeah we can move it private. that works out ok
141 std::string(base::SysNSStringToUTF8(refreshToken)),
142 base::SysNSStringToUTF8(email));
143 }
144
145 - (void)callbackWithAccessToken:
146 (const remoting::OAuthTokenGetter::TokenCallback&)onAccessToken {
147 if (_tokenGetter) {
148 _tokenGetter->CallWithToken(onAccessToken);
Yuwei 2017/05/04 05:10:14 Be careful here since a failure to reset onAccessT
nicholss 2017/05/08 17:08:10 Added a TODO.
149 }
150 }
151
152 - (void)logout {
153 [self storeUserInfo:nil];
154 [self setUser:nil];
155 }
156
157 #pragma mark - Persistence
158
159 - (void)storeUserInfo:(UserInfo*)user {
160 NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
161 if (user) {
162 [defaults setObject:user.userEmail forKey:kCRDAuthenticatedUserEmailKey];
163 // TODO(nicholss): Need to match the token with the email.
164 [_keychainWrapper setRefreshToken:user.refreshToken];
165 } else {
166 [defaults removeObjectForKey:kCRDAuthenticatedUserEmailKey];
167 [_keychainWrapper resetKeychainItem];
168 }
169 [defaults synchronize];
170 }
171
172 - (UserInfo*)loadUserInfo {
173 UserInfo* user = [[UserInfo alloc] init];
174 NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
175 user.userEmail = [defaults objectForKey:kCRDAuthenticatedUserEmailKey];
176 // TODO(nicholss): Need to match the token with the email.
177 user.refreshToken = [_keychainWrapper refreshToken];
178
179 if (!user || ![user isAuthenticated]) {
180 NSLog(@"Complete User not found in Keychain.");
181 user = nil;
182 } else {
183 NSLog(@"UserInfo: %@", user);
184 [self authenticateWithRefreshToken:user.refreshToken email:user.userEmail];
185 }
186 return user;
187 }
188
189 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698