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

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

Powered by Google App Engine
This is Rietveld 408576698