Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if !defined(__has_feature) || !__has_feature(objc_arc) | 5 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 6 #error "This file requires ARC support." | 6 #error "This file requires ARC support." |
| 7 #endif | 7 #endif |
| 8 | 8 |
| 9 #import "remoting/client/ios/facade/remoting_service.h" | |
| 10 | |
| 9 #import <Foundation/Foundation.h> | 11 #import <Foundation/Foundation.h> |
| 10 | 12 |
| 11 #import "remoting/client/ios/facade/remoting_service.h" | 13 #import "base/mac/bind_objc_block.h" |
| 12 | 14 |
| 13 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/strings/sys_string_conversions.h" | |
| 17 #include "net/url_request/url_request_context_getter.h" | |
| 18 #include "remoting/base/oauth_token_getter.h" | |
| 19 #include "remoting/base/oauth_token_getter_impl.h" | |
| 20 #include "remoting/client/ios/facade/host_info.h" | |
| 21 #include "remoting/client/ios/facade/host_list_fetcher.h" | |
| 14 | 22 |
| 15 @interface RemotingService () | 23 const char kOauthRedirectUrl[] = |
| 24 "https://chromoting-oauth.talkgadget." | |
| 25 "google.com/talkgadget/oauth/chrome-remote-desktop/dev"; | |
| 16 | 26 |
| 17 @property(nonatomic, copy) NSString* authorizationCode; | 27 std::unique_ptr<remoting::OAuthTokenGetter> |
| 28 CreateOAuthTokenGetterWithAuthorizationCode( | |
| 29 const std::string auth_code, | |
|
joedow
2017/04/10 16:09:59
These are const now, but not const ref, they shoul
nicholss
2017/04/10 17:49:53
Done.
| |
| 30 const remoting::OAuthTokenGetter::CredentialsUpdatedCallback& | |
| 31 on_credentials_update) { | |
| 32 std::unique_ptr<remoting::OAuthTokenGetter::OAuthIntermediateCredentials> | |
| 33 oauth_credentials( | |
| 34 new remoting::OAuthTokenGetter::OAuthIntermediateCredentials( | |
| 35 auth_code, /*is_service_account=*/false)); | |
| 36 oauth_credentials->oauth_redirect_uri = kOauthRedirectUrl; | |
| 37 | |
| 38 std::unique_ptr<remoting::OAuthTokenGetter> oauth_tokenGetter( | |
| 39 new remoting::OAuthTokenGetterImpl( | |
| 40 std::move(oauth_credentials), on_credentials_update, | |
| 41 [[RemotingService SharedInstance] runtime]->url_requester(), | |
| 42 /*auto_refresh=*/true)); | |
| 43 return oauth_tokenGetter; | |
| 44 } | |
| 45 | |
| 46 std::unique_ptr<remoting::OAuthTokenGetter> CreateOAuthTokenWithRefreshToken( | |
| 47 const std::string refresh_token, | |
| 48 const std::string email) { | |
| 49 std::unique_ptr<remoting::OAuthTokenGetter::OAuthAuthorizationCredentials> | |
| 50 oauth_credentials( | |
| 51 new remoting::OAuthTokenGetter::OAuthAuthorizationCredentials( | |
| 52 email, refresh_token, /*is_service_account=*/false)); | |
| 53 | |
| 54 std::unique_ptr<remoting::OAuthTokenGetter> oauth_tokenGetter( | |
| 55 new remoting::OAuthTokenGetterImpl( | |
| 56 std::move(oauth_credentials), | |
| 57 [[RemotingService SharedInstance] runtime]->url_requester(), | |
| 58 /*auto_refresh=*/true)); | |
| 59 return oauth_tokenGetter; | |
| 60 } | |
| 61 | |
| 62 @interface RemotingService () { | |
| 63 std::unique_ptr<remoting::OAuthTokenGetter> _tokenGetter; | |
| 64 UserInfo* _user; | |
| 65 NSArray<HostInfo*>* _hosts; | |
| 66 id<RemotingAuthenticationDelegate> _authDelegate; | |
| 67 id<RemotingHostListDelegate> _hostListDelegate; | |
| 68 remoting::HostListFetcher* _hostListFetcher; | |
| 69 } | |
| 18 | 70 |
| 19 @end | 71 @end |
| 20 | 72 |
| 21 // | 73 // |
| 22 // RemodingService will act as the facade to the C++ layer that has not been | 74 // RemodingService will act as the facade to the C++ layer that has not been |
| 23 // implemented/integrated yet. | 75 // implemented/integrated yet. |
| 24 // TODO(nicholss): Implement/Integrate this class. At the moment it is being | 76 // TODO(nicholss): Implement/Integrate this class. At the moment it is being |
| 25 // used to generate fake data to implement the UI of the app. | 77 // used to generate fake data to implement the UI of the app. |
| 78 // Update: Half implemented now. User is still fake, but now real hosts lists. | |
| 26 // | 79 // |
| 27 @implementation RemotingService | 80 @implementation RemotingService |
| 28 | 81 |
| 29 @synthesize authorizationCode = _authorizationCode; | 82 // RemotingService is a singleton. |
| 83 + (RemotingService*)SharedInstance { | |
| 84 static RemotingService* sharedInstance = nil; | |
| 85 static dispatch_once_t guard; | |
| 86 dispatch_once(&guard, ^{ | |
| 87 sharedInstance = [[RemotingService alloc] init]; | |
| 88 }); | |
| 89 return sharedInstance; | |
| 90 } | |
| 91 | |
| 92 - (instancetype)init { | |
| 93 self = [super init]; | |
| 94 if (self) { | |
| 95 _user = nil; | |
| 96 _hosts = nil; | |
| 97 _hostListFetcher = new remoting::HostListFetcher( | |
| 98 remoting::ChromotingClientRuntime::GetInstance()->url_requester()); | |
| 99 } | |
| 100 return self; | |
| 101 } | |
| 102 | |
| 103 #pragma mark - RemotingService Implementation | |
| 104 | |
| 105 // TODO(nicholss): isAuthenticated needs to just kick off a request to | |
| 106 // authenticate a user. and more than one controller might want to be a delegate | |
| 107 // for this info so need to change this to be more of the registration types. | |
| 108 // The remoting_service might also want to be registered for authentication | |
| 109 // changes and it can update it's cache as it needs. | |
| 110 | |
| 111 - (void)setAuthenticationDelegate:(id<RemotingAuthenticationDelegate>)delegate { | |
| 112 _authDelegate = delegate; | |
| 113 if (_authDelegate) { | |
| 114 [_authDelegate nowAuthenticated:[self isAuthenticated]]; | |
| 115 } | |
| 116 if (!_user && _tokenGetter) { | |
| 117 _tokenGetter->CallWithToken(base::BindBlockArc( | |
| 118 ^(remoting::OAuthTokenGetter::Status status, | |
| 119 const std::string& user_email, const std::string& access_token) { | |
| 120 if (status == remoting::OAuthTokenGetter::Status::SUCCESS) { | |
| 121 _user = [[UserInfo alloc] init]; | |
| 122 _user.userEmail = | |
| 123 [NSString stringWithCString:user_email.c_str() | |
| 124 encoding:[NSString defaultCStringEncoding]]; | |
| 125 } else { | |
| 126 _user = nil; | |
| 127 } | |
| 128 if (_authDelegate) { | |
| 129 [_authDelegate nowAuthenticated:[self isAuthenticated]]; | |
| 130 } | |
| 131 })); | |
| 132 } | |
| 133 } | |
| 30 | 134 |
| 31 - (BOOL)isAuthenticated { | 135 - (BOOL)isAuthenticated { |
| 32 return self.authorizationCode != nil; | 136 if (_user) { |
| 137 return YES; | |
| 138 } | |
| 139 return NO; | |
| 140 } | |
| 141 | |
| 142 - (void)startHostListFetchWith:(NSString*)accessToken { | |
| 143 NSLog(@"startHostListFetchWith : %@ %@", accessToken, _authDelegate); | |
| 144 if (_authDelegate) { | |
| 145 [_authDelegate nowAuthenticated:YES]; | |
| 146 | |
| 147 _hostListFetcher->RetrieveHostlist( | |
| 148 base::SysNSStringToUTF8(accessToken), | |
| 149 base::BindBlockArc(^(const std::vector<remoting::HostInfo>& hostlist) { | |
| 150 NSMutableArray<HostInfo*>* hosts = | |
| 151 [NSMutableArray arrayWithCapacity:hostlist.size()]; | |
| 152 std::string status; | |
| 153 for (const remoting::HostInfo& host_info : hostlist) { | |
| 154 remoting::HostStatus host_status = host_info.status; | |
| 155 switch (host_status) { | |
| 156 case remoting::kHostStatusOnline: | |
| 157 status = "ONLINE"; | |
| 158 break; | |
| 159 case remoting::kHostStatusOffline: | |
| 160 status = "OFFLINE"; | |
| 161 break; | |
| 162 default: | |
| 163 status = "UNKNOWN"; | |
| 164 } | |
| 165 // TODO(nicholss): Not yet integrated: createdTime, hostVersion, | |
| 166 // kind, offlineReason. Add them as the app will need this info. | |
| 167 HostInfo* host = [[HostInfo alloc] init]; | |
| 168 host.hostId = | |
| 169 [NSString stringWithCString:host_info.host_id.c_str() | |
| 170 encoding:[NSString defaultCStringEncoding]]; | |
| 171 host.hostName = | |
| 172 [NSString stringWithCString:host_info.host_name.c_str() | |
| 173 encoding:[NSString defaultCStringEncoding]]; | |
| 174 host.jabberId = | |
| 175 [NSString stringWithCString:host_info.host_jid.c_str() | |
| 176 encoding:[NSString defaultCStringEncoding]]; | |
| 177 host.publicKey = | |
| 178 [NSString stringWithCString:host_info.public_key.c_str() | |
| 179 encoding:[NSString defaultCStringEncoding]]; | |
| 180 host.status = | |
| 181 [NSString stringWithCString:status.c_str() | |
| 182 encoding:[NSString defaultCStringEncoding]]; | |
| 183 [hosts addObject:host]; | |
| 184 } | |
| 185 _hosts = hosts; | |
| 186 [_hostListDelegate hostListUpdated]; | |
| 187 })); | |
| 188 } | |
| 33 } | 189 } |
| 34 | 190 |
| 35 - (void)authenticateWithAuthorizationCode:(NSString*)authorizationCode { | 191 - (void)authenticateWithAuthorizationCode:(NSString*)authorizationCode { |
| 36 self.authorizationCode = authorizationCode; | 192 _tokenGetter = CreateOAuthTokenGetterWithAuthorizationCode( |
| 193 std::string(base::SysNSStringToUTF8(authorizationCode)), | |
| 194 base::BindBlockArc( | |
| 195 ^(const std::string& user_email, const std::string& refresh_token) { | |
| 196 // TODO(nicholss): Do something with these new creds. | |
| 197 VLOG(1) << "New Creds: " << user_email << " " << refresh_token; | |
| 198 })); | |
| 199 } | |
| 200 | |
| 201 - (void)authenticateWithRefreshToken:(NSString*)refreshToken | |
| 202 email:(NSString*)email { | |
| 203 _tokenGetter = CreateOAuthTokenWithRefreshToken( | |
| 204 std::string(base::SysNSStringToUTF8(refreshToken)), | |
| 205 base::SysNSStringToUTF8(email)); | |
| 37 } | 206 } |
| 38 | 207 |
| 39 - (UserInfo*)getUser { | 208 - (UserInfo*)getUser { |
| 40 if (![self isAuthenticated]) { | 209 if (![self isAuthenticated]) { |
| 41 return nil; | 210 return nil; |
| 42 } | 211 } |
| 43 | 212 |
| 44 NSMutableString* json = [[NSMutableString alloc] init]; | 213 NSMutableString* json = [[NSMutableString alloc] init]; |
| 45 [json appendString:@"{"]; | 214 [json appendString:@"{"]; |
| 46 [json appendString:@"\"userId\":\"AABBCC123\","]; | 215 [json appendString:@"\"userId\":\"AABBCC123\","]; |
| 47 [json appendString:@"\"userFullName\":\"John Smith\","]; | 216 [json appendString:@"\"userFullName\":\"John Smith\","]; |
| 48 [json appendString:@"\"userEmail\":\"john@example.com\","]; | 217 [json appendString:@"\"userEmail\":\"john@example.com\","]; |
| 49 [json appendString:@"}"]; | 218 [json appendString:@"}"]; |
| 50 | 219 |
| 51 NSMutableData* data = [NSMutableData | 220 NSMutableData* data = [NSMutableData |
| 52 dataWithData:[[json copy] dataUsingEncoding:NSUTF8StringEncoding]]; | 221 dataWithData:[[json copy] dataUsingEncoding:NSUTF8StringEncoding]]; |
| 53 | 222 |
| 54 UserInfo* user = [UserInfo parseListFromJSON:data]; | 223 UserInfo* user = [UserInfo parseListFromJSON:data]; |
| 55 return user; | 224 return user; |
| 56 } | 225 } |
| 57 | 226 |
| 227 - (void)setHostListDelegate:(id<RemotingHostListDelegate>)delegate { | |
| 228 bool attemptUpdate = (_hostListDelegate != delegate); | |
| 229 _hostListDelegate = delegate; | |
| 230 if (attemptUpdate && _hostListDelegate && _tokenGetter) { | |
| 231 _tokenGetter->CallWithToken(base::BindBlockArc( | |
| 232 ^(remoting::OAuthTokenGetter::Status status, | |
| 233 const std::string& user_email, const std::string& access_token) { | |
| 234 NSString* accessToken = | |
| 235 [NSString stringWithCString:access_token.c_str() | |
| 236 encoding:[NSString defaultCStringEncoding]]; | |
| 237 [self startHostListFetchWith:accessToken]; | |
| 238 })); | |
| 239 } | |
| 240 } | |
| 241 | |
| 58 - (NSArray<HostInfo*>*)getHosts { | 242 - (NSArray<HostInfo*>*)getHosts { |
| 59 if (![self isAuthenticated]) { | 243 if (![self isAuthenticated]) { |
| 60 return nil; | 244 return nil; |
| 61 } | 245 } |
| 62 | 246 return _hosts; |
| 63 NSMutableString* json = [[NSMutableString alloc] init]; | |
| 64 [json | |
| 65 appendString:@"{\"data\":{\"kind\":\"chromoting#hostList\",\"items\":["]; | |
| 66 [json appendString:@"{"]; | |
| 67 [json appendString:@"\"createdTime\":\"2000-01-01T00:00:01.000Z\","]; | |
| 68 [json appendString:@"\"hostId\":\"Host1\","]; | |
| 69 [json appendString:@"\"hostName\":\"HostName1\","]; | |
| 70 [json appendString:@"\"hostVersion\":\"2.22.5.4\","]; | |
| 71 [json appendString:@"\"kind\":\"Chromoting#host\","]; | |
| 72 [json appendString:@"\"jabberId\":\"JabberingOn\","]; | |
| 73 [json appendString:@"\"publicKey\":\"AAAAABBBBBZZZZZ\","]; | |
| 74 [json appendString:@"\"status\":\"TESTING\","]; | |
| 75 [json appendString:@"\"updatedTime\":\"2000-01-01T00:00:01.000Z\""]; | |
| 76 [json appendString:@"},"]; | |
| 77 [json appendString:@"{"]; | |
| 78 [json appendString:@"\"createdTime\":\"2000-01-01T00:00:01.000Z\","]; | |
| 79 [json appendString:@"\"hostId\":\"Host2\","]; | |
| 80 [json appendString:@"\"hostName\":\"HostName2\","]; | |
| 81 [json appendString:@"\"hostVersion\":\"2.22.5.4\","]; | |
| 82 [json appendString:@"\"kind\":\"Chromoting#host\","]; | |
| 83 [json appendString:@"\"jabberId\":\"JabberingOn\","]; | |
| 84 [json appendString:@"\"publicKey\":\"AAAAABBBBBZZZZZ\","]; | |
| 85 [json appendString:@"\"status\":\"ONLINE\","]; | |
| 86 [json appendString:@"\"updatedTime\":\"2000-01-01T00:00:01.000Z\""]; | |
| 87 [json appendString:@"}"]; | |
| 88 [json appendString:@"]}}"]; | |
| 89 | |
| 90 NSMutableData* data = [NSMutableData | |
| 91 dataWithData:[[json copy] dataUsingEncoding:NSUTF8StringEncoding]]; | |
| 92 | |
| 93 NSMutableArray<HostInfo*>* hosts = [HostInfo parseListFromJSON:data]; | |
| 94 return hosts; | |
| 95 } | 247 } |
| 96 | 248 |
| 97 // RemotingService is a singleton. | 249 - (remoting::ChromotingClientRuntime*)runtime { |
| 98 + (RemotingService*)sharedInstance { | 250 return remoting::ChromotingClientRuntime::GetInstance(); |
| 99 static RemotingService* sharedInstance = nil; | |
| 100 static dispatch_once_t guard; | |
| 101 dispatch_once(&guard, ^{ | |
| 102 sharedInstance = [[RemotingService alloc] init]; | |
| 103 }); | |
| 104 return sharedInstance; | |
| 105 } | 251 } |
| 106 | 252 |
| 107 @end | 253 @end |
| OLD | NEW |