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