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

Side by Side Diff: chrome/browser/extensions/api/identity/identity_api.cc

Issue 10701041: implement sign in dialog (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "chrome/browser/extensions/api/identity/identity_api.h" 5 #include "chrome/browser/extensions/api/identity/identity_api.h"
6 6
7 #include "base/values.h" 7 #include "base/values.h"
8 #include "chrome/common/extensions/api/experimental_identity.h" 8 #include "chrome/common/extensions/api/experimental_identity.h"
9 #include "chrome/browser/extensions/extension_install_prompt.h" 9 #include "chrome/browser/extensions/extension_install_prompt.h"
10 #include "chrome/browser/extensions/extension_function_dispatcher.h" 10 #include "chrome/browser/extensions/extension_function_dispatcher.h"
11 #include "chrome/browser/extensions/extension_service.h" 11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/permissions_updater.h" 12 #include "chrome/browser/extensions/permissions_updater.h"
13 #include "chrome/browser/signin/token_service.h" 13 #include "chrome/browser/signin/token_service.h"
14 #include "chrome/browser/signin/token_service_factory.h" 14 #include "chrome/browser/signin/token_service_factory.h"
15 #include "chrome/browser/ui/browser.h" 15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/tab_contents/tab_contents.h" 16 #include "chrome/browser/ui/browser_navigator.h"
17 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
18 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
17 #include "chrome/common/extensions/extension.h" 19 #include "chrome/common/extensions/extension.h"
20 #include "chrome/common/url_constants.h"
21 #include "content/public/common/page_transition_types.h"
18 #include "googleurl/src/gurl.h" 22 #include "googleurl/src/gurl.h"
23 #include "webkit/glue/window_open_disposition.h"
19 24
20 namespace extensions { 25 namespace extensions {
21 26
22 namespace { 27 const char IdentityGetAuthTokenFunction::kInvalidClientId[] =
23 28 "Invalid OAuth2 Client ID.";
24 const char kInvalidClientId[] = "Invalid OAuth2 Client ID."; 29 const char IdentityGetAuthTokenFunction::kInvalidScopes[] =
25 const char kInvalidScopes[] = "Invalid OAuth2 scopes."; 30 "Invalid OAuth2 scopes.";
26 const char kInvalidRedirect[] = "Did not redirect to the right URL."; 31 const char IdentityGetAuthTokenFunction::kAuthFailure[] =
27 const char kAuthFailure[] = "OAuth2 request failed: "; 32 "OAuth2 request failed: ";
28 const char kNoGrant[] = "OAuth2 not granted or revoked."; 33 const char IdentityGetAuthTokenFunction::kNoGrant[] =
29 const char kUserRejected[] = "The user did not approve access."; 34 "OAuth2 not granted or revoked.";
30 35 const char IdentityGetAuthTokenFunction::kUserRejected[] =
31 } // namespace 36 "The user did not approve access.";
37 const char IdentityGetAuthTokenFunction::kUserNotSignedIn[] =
38 "The user is not signed in.";
32 39
33 namespace GetAuthToken = extensions::api::experimental_identity::GetAuthToken; 40 namespace GetAuthToken = extensions::api::experimental_identity::GetAuthToken;
34 namespace LaunchWebAuthFlow = 41 namespace LaunchWebAuthFlow =
35 extensions::api::experimental_identity::LaunchWebAuthFlow; 42 extensions::api::experimental_identity::LaunchWebAuthFlow;
36 43
37 IdentityGetAuthTokenFunction::IdentityGetAuthTokenFunction() 44 IdentityGetAuthTokenFunction::IdentityGetAuthTokenFunction()
38 : interactive_(false) {} 45 : interactive_(false) {}
39 IdentityGetAuthTokenFunction::~IdentityGetAuthTokenFunction() {} 46 IdentityGetAuthTokenFunction::~IdentityGetAuthTokenFunction() {}
40 47
41 bool IdentityGetAuthTokenFunction::RunImpl() { 48 bool IdentityGetAuthTokenFunction::RunImpl() {
42 scoped_ptr<GetAuthToken::Params> params(GetAuthToken::Params::Create(*args_)); 49 scoped_ptr<GetAuthToken::Params> params(GetAuthToken::Params::Create(*args_));
43 EXTENSION_FUNCTION_VALIDATE(params.get()); 50 EXTENSION_FUNCTION_VALIDATE(params.get());
44 if (params->details.get() && params->details->interactive.get()) 51 if (params->details.get() && params->details->interactive.get())
45 interactive_ = *params->details->interactive; 52 interactive_ = *params->details->interactive;
46 53
54 const Extension::OAuth2Info& oauth2_info = GetExtension()->oauth2_info();
55
56 // Check that the necessary information is present in the manfist.
57 if (oauth2_info.client_id.empty()) {
58 error_ = kInvalidClientId;
59 return false;
60 }
61
62 if (oauth2_info.scopes.size() == 0) {
63 error_ = kInvalidScopes;
64 return false;
65 }
66
47 // Balanced in OnIssueAdviceSuccess|OnMintTokenSuccess|OnMintTokenFailure| 67 // Balanced in OnIssueAdviceSuccess|OnMintTokenSuccess|OnMintTokenFailure|
48 // InstallUIAbort. 68 // InstallUIAbort|OnLoginUIClosed.
49 AddRef(); 69 AddRef();
50 70
51 if (StartFlow(ExtensionInstallPrompt::ShouldAutomaticallyApproveScopes() ? 71 if (!HasLoginToken()) {
52 OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE : 72 if (StartLogin()) {
53 OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE)) { 73 return true;
74 } else {
75 Release();
76 return false;
77 }
78 }
79
80 if (StartFlow(GetTokenFlowMode())) {
54 return true; 81 return true;
55 } else { 82 } else {
56 Release(); 83 Release();
57 return false; 84 return false;
58 } 85 }
59 } 86 }
60 87
61 void IdentityGetAuthTokenFunction::OnMintTokenSuccess( 88 void IdentityGetAuthTokenFunction::OnMintTokenSuccess(
62 const std::string& access_token) { 89 const std::string& access_token) {
63 SetResult(Value::CreateStringValue(access_token)); 90 SetResult(Value::CreateStringValue(access_token));
64 SendResponse(true); 91 SendResponse(true);
65 Release(); // Balanced in RunImpl. 92 Release(); // Balanced in RunImpl.
66 } 93 }
67 94
68 void IdentityGetAuthTokenFunction::OnMintTokenFailure( 95 void IdentityGetAuthTokenFunction::OnMintTokenFailure(
69 const GoogleServiceAuthError& error) { 96 const GoogleServiceAuthError& error) {
70 error_ = std::string(kAuthFailure) + error.ToString(); 97 error_ = std::string(kAuthFailure) + error.ToString();
71 SendResponse(false); 98 SendResponse(false);
72 Release(); // Balanced in RunImpl. 99 Release(); // Balanced in RunImpl.
73 } 100 }
74 101
75 void IdentityGetAuthTokenFunction::OnIssueAdviceSuccess( 102 void IdentityGetAuthTokenFunction::OnIssueAdviceSuccess(
76 const IssueAdviceInfo& issue_advice) { 103 const IssueAdviceInfo& issue_advice) {
77 // Existing grant was revoked and we used NO_FORCE, so we got info back 104 // Existing grant was revoked and we used NO_FORCE, so we got info back
78 // instead. 105 // instead.
79 if (interactive_) { 106 if (interactive_) {
80 install_ui_.reset( 107 install_ui_.reset(
81 chrome::CreateExtensionInstallPromptWithBrowser(GetCurrentBrowser())); 108 chrome::CreateExtensionInstallPromptWithBrowser(GetCurrentBrowser()));
82 install_ui_->ConfirmIssueAdvice(this, GetExtension(), issue_advice); 109 ShowOAuthApprovalDialog(issue_advice);
83 } else { 110 } else {
84 error_ = kNoGrant; 111 error_ = kNoGrant;
85 SendResponse(false); 112 SendResponse(false);
86 Release(); // Balanced in RunImpl. 113 Release(); // Balanced in RunImpl.
87 } 114 }
88 } 115 }
89 116
117 void IdentityGetAuthTokenFunction::OnLoginUIClosed(
118 LoginUIService::LoginUI* ui) {
119 StopObservingLoginService();
120 if (!StartFlow(GetTokenFlowMode())) {
121 SendResponse(false);
122 Release();
123 }
124 }
125
90 void IdentityGetAuthTokenFunction::InstallUIProceed() { 126 void IdentityGetAuthTokenFunction::InstallUIProceed() {
91 DCHECK(install_ui_->record_oauth2_grant()); 127 DCHECK(install_ui_->record_oauth2_grant());
92 // The user has accepted the scopes, so we may now force (recording a grant 128 // The user has accepted the scopes, so we may now force (recording a grant
93 // and receiving a token). 129 // and receiving a token).
94 bool success = StartFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE); 130 bool success = StartFlow(OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE);
95 DCHECK(success); 131 DCHECK(success);
96 } 132 }
97 133
98 void IdentityGetAuthTokenFunction::InstallUIAbort(bool user_initiated) { 134 void IdentityGetAuthTokenFunction::InstallUIAbort(bool user_initiated) {
99 error_ = kUserRejected; 135 error_ = kUserRejected;
100 SendResponse(false); 136 SendResponse(false);
101 Release(); // Balanced in RunImpl. 137 Release(); // Balanced in RunImpl.
102 } 138 }
103 139
104 bool IdentityGetAuthTokenFunction::StartFlow(OAuth2MintTokenFlow::Mode mode) { 140 bool IdentityGetAuthTokenFunction::StartFlow(OAuth2MintTokenFlow::Mode mode) {
105 const Extension* extension = GetExtension(); 141 if (!HasLoginToken()) {
106 Extension::OAuth2Info oauth2_info = extension->oauth2_info(); 142 error_ = kUserNotSignedIn;
107
108 if (oauth2_info.client_id.empty()) {
109 error_ = kInvalidClientId;
110 return false; 143 return false;
111 } 144 }
112 145
113 if (oauth2_info.scopes.size() == 0) { 146 flow_.reset(CreateMintTokenFlow(mode));
114 error_ = kInvalidScopes; 147 flow_->Start();
148 return true;
149 }
150
151 bool IdentityGetAuthTokenFunction::StartLogin() {
152 if (!interactive_) {
153 error_ = kUserNotSignedIn;
115 return false; 154 return false;
116 } 155 }
117 156
157 ShowLoginPopup();
158 return true;
159 }
160
161 void IdentityGetAuthTokenFunction::StartObservingLoginService() {
162 LoginUIService* login_ui_service =
163 LoginUIServiceFactory::GetForProfile(profile());
164 login_ui_service->AddObserver(this);
165 }
166
167 void IdentityGetAuthTokenFunction::StopObservingLoginService() {
168 LoginUIService* login_ui_service =
169 LoginUIServiceFactory::GetForProfile(profile());
170 login_ui_service->RemoveObserver(this);
171 }
172
173 void IdentityGetAuthTokenFunction::ShowLoginPopup() {
174 StartObservingLoginService();
175
176 LoginUIService* login_ui_service =
177 LoginUIServiceFactory::GetForProfile(profile());
178 LoginUIService::LoginUI* login_ui = login_ui_service->current_login_ui();
179 if (login_ui) {
180 login_ui->FocusUI();
181 } else {
182 Browser* browser = Browser::CreateWithParams(Browser::CreateParams(
183 Browser::TYPE_POPUP, profile()));
184 chrome::NavigateParams params(browser,
185 GURL(chrome::kChromeUISyncPromoURL),
186 content::PAGE_TRANSITION_START_PAGE);
187 params.disposition = CURRENT_TAB;
188 chrome::Navigate(&params);
189 }
190 }
191
192 void IdentityGetAuthTokenFunction::ShowOAuthApprovalDialog(
193 const IssueAdviceInfo& issue_advice) {
194 install_ui_->ConfirmIssueAdvice(this, GetExtension(), issue_advice);
195 }
196
197 OAuth2MintTokenFlow* IdentityGetAuthTokenFunction::CreateMintTokenFlow(
198 OAuth2MintTokenFlow::Mode mode) {
199 const Extension::OAuth2Info& oauth2_info = GetExtension()->oauth2_info();
118 TokenService* token_service = TokenServiceFactory::GetForProfile(profile()); 200 TokenService* token_service = TokenServiceFactory::GetForProfile(profile());
119 flow_.reset(new OAuth2MintTokenFlow( 201 return new OAuth2MintTokenFlow(
120 profile()->GetRequestContext(), 202 profile()->GetRequestContext(),
121 this, 203 this,
122 OAuth2MintTokenFlow::Parameters( 204 OAuth2MintTokenFlow::Parameters(
123 token_service->GetOAuth2LoginRefreshToken(), 205 token_service->GetOAuth2LoginRefreshToken(),
124 extension->id(), 206 GetExtension()->id(),
125 oauth2_info.client_id, 207 oauth2_info.client_id,
126 oauth2_info.scopes, 208 oauth2_info.scopes,
127 mode))); 209 mode));
128 flow_->Start();
129 return true;
130 } 210 }
131 211
212 bool IdentityGetAuthTokenFunction::HasLoginToken() const {
213 TokenService* token_service = TokenServiceFactory::GetForProfile(profile());
214 return token_service->HasOAuthLoginToken();
215 }
216
217 OAuth2MintTokenFlow::Mode IdentityGetAuthTokenFunction::GetTokenFlowMode()
218 const {
219 return ExtensionInstallPrompt::ShouldAutomaticallyApproveScopes() ?
220 OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE :
221 OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE;
222 }
223
224 const char IdentityLaunchWebAuthFlowFunction::kInvalidRedirect[] =
225 "Did not redirect to the right URL.";
226
132 IdentityLaunchWebAuthFlowFunction::IdentityLaunchWebAuthFlowFunction() {} 227 IdentityLaunchWebAuthFlowFunction::IdentityLaunchWebAuthFlowFunction() {}
133 IdentityLaunchWebAuthFlowFunction::~IdentityLaunchWebAuthFlowFunction() {} 228 IdentityLaunchWebAuthFlowFunction::~IdentityLaunchWebAuthFlowFunction() {}
134 229
135 bool IdentityLaunchWebAuthFlowFunction::RunImpl() { 230 bool IdentityLaunchWebAuthFlowFunction::RunImpl() {
136 scoped_ptr<LaunchWebAuthFlow::Params> params( 231 scoped_ptr<LaunchWebAuthFlow::Params> params(
137 LaunchWebAuthFlow::Params::Create(*args_)); 232 LaunchWebAuthFlow::Params::Create(*args_));
138 EXTENSION_FUNCTION_VALIDATE(params.get()); 233 EXTENSION_FUNCTION_VALIDATE(params.get());
139 234
140 GURL auth_url(params->details.url); 235 GURL auth_url(params->details.url);
141 WebAuthFlow::Mode mode = 236 WebAuthFlow::Mode mode =
(...skipping 14 matching lines...) Expand all
156 Release(); // Balanced in RunImpl. 251 Release(); // Balanced in RunImpl.
157 } 252 }
158 253
159 void IdentityLaunchWebAuthFlowFunction::OnAuthFlowFailure() { 254 void IdentityLaunchWebAuthFlowFunction::OnAuthFlowFailure() {
160 error_ = kInvalidRedirect; 255 error_ = kInvalidRedirect;
161 SendResponse(false); 256 SendResponse(false);
162 Release(); // Balanced in RunImpl. 257 Release(); // Balanced in RunImpl.
163 } 258 }
164 259
165 } // namespace extensions 260 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698