identity_api.cc revision 5e3f23d412006dc4db4e659864679f29341e113f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/identity/identity_api.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <set> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string> 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <utility> 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector> 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/lazy_instance.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/prefs/pref_service.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 155e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/app_mode/app_mode_utils.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/browser_process.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_function_dispatcher.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/signin/signin_manager.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/signin/token_service.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/signin/token_service_factory.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/api/identity.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension_manifest_constants.h" 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/pref_names.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "google_apis/gaia/gaia_constants.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h" 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace identity_constants { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidClientId[] = "Invalid OAuth2 Client ID."; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidScopes[] = "Invalid OAuth2 scopes."; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAuthFailure[] = "OAuth2 request failed: "; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNoGrant[] = "OAuth2 not granted or revoked."; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserRejected[] = "The user did not approve access."; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserNotSignedIn[] = "The user is not signed in."; 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kInteractionRequired[] = "User interaction required."; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidRedirect[] = "Did not redirect to the right URL."; 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOffTheRecord[] = "Identity API is disabled in incognito windows."; 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kPageLoadFailure[] = "Authorization page could not be loaded."; 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kCachedIssueAdviceTTLSeconds = 1; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace identity_constants 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static const char kChromiumDomainRedirectUrlPattern[] = 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "https://%s.chromiumapp.org/"; 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace identity = api::identity; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IdentityGetAuthTokenFunction::IdentityGetAuthTokenFunction() 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : should_prompt_for_scopes_(false), 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_prompt_for_signin_(false) {} 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IdentityGetAuthTokenFunction::~IdentityGetAuthTokenFunction() {} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IdentityGetAuthTokenFunction::RunImpl() { 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (profile()->IsOffTheRecord()) { 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = identity_constants::kOffTheRecord; 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<identity::GetAuthToken::Params> params( 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) identity::GetAuthToken::Params::Create(*args_)); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool interactive = params->details.get() && 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params->details->interactive.get() && 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *params->details->interactive; 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_prompt_for_scopes_ = interactive; 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_prompt_for_signin_ = interactive; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check that the necessary information is present in the manifest. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (oauth2_info.client_id.empty()) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = identity_constants::kInvalidClientId; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (oauth2_info.scopes.size() == 0) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = identity_constants::kInvalidScopes; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Balanced in CompleteFunctionWithResult|CompleteFunctionWithError 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRef(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!HasLoginToken()) { 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!should_prompt_for_signin_) { 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = identity_constants::kUserNotSignedIn; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Display a login prompt. 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartSigninFlow(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TokenService* token_service = TokenServiceFactory::GetForProfile(profile()); 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) refresh_token_ = token_service->GetOAuth2LoginRefreshToken(); 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::CompleteFunctionWithResult( 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& access_token) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetResult(Value::CreateStringValue(access_token)); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(true); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); // Balanced in RunImpl. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::CompleteFunctionWithError( 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error) { 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = error; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(false); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); // Balanced in RunImpl. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartSigninFlow() { 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // All cached tokens are invalid because the user is not signed in. 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityAPI* id_api = 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(profile_); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) id_api->EraseAllCachedTokens(); 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Display a login prompt. If the subsequent mint fails, don't display the 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // login prompt again. 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_prompt_for_signin_ = false; 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ShowLoginPopup(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartMintTokenFlow( 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMintRequestQueue::MintType type) { 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mint_token_flow_type_ = type; 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Flows are serialized to prevent excessive traffic to GAIA, and 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // to consolidate UI pop-ups. 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::set<std::string> scopes(oauth2_info.scopes.begin(), 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) oauth2_info.scopes.end()); 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityAPI* id_api = 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(profile_); 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!should_prompt_for_scopes_) { 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Caller requested no interaction. 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (type == IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE) { 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // GAIA told us to do a consent UI. 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteFunctionWithError(identity_constants::kNoGrant); 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!id_api->mint_queue()->empty( 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE, 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetExtension()->id(), scopes)) { 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Another call is going through a consent UI. 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteFunctionWithError(identity_constants::kNoGrant); 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) id_api->mint_queue()->RequestStart(type, 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetExtension()->id(), 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scopes, 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::CompleteMintTokenFlow() { 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMintRequestQueue::MintType type = mint_token_flow_type_; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::set<std::string> scopes(oauth2_info.scopes.begin(), 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) oauth2_info.scopes.end()); 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extensions::IdentityAPI::GetFactoryInstance()->GetForProfile( 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile_)->mint_queue()->RequestComplete(type, 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetExtension()->id(), 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scopes, 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartMintToken( 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMintRequestQueue::MintType type) { 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityAPI* id_api = IdentityAPI::GetFactoryInstance()->GetForProfile( 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile()); 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityTokenCacheValue cache_entry = id_api->GetCachedToken( 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetExtension()->id(), oauth2_info.scopes); 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityTokenCacheValue::CacheValueStatus cache_status = 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cache_entry.status(); 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (type == IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE) { 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (cache_status) { 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND: 206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_CHROMEOS) 207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Always force minting token for ChromeOS kiosk app. 208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (chrome::IsRunningInForcedAppMode()) { 209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) StartGaiaRequest(OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE); 210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartGaiaRequest(OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE); 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case IdentityTokenCacheValue::CACHE_STATUS_TOKEN: 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteMintTokenFlow(); 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteFunctionWithResult(cache_entry.token()); 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case IdentityTokenCacheValue::CACHE_STATUS_ADVICE: 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteMintTokenFlow(); 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_prompt_for_signin_ = false; 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) issue_advice_ = cache_entry.issue_advice(); 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE); 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(type == IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE); 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (cache_status == IdentityTokenCacheValue::CACHE_STATUS_TOKEN) { 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteMintTokenFlow(); 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteFunctionWithResult(cache_entry.token()); 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ShowOAuthApprovalDialog(issue_advice_); 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnMintTokenSuccess( 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& access_token, int time_to_live) { 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityTokenCacheValue token(access_token, 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::TimeDelta::FromSeconds(time_to_live)); 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityAPI::GetFactoryInstance()->GetForProfile(profile())->SetCachedToken( 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetExtension()->id(), oauth2_info.scopes, token); 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteMintTokenFlow(); 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteFunctionWithResult(access_token); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnMintTokenFailure( 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GoogleServiceAuthError& error) { 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteMintTokenFlow(); 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (error.state()) { 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case GoogleServiceAuthError::ACCOUNT_DELETED: 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case GoogleServiceAuthError::ACCOUNT_DISABLED: 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extensions::IdentityAPI::GetFactoryInstance()->GetForProfile( 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile())->ReportAuthError(error); 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (should_prompt_for_signin_) { 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Display a login prompt and try again (once). 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartSigninFlow(); 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Return error to caller. 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteFunctionWithError( 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(identity_constants::kAuthFailure) + error.ToString()); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnIssueAdviceSuccess( 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IssueAdviceInfo& issue_advice) { 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityAPI::GetFactoryInstance()->GetForProfile(profile())->SetCachedToken( 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetExtension()->id(), oauth2_info.scopes, 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityTokenCacheValue(issue_advice)); 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteMintTokenFlow(); 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_prompt_for_signin_ = false; 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Existing grant was revoked and we used NO_FORCE, so we got info back 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // instead. Start a consent UI if we can. 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) issue_advice_ = issue_advice; 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::SigninSuccess(const std::string& token) { 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) refresh_token_ = token; 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::SigninFailed() { 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteFunctionWithError(identity_constants::kUserNotSignedIn); 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnGaiaFlowFailure( 30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GaiaWebAuthFlow::Failure failure, 30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GoogleServiceAuthError service_error, 30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& oauth_error) { 30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CompleteMintTokenFlow(); 30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string error; 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switch (failure) { 30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case GaiaWebAuthFlow::WINDOW_CLOSED: 31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error = identity_constants::kUserRejected; 31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case GaiaWebAuthFlow::INVALID_REDIRECT: 31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error = identity_constants::kInvalidRedirect; 31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case GaiaWebAuthFlow::SERVICE_AUTH_ERROR: 31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error = std::string(identity_constants::kAuthFailure) + 31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) service_error.ToString(); 32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case GaiaWebAuthFlow::OAUTH_ERROR: 32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error = MapOAuth2ErrorToDescription(oauth_error); 32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(courage): load failure tests 327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case GaiaWebAuthFlow::LOAD_FAILED: 329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = identity_constants::kPageLoadFailure; 330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default: 33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NOTREACHED() << "Unexpected error from gaia web auth flow: " << failure; 33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error = identity_constants::kInvalidRedirect; 33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CompleteFunctionWithError(error); 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnGaiaFlowCompleted( 34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& access_token, 34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& expiration) { 34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int time_to_live; 34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!expiration.empty() && base::StringToInt(expiration, &time_to_live)) { 34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); 34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) IdentityTokenCacheValue token_value( 34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) access_token, base::TimeDelta::FromSeconds(time_to_live)); 35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) IdentityAPI::GetFactoryInstance()->GetForProfile(profile()) 35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ->SetCachedToken(GetExtension()->id(), oauth2_info.scopes, token_value); 35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteMintTokenFlow(); 35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CompleteFunctionWithResult(access_token); 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartGaiaRequest( 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OAuth2MintTokenFlow::Mode mode) { 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mint_token_flow_.reset(CreateMintTokenFlow(mode)); 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mint_token_flow_->Start(); 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::ShowLoginPopup() { 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signin_flow_.reset(new IdentitySigninFlow(this, profile())); 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signin_flow_->Start(); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IdentityGetAuthTokenFunction::ShowOAuthApprovalDialog( 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IssueAdviceInfo& issue_advice) { 37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); 372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string locale = g_browser_process->local_state()->GetString( 373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) prefs::kApplicationLocale); 37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 37590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) gaia_web_auth_flow_.reset(new GaiaWebAuthFlow( 376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this, profile(), GetExtension()->id(), oauth2_info, locale)); 37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) gaia_web_auth_flow_->Start(); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OAuth2MintTokenFlow* IdentityGetAuthTokenFunction::CreateMintTokenFlow( 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OAuth2MintTokenFlow::Mode mode) { 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension()); 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OAuth2MintTokenFlow* mint_token_flow = 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new OAuth2MintTokenFlow( 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile()->GetRequestContext(), 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OAuth2MintTokenFlow::Parameters( 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) refresh_token_, 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetExtension()->id(), 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) oauth2_info.client_id, 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) oauth2_info.scopes, 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mode)); 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS) 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (chrome::IsRunningInForcedAppMode()) { 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string chrome_client_id; 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string chrome_client_secret; 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (chromeos::UserManager::Get()->GetAppModeChromeClientOAuthInfo( 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &chrome_client_id, &chrome_client_secret)) { 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mint_token_flow->SetChromeOAuthClientInfo(chrome_client_id, 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chrome_client_secret); 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return mint_token_flow; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IdentityGetAuthTokenFunction::HasLoginToken() const { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TokenService* token_service = TokenServiceFactory::GetForProfile(profile()); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return token_service->HasOAuthLoginToken(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string IdentityGetAuthTokenFunction::MapOAuth2ErrorToDescription( 41390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& error) { 41490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kOAuth2ErrorAccessDenied[] = "access_denied"; 41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kOAuth2ErrorInvalidScope[] = "invalid_scope"; 41690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (error == kOAuth2ErrorAccessDenied) 41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return std::string(identity_constants::kUserRejected); 41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else if (error == kOAuth2ErrorInvalidScope) 42090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return std::string(identity_constants::kInvalidScopes); 42190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else 42290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return std::string(identity_constants::kAuthFailure) + error; 42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityRemoveCachedAuthTokenFunction::IdentityRemoveCachedAuthTokenFunction() { 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityRemoveCachedAuthTokenFunction:: 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~IdentityRemoveCachedAuthTokenFunction() { 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IdentityRemoveCachedAuthTokenFunction::RunImpl() { 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (profile()->IsOffTheRecord()) { 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = identity_constants::kOffTheRecord; 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<identity::RemoveCachedAuthToken::Params> params( 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) identity::RemoveCachedAuthToken::Params::Create(*args_)); 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityAPI::GetFactoryInstance()->GetForProfile(profile())->EraseCachedToken( 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetExtension()->id(), params->details.token); 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IdentityLaunchWebAuthFlowFunction::IdentityLaunchWebAuthFlowFunction() {} 44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 44890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IdentityLaunchWebAuthFlowFunction::~IdentityLaunchWebAuthFlowFunction() { 44990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (auth_flow_) 45090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) auth_flow_.release()->DetachDelegateAndDelete(); 45190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IdentityLaunchWebAuthFlowFunction::RunImpl() { 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (profile()->IsOffTheRecord()) { 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = identity_constants::kOffTheRecord; 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<identity::LaunchWebAuthFlow::Params> params( 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) identity::LaunchWebAuthFlow::Params::Create(*args_)); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL auth_url(params->details.url); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebAuthFlow::Mode mode = 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params->details.interactive && *params->details.interactive ? 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebAuthFlow::INTERACTIVE : WebAuthFlow::SILENT; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Set up acceptable target URLs. (Does not include chrome-extension 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // scheme for this version of the API.) 470b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) InitFinalRedirectURLPrefix(GetExtension()->id()); 471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRef(); // Balanced in OnAuthFlowSuccess/Failure. 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) auth_flow_.reset(new WebAuthFlow(this, profile(), auth_url, mode)); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_flow_->Start(); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 479b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::InitFinalRedirectURLPrefixForTest( 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& extension_id) { 481b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) InitFinalRedirectURLPrefix(extension_id); 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 484b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::InitFinalRedirectURLPrefix( 485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& extension_id) { 486b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (final_url_prefix_.is_empty()) { 487b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) final_url_prefix_ = GURL(base::StringPrintf( 488b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) kChromiumDomainRedirectUrlPattern, extension_id.c_str())); 489b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::OnAuthFlowFailure( 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebAuthFlow::Failure failure) { 494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (failure) { 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case WebAuthFlow::WINDOW_CLOSED: 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = identity_constants::kUserRejected; 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case WebAuthFlow::INTERACTION_REQUIRED: 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = identity_constants::kInteractionRequired; 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case WebAuthFlow::LOAD_FAILED: 502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error_ = identity_constants::kPageLoadFailure; 503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NOTREACHED() << "Unexpected error from web auth flow: " << failure; 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = identity_constants::kInvalidRedirect; 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(false); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); // Balanced in RunImpl. 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::OnAuthFlowURLChange( 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL& redirect_url) { 515b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (redirect_url.GetWithEmptyPath() == final_url_prefix_) { 516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetResult(Value::CreateStringValue(redirect_url.spec())); 517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(true); 518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Release(); // Balanced in RunImpl. 519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::IdentityTokenCacheValue() 523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : status_(CACHE_STATUS_NOTFOUND) { 524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::IdentityTokenCacheValue( 527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IssueAdviceInfo& issue_advice) : status_(CACHE_STATUS_ADVICE), 528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) issue_advice_(issue_advice) { 529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expiration_time_ = base::Time::Now() + base::TimeDelta::FromSeconds( 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) identity_constants::kCachedIssueAdviceTTLSeconds); 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::IdentityTokenCacheValue( 534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& token, base::TimeDelta time_to_live) 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : status_(CACHE_STATUS_TOKEN), 536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_(token) { 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::TimeDelta zero_delta; 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (time_to_live < zero_delta) 539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) time_to_live = zero_delta; 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expiration_time_ = base::Time::Now() + time_to_live; 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::~IdentityTokenCacheValue() { 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::CacheValueStatus 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityTokenCacheValue::status() const { 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (is_expired()) 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND; 551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status_; 553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const IssueAdviceInfo& IdentityTokenCacheValue::issue_advice() const { 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return issue_advice_; 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::string& IdentityTokenCacheValue::token() const { 560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return token_; 561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IdentityTokenCacheValue::is_expired() const { 564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status_ == CACHE_STATUS_NOTFOUND || 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expiration_time_ < base::Time::Now(); 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 56890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const base::Time& IdentityTokenCacheValue::expiration_time() const { 56990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return expiration_time_; 57090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 57190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityAPI::IdentityAPI(Profile* profile) 573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : profile_(profile), 574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signin_manager_(NULL), 575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_(GoogleServiceAuthError::NONE) { 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IdentityAPI::~IdentityAPI() { 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::Initialize() { 582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signin_manager_ = SigninManagerFactory::GetForProfile(profile_); 583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signin_manager_->signin_global_error()->AddProvider(this); 584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) registrar_.Add(this, 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chrome::NOTIFICATION_TOKEN_AVAILABLE, 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::Source<TokenService>(token_service)); 589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityMintRequestQueue* IdentityAPI::mint_queue() { 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return &mint_queue_; 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::SetCachedToken(const std::string& extension_id, 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<std::string> scopes, 597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IdentityTokenCacheValue& token_data) { 598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::set<std::string> scopeset(scopes.begin(), scopes.end()); 599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TokenCacheKey key(extension_id, scopeset); 600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 60190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CachedTokens::iterator it = token_cache_.find(key); 602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (it != token_cache_.end() && it->second.status() <= token_data.status()) 603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_cache_.erase(it); 604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_cache_.insert(std::make_pair(key, token_data)); 606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::EraseCachedToken(const std::string& extension_id, 609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& token) { 61090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CachedTokens::iterator it; 611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (it = token_cache_.begin(); it != token_cache_.end(); ++it) { 612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (it->first.extension_id == extension_id && 613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) it->second.status() == IdentityTokenCacheValue::CACHE_STATUS_TOKEN && 614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) it->second.token() == token) { 615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_cache_.erase(it); 616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::EraseAllCachedTokens() { 622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_cache_.clear(); 623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const IdentityTokenCacheValue& IdentityAPI::GetCachedToken( 626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& extension_id, const std::vector<std::string> scopes) { 627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::set<std::string> scopeset(scopes.begin(), scopes.end()); 628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TokenCacheKey key(extension_id, scopeset); 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return token_cache_[key]; 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 63290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const IdentityAPI::CachedTokens& IdentityAPI::GetAllCachedTokens() { 63390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return token_cache_; 63490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 63590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::ReportAuthError(const GoogleServiceAuthError& error) { 637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!signin_manager_) 638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Initialize(); 639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = error; 641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signin_manager_->signin_global_error()->AuthStatusChanged(); 642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::Shutdown() { 645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (signin_manager_) 646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signin_manager_->signin_global_error()->RemoveProvider(this); 647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static base::LazyInstance<ProfileKeyedAPIFactory<IdentityAPI> > 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_factory = LAZY_INSTANCE_INITIALIZER; 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProfileKeyedAPIFactory<IdentityAPI>* IdentityAPI::GetFactoryInstance() { 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return &g_factory.Get(); 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GoogleServiceAuthError IdentityAPI::GetAuthStatus() const { 658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return error_; 659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::Observe(int type, 662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const content::NotificationSource& source, 663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const content::NotificationDetails& details) { 664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(type == chrome::NOTIFICATION_TOKEN_AVAILABLE); 665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TokenService::TokenAvailableDetails* token_details = 666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::Details<TokenService::TokenAvailableDetails>(details).ptr(); 667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (token_details->service() == 668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GaiaConstants::kGaiaOAuth2LoginRefreshToken) { 669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = GoogleServiceAuthError::AuthErrorNone(); 670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signin_manager_->signin_global_error()->AuthStatusChanged(); 671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <> 675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ProfileKeyedAPIFactory<IdentityAPI>::DeclareFactoryDependencies() { 676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DependsOn(ExtensionSystemFactory::GetInstance()); 677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DependsOn(TokenServiceFactory::GetInstance()); 678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DependsOn(SigninManagerFactory::GetInstance()); 679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityAPI::TokenCacheKey::TokenCacheKey(const std::string& extension_id, 682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::set<std::string> scopes) 683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : extension_id(extension_id), 684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scopes(scopes) { 685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityAPI::TokenCacheKey::~TokenCacheKey() { 688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IdentityAPI::TokenCacheKey::operator<( 691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IdentityAPI::TokenCacheKey& rhs) const { 692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (extension_id < rhs.extension_id) 693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else if (rhs.extension_id < extension_id) 695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return scopes < rhs.scopes; 698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 701