OLD | NEW |
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(¶ms); |
| 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 Loading... |
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 |
OLD | NEW |