identity_api.cc revision 3551c9c881056c480085172ff9840cab31610854
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"
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_function_dispatcher.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/policy/browser_policy_connector.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/signin/profile_oauth2_token_service.h"
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/signin/signin_global_error.h"
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/api/identity.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension_manifest_constants.h"
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/pref_names.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "google_apis/gaia/gaia_urls.h"
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS)
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h"
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h"
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace identity_constants {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidClientId[] = "Invalid OAuth2 Client ID.";
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidScopes[] = "Invalid OAuth2 scopes.";
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAuthFailure[] = "OAuth2 request failed: ";
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNoGrant[] = "OAuth2 not granted or revoked.";
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserRejected[] = "The user did not approve access.";
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserNotSignedIn[] = "The user is not signed in.";
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kInteractionRequired[] = "User interaction required.";
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidRedirect[] = "Did not redirect to the right URL.";
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOffTheRecord[] = "Identity API is disabled in incognito windows.";
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kPageLoadFailure[] = "Authorization page could not be loaded.";
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kCachedIssueAdviceTTLSeconds = 1;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace identity_constants
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static const char kChromiumDomainRedirectUrlPattern[] =
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    "https://%s.chromiumapp.org/";
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace identity = api::identity;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IdentityGetAuthTokenFunction::IdentityGetAuthTokenFunction()
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : should_prompt_for_scopes_(false),
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      should_prompt_for_signin_(false) {}
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IdentityGetAuthTokenFunction::~IdentityGetAuthTokenFunction() {}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IdentityGetAuthTokenFunction::RunImpl() {
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (profile()->IsOffTheRecord()) {
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_ = identity_constants::kOffTheRecord;
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<identity::GetAuthToken::Params> params(
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      identity::GetAuthToken::Params::Create(*args_));
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool interactive = params->details.get() &&
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      params->details->interactive.get() &&
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *params->details->interactive;
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  should_prompt_for_scopes_ = interactive;
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  should_prompt_for_signin_ = interactive;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check that the necessary information is present in the manifest.
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  oauth2_client_id_ = GetOAuth2ClientId();
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (oauth2_client_id_.empty()) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_ = identity_constants::kInvalidClientId;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (oauth2_info.scopes.size() == 0) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_ = identity_constants::kInvalidScopes;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Balanced in CompleteFunctionWithResult|CompleteFunctionWithError
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRef();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_CHROMEOS)
108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (chromeos::UserManager::Get()->IsLoggedInAsKioskApp() &&
109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      g_browser_process->browser_policy_connector()->IsEnterpriseManaged()) {
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE);
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return true;
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HasLoginToken()) {
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!should_prompt_for_signin_) {
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      error_ = identity_constants::kUserNotSignedIn;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Release();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Display a login prompt.
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    StartSigninFlow();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::CompleteFunctionWithResult(
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& access_token) {
1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SetResult(new base::StringValue(access_token));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(true);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();  // Balanced in RunImpl.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::CompleteFunctionWithError(
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& error) {
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error_ = error;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(false);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();  // Balanced in RunImpl.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartSigninFlow() {
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // All cached tokens are invalid because the user is not signed in.
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api =
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(profile_);
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api->EraseAllCachedTokens();
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Display a login prompt. If the subsequent mint fails, don't display the
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // login prompt again.
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  should_prompt_for_signin_ = false;
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShowLoginPopup();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartMintTokenFlow(
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IdentityMintRequestQueue::MintType type) {
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  mint_token_flow_type_ = type;
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Flows are serialized to prevent excessive traffic to GAIA, and
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // to consolidate UI pop-ups.
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api =
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(profile_);
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!should_prompt_for_scopes_) {
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Caller requested no interaction.
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (type == IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE) {
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // GAIA told us to do a consent UI.
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CompleteFunctionWithError(identity_constants::kNoGrant);
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!id_api->mint_queue()->empty(
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE,
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetExtension()->id(), scopes)) {
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Another call is going through a consent UI.
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CompleteFunctionWithError(identity_constants::kNoGrant);
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api->mint_queue()->RequestStart(type,
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     GetExtension()->id(),
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     scopes,
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     this);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::CompleteMintTokenFlow() {
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type = mint_token_flow_type_;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_)->mint_queue()->RequestComplete(type,
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                               GetExtension()->id(),
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                               scopes,
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                               this);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartMintToken(
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IdentityMintRequestQueue::MintType type) {
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api = IdentityAPI::GetFactoryInstance()->GetForProfile(
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile());
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue cache_entry = id_api->GetCachedToken(
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetExtension()->id(), oauth2_info.scopes);
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue::CacheValueStatus cache_status =
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      cache_entry.status();
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (type == IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE) {
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    switch (cache_status) {
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND:
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_CHROMEOS)
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        // Always force minting token for ChromeOS kiosk app.
218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        if (chromeos::UserManager::Get()->IsLoggedInAsKioskApp()) {
219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          if (g_browser_process->browser_policy_connector()->
220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                  IsEnterpriseManaged()) {
221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            OAuth2TokenService::ScopeSet scope_set(oauth2_info.scopes.begin(),
222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                                   oauth2_info.scopes.end());
223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            device_token_request_ =
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                chromeos::DeviceOAuth2TokenServiceFactory::Get()->StartRequest(
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                    scope_set, this);
226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          } else {
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE;
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            StartLoginAccessTokenRequest();
229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          }
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          return;
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        }
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        if (oauth2_info.auto_approve)
2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          // oauth2_info.auto_approve is protected by a whitelist in
2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          // _manifest_features.json hence only selected extensions take
2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          // advantage of forcefully minting the token.
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE;
2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        else
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE;
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        StartLoginAccessTokenRequest();
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case IdentityTokenCacheValue::CACHE_STATUS_TOKEN:
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CompleteMintTokenFlow();
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CompleteFunctionWithResult(cache_entry.token());
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case IdentityTokenCacheValue::CACHE_STATUS_ADVICE:
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CompleteMintTokenFlow();
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        should_prompt_for_signin_ = false;
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        issue_advice_ = cache_entry.issue_advice();
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE);
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK(type == IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE);
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (cache_status == IdentityTokenCacheValue::CACHE_STATUS_TOKEN) {
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CompleteMintTokenFlow();
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CompleteFunctionWithResult(cache_entry.token());
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ShowOAuthApprovalDialog(issue_advice_);
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnMintTokenSuccess(
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& access_token, int time_to_live) {
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(access_token,
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(time_to_live));
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI::GetFactoryInstance()->GetForProfile(profile())->SetCachedToken(
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetExtension()->id(), oauth2_info.scopes, token);
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CompleteMintTokenFlow();
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CompleteFunctionWithResult(access_token);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnMintTokenFailure(
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GoogleServiceAuthError& error) {
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CompleteMintTokenFlow();
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (error.state()) {
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case GoogleServiceAuthError::ACCOUNT_DELETED:
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case GoogleServiceAuthError::ACCOUNT_DISABLED:
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          profile())->ReportAuthError(error);
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (should_prompt_for_signin_) {
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Display a login prompt and try again (once).
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        StartSigninFlow();
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    default:
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Return error to caller.
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CompleteFunctionWithError(
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string(identity_constants::kAuthFailure) + error.ToString());
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnIssueAdviceSuccess(
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const IssueAdviceInfo& issue_advice) {
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI::GetFactoryInstance()->GetForProfile(profile())->SetCachedToken(
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetExtension()->id(), oauth2_info.scopes,
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityTokenCacheValue(issue_advice));
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CompleteMintTokenFlow();
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  should_prompt_for_signin_ = false;
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Existing grant was revoked and we used NO_FORCE, so we got info back
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // instead. Start a consent UI if we can.
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  issue_advice_ = issue_advice;
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid IdentityGetAuthTokenFunction::SigninSuccess() {
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::SigninFailed() {
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CompleteFunctionWithError(identity_constants::kUserNotSignedIn);
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnGaiaFlowFailure(
32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GaiaWebAuthFlow::Failure failure,
33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GoogleServiceAuthError service_error,
33190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& oauth_error) {
33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CompleteMintTokenFlow();
33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string error;
33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  switch (failure) {
33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case GaiaWebAuthFlow::WINDOW_CLOSED:
33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      error = identity_constants::kUserRejected;
33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case GaiaWebAuthFlow::INVALID_REDIRECT:
34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      error = identity_constants::kInvalidRedirect;
34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case GaiaWebAuthFlow::SERVICE_AUTH_ERROR:
34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      error = std::string(identity_constants::kAuthFailure) +
34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          service_error.ToString();
34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case GaiaWebAuthFlow::OAUTH_ERROR:
35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      error = MapOAuth2ErrorToDescription(oauth_error);
35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case GaiaWebAuthFlow::LOAD_FAILED:
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      error = identity_constants::kPageLoadFailure;
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    default:
35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      NOTREACHED() << "Unexpected error from gaia web auth flow: " << failure;
35990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      error = identity_constants::kInvalidRedirect;
36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
36290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CompleteFunctionWithError(error);
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnGaiaFlowCompleted(
36790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& access_token,
36890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& expiration) {
36990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int time_to_live;
37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!expiration.empty() && base::StringToInt(expiration, &time_to_live)) {
37290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    IdentityTokenCacheValue token_value(
37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        access_token, base::TimeDelta::FromSeconds(time_to_live));
37590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    IdentityAPI::GetFactoryInstance()->GetForProfile(profile())
37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        ->SetCachedToken(GetExtension()->id(), oauth2_info.scopes, token_value);
37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CompleteMintTokenFlow();
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CompleteFunctionWithResult(access_token);
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IdentityGetAuthTokenFunction::OnGetTokenSuccess(
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const OAuth2TokenService::Request* request,
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& access_token,
386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::Time& expiration_time) {
3877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (login_token_request_.get() == request) {
3887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    login_token_request_.reset();
3897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    StartGaiaRequest(access_token);
3907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else {
3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DCHECK_EQ(device_token_request_.get(), request);
3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    device_token_request_.reset();
393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    IdentityTokenCacheValue token(access_token,
3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                  expiration_time - base::Time::Now());
3977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    IdentityAPI::GetFactoryInstance()->GetForProfile(profile())->SetCachedToken(
3987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        GetExtension()->id(), oauth2_info.scopes, token);
399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    CompleteMintTokenFlow();
4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    CompleteFunctionWithResult(access_token);
4027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IdentityGetAuthTokenFunction::OnGetTokenFailure(
406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const OAuth2TokenService::Request* request,
407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const GoogleServiceAuthError& error) {
4087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (login_token_request_.get() == request) {
4097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    login_token_request_.reset();
4107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else {
4117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DCHECK_EQ(device_token_request_.get(), request);
4127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    device_token_request_.reset();
4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  OnGaiaFlowFailure(GaiaWebAuthFlow::SERVICE_AUTH_ERROR, error, std::string());
416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid IdentityGetAuthTokenFunction::StartLoginAccessTokenRequest() {
419a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ProfileOAuth2TokenService* service =
420a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ProfileOAuth2TokenServiceFactory::GetForProfile(profile());
421a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(OS_CHROMEOS)
422a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (chrome::IsRunningInForcedAppMode()) {
423a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    std::string app_client_id;
424a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    std::string app_client_secret;
425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (chromeos::UserManager::Get()->GetAppModeChromeClientOAuthInfo(
426a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)           &app_client_id, &app_client_secret)) {
427a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      login_token_request_ =
428a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          service->StartRequestForClient(app_client_id,
429a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                         app_client_secret,
430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                         OAuth2TokenService::ScopeSet(),
431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                         this);
432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return;
433a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif
436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  login_token_request_ = service->StartRequest(OAuth2TokenService::ScopeSet(),
437a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                               this);
4387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartGaiaRequest(
4417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& login_access_token) {
4427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(!login_access_token.empty());
4437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  mint_token_flow_.reset(CreateMintTokenFlow(login_access_token));
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  mint_token_flow_->Start();
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::ShowLoginPopup() {
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signin_flow_.reset(new IdentitySigninFlow(this, profile()));
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signin_flow_->Start();
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IdentityGetAuthTokenFunction::ShowOAuthApprovalDialog(
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IssueAdviceInfo& issue_advice) {
45490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const std::string locale = g_browser_process->local_state()->GetString(
456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      prefs::kApplicationLocale);
45790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
45890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gaia_web_auth_flow_.reset(new GaiaWebAuthFlow(
459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      this, profile(), GetExtension()->id(), oauth2_info, locale));
46090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gaia_web_auth_flow_->Start();
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OAuth2MintTokenFlow* IdentityGetAuthTokenFunction::CreateMintTokenFlow(
4647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& login_access_token) {
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  OAuth2MintTokenFlow* mint_token_flow =
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new OAuth2MintTokenFlow(
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          profile()->GetRequestContext(),
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          this,
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          OAuth2MintTokenFlow::Parameters(
4727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              login_access_token,
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              GetExtension()->id(),
474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              oauth2_client_id_,
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              oauth2_info.scopes,
4767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              gaia_mint_token_mode_));
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return mint_token_flow;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IdentityGetAuthTokenFunction::HasLoginToken() const {
4817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return ProfileOAuth2TokenServiceFactory::GetForProfile(profile())->
4827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      RefreshTokenIsAvailable();
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string IdentityGetAuthTokenFunction::MapOAuth2ErrorToDescription(
48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& error) {
48790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const char kOAuth2ErrorAccessDenied[] = "access_denied";
48890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const char kOAuth2ErrorInvalidScope[] = "invalid_scope";
48990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
49090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (error == kOAuth2ErrorAccessDenied)
49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return std::string(identity_constants::kUserRejected);
49290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  else if (error == kOAuth2ErrorInvalidScope)
49390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return std::string(identity_constants::kInvalidScopes);
49490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  else
49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return std::string(identity_constants::kAuthFailure) + error;
49690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
49790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string IdentityGetAuthTokenFunction::GetOAuth2ClientId() const {
499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string client_id = oauth2_info.client_id;
501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Component apps using auto_approve may use Chrome's client ID by
503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // omitting the field.
504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (client_id.empty() && GetExtension()->location() == Manifest::COMPONENT &&
505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      oauth2_info.auto_approve) {
506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    client_id = GaiaUrls::GetInstance()->oauth2_chrome_client_id();
507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return client_id;
509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityRemoveCachedAuthTokenFunction::IdentityRemoveCachedAuthTokenFunction() {
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityRemoveCachedAuthTokenFunction::
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ~IdentityRemoveCachedAuthTokenFunction() {
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IdentityRemoveCachedAuthTokenFunction::RunImpl() {
519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (profile()->IsOffTheRecord()) {
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_ = identity_constants::kOffTheRecord;
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<identity::RemoveCachedAuthToken::Params> params(
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      identity::RemoveCachedAuthToken::Params::Create(*args_));
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI::GetFactoryInstance()->GetForProfile(profile())->EraseCachedToken(
528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetExtension()->id(), params->details.token);
529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IdentityLaunchWebAuthFlowFunction::IdentityLaunchWebAuthFlowFunction() {}
53390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
53490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IdentityLaunchWebAuthFlowFunction::~IdentityLaunchWebAuthFlowFunction() {
53590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (auth_flow_)
53690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    auth_flow_.release()->DetachDelegateAndDelete();
53790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IdentityLaunchWebAuthFlowFunction::RunImpl() {
540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (profile()->IsOffTheRecord()) {
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_ = identity_constants::kOffTheRecord;
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<identity::LaunchWebAuthFlow::Params> params(
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      identity::LaunchWebAuthFlow::Params::Create(*args_));
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GURL auth_url(params->details.url);
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebAuthFlow::Mode mode =
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      params->details.interactive && *params->details.interactive ?
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebAuthFlow::INTERACTIVE : WebAuthFlow::SILENT;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Set up acceptable target URLs. (Does not include chrome-extension
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // scheme for this version of the API.)
556b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  InitFinalRedirectURLPrefix(GetExtension()->id());
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRef();  // Balanced in OnAuthFlowSuccess/Failure.
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  auth_flow_.reset(new WebAuthFlow(this, profile(), auth_url, mode));
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_flow_->Start();
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::InitFinalRedirectURLPrefixForTest(
566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& extension_id) {
567b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  InitFinalRedirectURLPrefix(extension_id);
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
570b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::InitFinalRedirectURLPrefix(
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& extension_id) {
572b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (final_url_prefix_.is_empty()) {
573b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    final_url_prefix_ = GURL(base::StringPrintf(
574b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        kChromiumDomainRedirectUrlPattern, extension_id.c_str()));
575b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::OnAuthFlowFailure(
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    WebAuthFlow::Failure failure) {
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (failure) {
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case WebAuthFlow::WINDOW_CLOSED:
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      error_ = identity_constants::kUserRejected;
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case WebAuthFlow::INTERACTION_REQUIRED:
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      error_ = identity_constants::kInteractionRequired;
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case WebAuthFlow::LOAD_FAILED:
588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      error_ = identity_constants::kPageLoadFailure;
589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    default:
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NOTREACHED() << "Unexpected error from web auth flow: " << failure;
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      error_ = identity_constants::kInvalidRedirect;
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(false);
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();  // Balanced in RunImpl.
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::OnAuthFlowURLChange(
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GURL& redirect_url) {
601b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (redirect_url.GetWithEmptyPath() == final_url_prefix_) {
6023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    SetResult(new base::StringValue(redirect_url.spec()));
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SendResponse(true);
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Release();  // Balanced in RunImpl.
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::IdentityTokenCacheValue()
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : status_(CACHE_STATUS_NOTFOUND) {
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::IdentityTokenCacheValue(
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const IssueAdviceInfo& issue_advice) : status_(CACHE_STATUS_ADVICE),
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           issue_advice_(issue_advice) {
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expiration_time_ = base::Time::Now() + base::TimeDelta::FromSeconds(
616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      identity_constants::kCachedIssueAdviceTTLSeconds);
617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::IdentityTokenCacheValue(
620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& token, base::TimeDelta time_to_live)
621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : status_(CACHE_STATUS_TOKEN),
622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      token_(token) {
623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeDelta zero_delta;
624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (time_to_live < zero_delta)
625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    time_to_live = zero_delta;
626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expiration_time_ = base::Time::Now() + time_to_live;
628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::~IdentityTokenCacheValue() {
631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::CacheValueStatus
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IdentityTokenCacheValue::status() const {
635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (is_expired())
636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND;
637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else
638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return status_;
639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const IssueAdviceInfo& IdentityTokenCacheValue::issue_advice() const {
642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return issue_advice_;
643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::string& IdentityTokenCacheValue::token() const {
646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return token_;
647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IdentityTokenCacheValue::is_expired() const {
650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return status_ == CACHE_STATUS_NOTFOUND ||
651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      expiration_time_ < base::Time::Now();
652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
65490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const base::Time& IdentityTokenCacheValue::expiration_time() const {
65590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return expiration_time_;
65690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
65790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityAPI::IdentityAPI(Profile* profile)
659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : profile_(profile),
6607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      error_(GoogleServiceAuthError::NONE),
6617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      initialized_(false) {
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IdentityAPI::~IdentityAPI() {
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::Initialize() {
6687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SigninGlobalError::GetForProfile(profile_)->AddProvider(this);
6697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->AddObserver(this);
670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  initialized_ = true;
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityMintRequestQueue* IdentityAPI::mint_queue() {
675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return &mint_queue_;
676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::SetCachedToken(const std::string& extension_id,
679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 const std::vector<std::string> scopes,
680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 const IdentityTokenCacheValue& token_data) {
681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopeset(scopes.begin(), scopes.end());
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TokenCacheKey key(extension_id, scopeset);
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
68490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CachedTokens::iterator it = token_cache_.find(key);
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (it != token_cache_.end() && it->second.status() <= token_data.status())
686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    token_cache_.erase(it);
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  token_cache_.insert(std::make_pair(key, token_data));
689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::EraseCachedToken(const std::string& extension_id,
692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   const std::string& token) {
69390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CachedTokens::iterator it;
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (it = token_cache_.begin(); it != token_cache_.end(); ++it) {
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (it->first.extension_id == extension_id &&
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        it->second.status() == IdentityTokenCacheValue::CACHE_STATUS_TOKEN &&
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        it->second.token() == token) {
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      token_cache_.erase(it);
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::EraseAllCachedTokens() {
705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  token_cache_.clear();
706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const IdentityTokenCacheValue& IdentityAPI::GetCachedToken(
709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& extension_id, const std::vector<std::string> scopes) {
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopeset(scopes.begin(), scopes.end());
711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TokenCacheKey key(extension_id, scopeset);
712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return token_cache_[key];
713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
71590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const IdentityAPI::CachedTokens& IdentityAPI::GetAllCachedTokens() {
71690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return token_cache_;
71790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
71890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::ReportAuthError(const GoogleServiceAuthError& error) {
720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error_ = error;
7217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SigninGlobalError::GetForProfile(profile_)->AuthStatusChanged();
722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::Shutdown() {
7257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!initialized_)
7267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
7277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SigninGlobalError::GetForProfile(profile_)->RemoveProvider(this);
7297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->
7307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      RemoveObserver(this);
7317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  initialized_ = false;
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static base::LazyInstance<ProfileKeyedAPIFactory<IdentityAPI> >
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_factory = LAZY_INSTANCE_INITIALIZER;
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProfileKeyedAPIFactory<IdentityAPI>* IdentityAPI::GetFactoryInstance() {
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return &g_factory.Get();
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GoogleServiceAuthError IdentityAPI::GetAuthStatus() const {
744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return error_;
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid IdentityAPI::OnRefreshTokenAvailable(const std::string& account_id) {
7487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  error_ = GoogleServiceAuthError::AuthErrorNone();
749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <>
752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ProfileKeyedAPIFactory<IdentityAPI>::DeclareFactoryDependencies() {
753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DependsOn(ExtensionSystemFactory::GetInstance());
7547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Need dependency on ProfileOAuth2TokenServiceFactory because it owns
7557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // the SigninGlobalError instance.
7567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityAPI::TokenCacheKey::TokenCacheKey(const std::string& extension_id,
760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                          const std::set<std::string> scopes)
761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : extension_id(extension_id),
762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scopes(scopes) {
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityAPI::TokenCacheKey::~TokenCacheKey() {
766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IdentityAPI::TokenCacheKey::operator<(
769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const IdentityAPI::TokenCacheKey& rhs) const {
770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (extension_id < rhs.extension_id)
771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else if (rhs.extension_id < extension_id)
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return scopes < rhs.scopes;
776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
779