| OLD | NEW |
| 1 // Copyright (c) 2012 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 #include "chrome/browser/extensions/api/identity/identity_get_auth_token_functio
n.h" |
| 6 |
| 7 #include "base/strings/string_number_conversions.h" |
| 5 #include "chrome/browser/extensions/api/identity/identity_api.h" | 8 #include "chrome/browser/extensions/api/identity/identity_api.h" |
| 6 | |
| 7 #include <stddef.h> | |
| 8 | |
| 9 #include <memory> | |
| 10 #include <set> | |
| 11 #include <string> | |
| 12 #include <utility> | |
| 13 #include <vector> | |
| 14 | |
| 15 #include "base/lazy_instance.h" | |
| 16 #include "base/macros.h" | |
| 17 #include "base/memory/ptr_util.h" | |
| 18 #include "base/strings/string_number_conversions.h" | |
| 19 #include "base/strings/stringprintf.h" | |
| 20 #include "base/trace_event/trace_event.h" | |
| 21 #include "base/values.h" | |
| 22 #include "build/build_config.h" | |
| 23 #include "chrome/browser/app_mode/app_mode_utils.h" | |
| 24 #include "chrome/browser/browser_process.h" | |
| 25 #include "chrome/browser/chrome_notification_types.h" | |
| 26 #include "chrome/browser/extensions/api/identity/identity_constants.h" | 9 #include "chrome/browser/extensions/api/identity/identity_constants.h" |
| 27 #include "chrome/browser/extensions/extension_service.h" | |
| 28 #include "chrome/browser/profiles/profile.h" | 10 #include "chrome/browser/profiles/profile.h" |
| 29 #include "chrome/browser/signin/account_tracker_service_factory.h" | |
| 30 #include "chrome/browser/signin/chrome_signin_client_factory.h" | 11 #include "chrome/browser/signin/chrome_signin_client_factory.h" |
| 31 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" | 12 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
| 32 #include "chrome/browser/signin/signin_manager_factory.h" | 13 #include "chrome/browser/signin/signin_manager_factory.h" |
| 33 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" | |
| 34 #include "chrome/common/extensions/api/identity.h" | 14 #include "chrome/common/extensions/api/identity.h" |
| 35 #include "chrome/common/url_constants.h" | |
| 36 #include "components/signin/core/browser/account_tracker_service.h" | |
| 37 #include "components/signin/core/browser/profile_oauth2_token_service.h" | 15 #include "components/signin/core/browser/profile_oauth2_token_service.h" |
| 38 #include "components/signin/core/browser/signin_manager.h" | 16 #include "components/signin/core/browser/signin_manager.h" |
| 39 #include "components/signin/core/common/profile_management_switches.h" | 17 #include "components/signin/core/common/profile_management_switches.h" |
| 40 #include "extensions/browser/event_router.h" | |
| 41 #include "extensions/browser/extension_function_dispatcher.h" | |
| 42 #include "extensions/common/extension.h" | |
| 43 #include "extensions/common/extension_l10n_util.h" | 18 #include "extensions/common/extension_l10n_util.h" |
| 44 #include "extensions/common/manifest_handlers/oauth2_manifest_handler.h" | |
| 45 #include "extensions/common/permissions/permission_set.h" | |
| 46 #include "extensions/common/permissions/permissions_data.h" | |
| 47 #include "google_apis/gaia/gaia_urls.h" | 19 #include "google_apis/gaia/gaia_urls.h" |
| 48 #include "url/gurl.h" | |
| 49 | 20 |
| 50 #if defined(OS_CHROMEOS) | 21 #if defined(OS_CHROMEOS) |
| 22 #include "chrome/browser/app_mode/app_mode_utils.h" |
| 23 #include "chrome/browser/browser_process.h" |
| 51 #include "chrome/browser/chromeos/login/session/user_session_manager.h" | 24 #include "chrome/browser/chromeos/login/session/user_session_manager.h" |
| 52 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" | 25 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" |
| 53 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h" | 26 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h" |
| 54 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h
" | 27 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h
" |
| 55 #include "components/user_manager/user_manager.h" | 28 #include "components/user_manager/user_manager.h" |
| 56 #include "google_apis/gaia/gaia_constants.h" | 29 #include "google_apis/gaia/gaia_constants.h" |
| 57 #endif | 30 #endif |
| 58 | 31 |
| 59 namespace extensions { | 32 namespace extensions { |
| 60 | 33 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 73 std::string GetPrimaryAccountId(content::BrowserContext* context) { | 46 std::string GetPrimaryAccountId(content::BrowserContext* context) { |
| 74 SigninManagerBase* signin_manager = | 47 SigninManagerBase* signin_manager = |
| 75 SigninManagerFactory::GetForProfile(Profile::FromBrowserContext(context)); | 48 SigninManagerFactory::GetForProfile(Profile::FromBrowserContext(context)); |
| 76 return signin_manager->GetAuthenticatedAccountId(); | 49 return signin_manager->GetAuthenticatedAccountId(); |
| 77 } | 50 } |
| 78 | 51 |
| 79 } // namespace | 52 } // namespace |
| 80 | 53 |
| 81 namespace identity = api::identity; | 54 namespace identity = api::identity; |
| 82 | 55 |
| 83 IdentityTokenCacheValue::IdentityTokenCacheValue() | |
| 84 : status_(CACHE_STATUS_NOTFOUND) {} | |
| 85 | |
| 86 IdentityTokenCacheValue::IdentityTokenCacheValue( | |
| 87 const IssueAdviceInfo& issue_advice) | |
| 88 : status_(CACHE_STATUS_ADVICE), issue_advice_(issue_advice) { | |
| 89 expiration_time_ = | |
| 90 base::Time::Now() + base::TimeDelta::FromSeconds( | |
| 91 identity_constants::kCachedIssueAdviceTTLSeconds); | |
| 92 } | |
| 93 | |
| 94 IdentityTokenCacheValue::IdentityTokenCacheValue(const std::string& token, | |
| 95 base::TimeDelta time_to_live) | |
| 96 : status_(CACHE_STATUS_TOKEN), token_(token) { | |
| 97 // Remove 20 minutes from the ttl so cached tokens will have some time | |
| 98 // to live any time they are returned. | |
| 99 time_to_live -= base::TimeDelta::FromMinutes(20); | |
| 100 | |
| 101 base::TimeDelta zero_delta; | |
| 102 if (time_to_live < zero_delta) | |
| 103 time_to_live = zero_delta; | |
| 104 | |
| 105 expiration_time_ = base::Time::Now() + time_to_live; | |
| 106 } | |
| 107 | |
| 108 IdentityTokenCacheValue::IdentityTokenCacheValue( | |
| 109 const IdentityTokenCacheValue& other) = default; | |
| 110 | |
| 111 IdentityTokenCacheValue::~IdentityTokenCacheValue() {} | |
| 112 | |
| 113 IdentityTokenCacheValue::CacheValueStatus IdentityTokenCacheValue::status() | |
| 114 const { | |
| 115 if (is_expired()) | |
| 116 return IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND; | |
| 117 else | |
| 118 return status_; | |
| 119 } | |
| 120 | |
| 121 const IssueAdviceInfo& IdentityTokenCacheValue::issue_advice() const { | |
| 122 return issue_advice_; | |
| 123 } | |
| 124 | |
| 125 const std::string& IdentityTokenCacheValue::token() const { return token_; } | |
| 126 | |
| 127 bool IdentityTokenCacheValue::is_expired() const { | |
| 128 return status_ == CACHE_STATUS_NOTFOUND || | |
| 129 expiration_time_ < base::Time::Now(); | |
| 130 } | |
| 131 | |
| 132 const base::Time& IdentityTokenCacheValue::expiration_time() const { | |
| 133 return expiration_time_; | |
| 134 } | |
| 135 | |
| 136 IdentityAPI::IdentityAPI(content::BrowserContext* context) | |
| 137 : browser_context_(context), | |
| 138 profile_identity_provider_( | |
| 139 SigninManagerFactory::GetForProfile( | |
| 140 Profile::FromBrowserContext(context)), | |
| 141 ProfileOAuth2TokenServiceFactory::GetForProfile( | |
| 142 Profile::FromBrowserContext(context)), | |
| 143 LoginUIServiceFactory::GetShowLoginPopupCallbackForProfile( | |
| 144 Profile::FromBrowserContext(context))), | |
| 145 account_tracker_(&profile_identity_provider_, | |
| 146 g_browser_process->system_request_context()), | |
| 147 get_auth_token_function_(nullptr) { | |
| 148 account_tracker_.AddObserver(this); | |
| 149 } | |
| 150 | |
| 151 IdentityAPI::~IdentityAPI() {} | |
| 152 | |
| 153 IdentityMintRequestQueue* IdentityAPI::mint_queue() { return &mint_queue_; } | |
| 154 | |
| 155 void IdentityAPI::SetCachedToken(const ExtensionTokenKey& key, | |
| 156 const IdentityTokenCacheValue& token_data) { | |
| 157 CachedTokens::iterator it = token_cache_.find(key); | |
| 158 if (it != token_cache_.end() && it->second.status() <= token_data.status()) | |
| 159 token_cache_.erase(it); | |
| 160 | |
| 161 token_cache_.insert(std::make_pair(key, token_data)); | |
| 162 } | |
| 163 | |
| 164 void IdentityAPI::EraseCachedToken(const std::string& extension_id, | |
| 165 const std::string& token) { | |
| 166 CachedTokens::iterator it; | |
| 167 for (it = token_cache_.begin(); it != token_cache_.end(); ++it) { | |
| 168 if (it->first.extension_id == extension_id && | |
| 169 it->second.status() == IdentityTokenCacheValue::CACHE_STATUS_TOKEN && | |
| 170 it->second.token() == token) { | |
| 171 token_cache_.erase(it); | |
| 172 break; | |
| 173 } | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 void IdentityAPI::EraseAllCachedTokens() { token_cache_.clear(); } | |
| 178 | |
| 179 const IdentityTokenCacheValue& IdentityAPI::GetCachedToken( | |
| 180 const ExtensionTokenKey& key) { | |
| 181 return token_cache_[key]; | |
| 182 } | |
| 183 | |
| 184 const IdentityAPI::CachedTokens& IdentityAPI::GetAllCachedTokens() { | |
| 185 return token_cache_; | |
| 186 } | |
| 187 | |
| 188 std::vector<std::string> IdentityAPI::GetAccounts() const { | |
| 189 const std::string primary_account_id = GetPrimaryAccountId(browser_context_); | |
| 190 const std::vector<gaia::AccountIds> ids = account_tracker_.GetAccounts(); | |
| 191 std::vector<std::string> gaia_ids; | |
| 192 | |
| 193 if (switches::IsExtensionsMultiAccount()) { | |
| 194 for (std::vector<gaia::AccountIds>::const_iterator it = ids.begin(); | |
| 195 it != ids.end(); | |
| 196 ++it) { | |
| 197 gaia_ids.push_back(it->gaia); | |
| 198 } | |
| 199 } else if (ids.size() >= 1) { | |
| 200 gaia_ids.push_back(ids[0].gaia); | |
| 201 } | |
| 202 | |
| 203 return gaia_ids; | |
| 204 } | |
| 205 | |
| 206 std::string IdentityAPI::FindAccountKeyByGaiaId(const std::string& gaia_id) { | |
| 207 return account_tracker_.FindAccountIdsByGaiaId(gaia_id).account_key; | |
| 208 } | |
| 209 | |
| 210 void IdentityAPI::Shutdown() { | |
| 211 if (get_auth_token_function_) | |
| 212 get_auth_token_function_->Shutdown(); | |
| 213 account_tracker_.RemoveObserver(this); | |
| 214 account_tracker_.Shutdown(); | |
| 215 } | |
| 216 | |
| 217 static base::LazyInstance<BrowserContextKeyedAPIFactory<IdentityAPI> > | |
| 218 g_factory = LAZY_INSTANCE_INITIALIZER; | |
| 219 | |
| 220 // static | |
| 221 BrowserContextKeyedAPIFactory<IdentityAPI>* IdentityAPI::GetFactoryInstance() { | |
| 222 return g_factory.Pointer(); | |
| 223 } | |
| 224 | |
| 225 void IdentityAPI::OnAccountAdded(const gaia::AccountIds& ids) { | |
| 226 } | |
| 227 | |
| 228 void IdentityAPI::OnAccountRemoved(const gaia::AccountIds& ids) { | |
| 229 } | |
| 230 | |
| 231 void IdentityAPI::OnAccountSignInChanged(const gaia::AccountIds& ids, | |
| 232 bool is_signed_in) { | |
| 233 api::identity::AccountInfo account_info; | |
| 234 account_info.id = ids.gaia; | |
| 235 | |
| 236 std::unique_ptr<base::ListValue> args = | |
| 237 api::identity::OnSignInChanged::Create(account_info, is_signed_in); | |
| 238 std::unique_ptr<Event> event( | |
| 239 new Event(events::IDENTITY_ON_SIGN_IN_CHANGED, | |
| 240 api::identity::OnSignInChanged::kEventName, std::move(args), | |
| 241 browser_context_)); | |
| 242 | |
| 243 EventRouter::Get(browser_context_)->BroadcastEvent(std::move(event)); | |
| 244 } | |
| 245 | |
| 246 void IdentityAPI::SetAccountStateForTest(gaia::AccountIds ids, | |
| 247 bool is_signed_in) { | |
| 248 account_tracker_.SetAccountStateForTest(ids, is_signed_in); | |
| 249 } | |
| 250 | |
| 251 template <> | |
| 252 void BrowserContextKeyedAPIFactory<IdentityAPI>::DeclareFactoryDependencies() { | |
| 253 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); | |
| 254 DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); | |
| 255 } | |
| 256 | |
| 257 IdentityGetAccountsFunction::IdentityGetAccountsFunction() { | |
| 258 } | |
| 259 | |
| 260 IdentityGetAccountsFunction::~IdentityGetAccountsFunction() { | |
| 261 } | |
| 262 | |
| 263 ExtensionFunction::ResponseAction IdentityGetAccountsFunction::Run() { | |
| 264 if (GetProfile()->IsOffTheRecord()) { | |
| 265 return RespondNow(Error(identity_constants::kOffTheRecord)); | |
| 266 } | |
| 267 | |
| 268 std::vector<std::string> gaia_ids = | |
| 269 IdentityAPI::GetFactoryInstance()->Get(GetProfile())->GetAccounts(); | |
| 270 DCHECK(gaia_ids.size() < 2 || switches::IsExtensionsMultiAccount()); | |
| 271 | |
| 272 std::unique_ptr<base::ListValue> infos(new base::ListValue()); | |
| 273 | |
| 274 for (std::vector<std::string>::const_iterator it = gaia_ids.begin(); | |
| 275 it != gaia_ids.end(); | |
| 276 ++it) { | |
| 277 api::identity::AccountInfo account_info; | |
| 278 account_info.id = *it; | |
| 279 infos->Append(account_info.ToValue()); | |
| 280 } | |
| 281 | |
| 282 return RespondNow(OneArgument(std::move(infos))); | |
| 283 } | |
| 284 | |
| 285 IdentityGetAuthTokenFunction::IdentityGetAuthTokenFunction() | 56 IdentityGetAuthTokenFunction::IdentityGetAuthTokenFunction() |
| 286 : OAuth2TokenService::Consumer("extensions_identity_api"), | 57 : OAuth2TokenService::Consumer("extensions_identity_api"), |
| 287 interactive_(false), | 58 interactive_(false), |
| 288 should_prompt_for_scopes_(false), | 59 should_prompt_for_scopes_(false), |
| 289 should_prompt_for_signin_(false) { | 60 should_prompt_for_signin_(false) { |
| 290 } | 61 } |
| 291 | 62 |
| 292 IdentityGetAuthTokenFunction::~IdentityGetAuthTokenFunction() { | 63 IdentityGetAuthTokenFunction::~IdentityGetAuthTokenFunction() { |
| 293 TRACE_EVENT_ASYNC_END0("identity", "IdentityGetAuthTokenFunction", this); | 64 TRACE_EVENT_ASYNC_END0("identity", "IdentityGetAuthTokenFunction", this); |
| 294 } | 65 } |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 // Component apps using auto_approve may use Chrome's client ID by | 638 // Component apps using auto_approve may use Chrome's client ID by |
| 868 // omitting the field. | 639 // omitting the field. |
| 869 if (client_id.empty() && extension()->location() == Manifest::COMPONENT && | 640 if (client_id.empty() && extension()->location() == Manifest::COMPONENT && |
| 870 oauth2_info.auto_approve) { | 641 oauth2_info.auto_approve) { |
| 871 client_id = GaiaUrls::GetInstance()->oauth2_chrome_client_id(); | 642 client_id = GaiaUrls::GetInstance()->oauth2_chrome_client_id(); |
| 872 } | 643 } |
| 873 return client_id; | 644 return client_id; |
| 874 } | 645 } |
| 875 | 646 |
| 876 } // namespace extensions | 647 } // namespace extensions |
| OLD | NEW |