identity_api.cc revision f2477e01787aa58f445919b809d89e252beef54f
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"
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/policy/browser_policy_connector.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/signin/profile_oauth2_token_service.h"
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/signin/signin_global_error.h"
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/api/identity.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h"
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/pref_names.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h"
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "google_apis/gaia/gaia_urls.h"
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS)
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h"
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h"
418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "google_apis/gaia/gaia_constants.h"
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace identity_constants {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidClientId[] = "Invalid OAuth2 Client ID.";
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidScopes[] = "Invalid OAuth2 scopes.";
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAuthFailure[] = "OAuth2 request failed: ";
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNoGrant[] = "OAuth2 not granted or revoked.";
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserRejected[] = "The user did not approve access.";
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserNotSignedIn[] = "The user is not signed in.";
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kInteractionRequired[] = "User interaction required.";
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidRedirect[] = "Did not redirect to the right URL.";
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOffTheRecord[] = "Identity API is disabled in incognito windows.";
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kPageLoadFailure[] = "Authorization page could not be loaded.";
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kCachedIssueAdviceTTLSeconds = 1;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace identity_constants
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static const char kChromiumDomainRedirectUrlPattern[] =
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    "https://%s.chromiumapp.org/";
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace identity = api::identity;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IdentityGetAuthTokenFunction::IdentityGetAuthTokenFunction()
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : should_prompt_for_scopes_(false),
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      should_prompt_for_signin_(false) {}
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IdentityGetAuthTokenFunction::~IdentityGetAuthTokenFunction() {}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IdentityGetAuthTokenFunction::RunImpl() {
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (GetProfile()->IsOffTheRecord()) {
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_ = identity_constants::kOffTheRecord;
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<identity::GetAuthToken::Params> params(
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      identity::GetAuthToken::Params::Create(*args_));
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool interactive = params->details.get() &&
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      params->details->interactive.get() &&
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *params->details->interactive;
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  should_prompt_for_scopes_ = interactive;
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  should_prompt_for_signin_ = interactive;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check that the necessary information is present in the manifest.
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  oauth2_client_id_ = GetOAuth2ClientId();
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (oauth2_client_id_.empty()) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_ = identity_constants::kInvalidClientId;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (oauth2_info.scopes.size() == 0) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_ = identity_constants::kInvalidScopes;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Balanced in CompleteFunctionWithResult|CompleteFunctionWithError
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRef();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_CHROMEOS)
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (chromeos::UserManager::Get()->IsLoggedInAsKioskApp() &&
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      g_browser_process->browser_policy_connector()->IsEnterpriseManaged()) {
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE);
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return true;
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HasLoginToken()) {
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!should_prompt_for_signin_) {
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      error_ = identity_constants::kUserNotSignedIn;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Release();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Display a login prompt.
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    StartSigninFlow();
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::CompleteFunctionWithResult(
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& access_token) {
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SetResult(new base::StringValue(access_token));
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(true);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();  // Balanced in RunImpl.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::CompleteFunctionWithError(
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& error) {
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error_ = error;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(false);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();  // Balanced in RunImpl.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartSigninFlow() {
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // All cached tokens are invalid because the user is not signed in.
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api =
1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          GetProfile());
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api->EraseAllCachedTokens();
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Display a login prompt. If the subsequent mint fails, don't display the
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // login prompt again.
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  should_prompt_for_signin_ = false;
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShowLoginPopup();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartMintTokenFlow(
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IdentityMintRequestQueue::MintType type) {
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  mint_token_flow_type_ = type;
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Flows are serialized to prevent excessive traffic to GAIA, and
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // to consolidate UI pop-ups.
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api =
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          GetProfile());
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!should_prompt_for_scopes_) {
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Caller requested no interaction.
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (type == IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE) {
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // GAIA told us to do a consent UI.
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CompleteFunctionWithError(identity_constants::kNoGrant);
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!id_api->mint_queue()->empty(
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE,
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetExtension()->id(), scopes)) {
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Another call is going through a consent UI.
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CompleteFunctionWithError(identity_constants::kNoGrant);
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api->mint_queue()->RequestStart(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::CompleteMintTokenFlow() {
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type = mint_token_flow_type_;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  extensions::IdentityAPI::GetFactoryInstance()
2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ->GetForProfile(GetProfile())
2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ->mint_queue()
2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ->RequestComplete(type, GetExtension()->id(), scopes, this);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartMintToken(
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IdentityMintRequestQueue::MintType type) {
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
2091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  IdentityAPI* id_api =
2101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      IdentityAPI::GetFactoryInstance()->GetForProfile(GetProfile());
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue cache_entry = id_api->GetCachedToken(
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetExtension()->id(), oauth2_info.scopes);
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue::CacheValueStatus cache_status =
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      cache_entry.status();
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (type == IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE) {
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    switch (cache_status) {
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND:
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_CHROMEOS)
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        // Always force minting token for ChromeOS kiosk app.
221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        if (chromeos::UserManager::Get()->IsLoggedInAsKioskApp()) {
2228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE;
223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          if (g_browser_process->browser_policy_connector()->
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                  IsEnterpriseManaged()) {
2258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            StartDeviceLoginAccessTokenRequest();
226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          } else {
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            StartLoginAccessTokenRequest();
228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          }
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          return;
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        }
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        if (oauth2_info.auto_approve)
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          // oauth2_info.auto_approve is protected by a whitelist in
2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          // _manifest_features.json hence only selected extensions take
2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          // advantage of forcefully minting the token.
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE;
2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        else
2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE;
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        StartLoginAccessTokenRequest();
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case IdentityTokenCacheValue::CACHE_STATUS_TOKEN:
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CompleteMintTokenFlow();
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CompleteFunctionWithResult(cache_entry.token());
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case IdentityTokenCacheValue::CACHE_STATUS_ADVICE:
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CompleteMintTokenFlow();
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        should_prompt_for_signin_ = false;
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        issue_advice_ = cache_entry.issue_advice();
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE);
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK(type == IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE);
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (cache_status == IdentityTokenCacheValue::CACHE_STATUS_TOKEN) {
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CompleteMintTokenFlow();
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CompleteFunctionWithResult(cache_entry.token());
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ShowOAuthApprovalDialog(issue_advice_);
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnMintTokenSuccess(
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& access_token, int time_to_live) {
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(access_token,
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(time_to_live));
2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  IdentityAPI::GetFactoryInstance()
2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ->GetForProfile(GetProfile())
2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ->SetCachedToken(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:
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case GoogleServiceAuthError::SERVICE_ERROR:
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case GoogleServiceAuthError::ACCOUNT_DELETED:
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case GoogleServiceAuthError::ACCOUNT_DISABLED:
2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()
2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          ->GetForProfile(GetProfile())
2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          ->ReportAuthError(error);
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (should_prompt_for_signin_) {
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Display a login prompt and try again (once).
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        StartSigninFlow();
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    default:
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Return error to caller.
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CompleteFunctionWithError(
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string(identity_constants::kAuthFailure) + error.ToString());
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnIssueAdviceSuccess(
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const IssueAdviceInfo& issue_advice) {
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  IdentityAPI::GetFactoryInstance()
3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ->GetForProfile(GetProfile())
3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ->SetCachedToken(GetExtension()->id(),
3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                       oauth2_info.scopes,
3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                       IdentityTokenCacheValue(issue_advice));
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CompleteMintTokenFlow();
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  should_prompt_for_signin_ = false;
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Existing grant was revoked and we used NO_FORCE, so we got info back
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // instead. Start a consent UI if we can.
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  issue_advice_ = issue_advice;
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid IdentityGetAuthTokenFunction::SigninSuccess() {
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::SigninFailed() {
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CompleteFunctionWithError(identity_constants::kUserNotSignedIn);
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnGaiaFlowFailure(
33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GaiaWebAuthFlow::Failure failure,
33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GoogleServiceAuthError service_error,
33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& oauth_error) {
33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CompleteMintTokenFlow();
33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string error;
33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  switch (failure) {
34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case GaiaWebAuthFlow::WINDOW_CLOSED:
34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      error = identity_constants::kUserRejected;
34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case GaiaWebAuthFlow::INVALID_REDIRECT:
34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      error = identity_constants::kInvalidRedirect;
34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case GaiaWebAuthFlow::SERVICE_AUTH_ERROR:
34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      error = std::string(identity_constants::kAuthFailure) +
35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          service_error.ToString();
35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case GaiaWebAuthFlow::OAUTH_ERROR:
35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      error = MapOAuth2ErrorToDescription(oauth_error);
35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case GaiaWebAuthFlow::LOAD_FAILED:
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      error = identity_constants::kPageLoadFailure;
359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    default:
36290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      NOTREACHED() << "Unexpected error from gaia web auth flow: " << failure;
36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      error = identity_constants::kInvalidRedirect;
36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
36790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CompleteFunctionWithError(error);
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnGaiaFlowCompleted(
37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& access_token,
37290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& expiration) {
37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int time_to_live;
37590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!expiration.empty() && base::StringToInt(expiration, &time_to_live)) {
37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    IdentityTokenCacheValue token_value(
37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        access_token, base::TimeDelta::FromSeconds(time_to_live));
3791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    IdentityAPI::GetFactoryInstance()
3801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        ->GetForProfile(GetProfile())
38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        ->SetCachedToken(GetExtension()->id(), oauth2_info.scopes, token_value);
38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CompleteMintTokenFlow();
38590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CompleteFunctionWithResult(access_token);
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IdentityGetAuthTokenFunction::OnGetTokenSuccess(
389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const OAuth2TokenService::Request* request,
390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& access_token,
391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::Time& expiration_time) {
3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  login_token_request_.reset();
3938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  StartGaiaRequest(access_token);
394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IdentityGetAuthTokenFunction::OnGetTokenFailure(
397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const OAuth2TokenService::Request* request,
398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const GoogleServiceAuthError& error) {
3998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  login_token_request_.reset();
400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  OnGaiaFlowFailure(GaiaWebAuthFlow::SERVICE_AUTH_ERROR, error, std::string());
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_CHROMEOS)
4048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartDeviceLoginAccessTokenRequest() {
4051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  chromeos::DeviceOAuth2TokenServiceFactory::Get(
4061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::Bind(&IdentityGetAuthTokenFunction::DidGetTokenService,
4071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 this));
4081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
4091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void IdentityGetAuthTokenFunction::DidGetTokenService(
4111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    chromeos::DeviceOAuth2TokenService* service) {
4121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!service) {
4131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CompleteFunctionWithError(identity_constants::kUserNotSignedIn);
4141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return;
4151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Since robot account refresh tokens are scoped down to [any-api] only,
4178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // request access token for [any-api] instead of login.
4188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  OAuth2TokenService::ScopeSet scopes;
4198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scopes.insert(GaiaConstants::kAnyApiOAuth2Scope);
4208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  login_token_request_ =
4218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      service->StartRequest(service->GetRobotAccountId(),
4228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                            scopes,
4238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                            this);
4248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif
4268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid IdentityGetAuthTokenFunction::StartLoginAccessTokenRequest() {
428a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ProfileOAuth2TokenService* service =
4291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile());
430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(OS_CHROMEOS)
431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (chrome::IsRunningInForcedAppMode()) {
432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    std::string app_client_id;
433a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    std::string app_client_secret;
434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (chromeos::UserManager::Get()->GetAppModeChromeClientOAuthInfo(
435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)           &app_client_id, &app_client_secret)) {
436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      login_token_request_ =
43768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          service->StartRequestForClient(service->GetPrimaryAccountId(),
43868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                         app_client_id,
439a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                         app_client_secret,
440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                         OAuth2TokenService::ScopeSet(),
441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                         this);
442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return;
443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif
44668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  login_token_request_ = service->StartRequest(
44768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      service->GetPrimaryAccountId(), OAuth2TokenService::ScopeSet(), this);
4487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartGaiaRequest(
4517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& login_access_token) {
4527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(!login_access_token.empty());
4537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  mint_token_flow_.reset(CreateMintTokenFlow(login_access_token));
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  mint_token_flow_->Start();
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::ShowLoginPopup() {
4581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  signin_flow_.reset(new IdentitySigninFlow(this, GetProfile()));
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  signin_flow_->Start();
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IdentityGetAuthTokenFunction::ShowOAuthApprovalDialog(
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IssueAdviceInfo& issue_advice) {
46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const std::string locale = g_browser_process->local_state()->GetString(
466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      prefs::kApplicationLocale);
46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
46890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gaia_web_auth_flow_.reset(new GaiaWebAuthFlow(
4691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      this, GetProfile(), GetExtension()->id(), oauth2_info, locale));
47090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gaia_web_auth_flow_->Start();
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OAuth2MintTokenFlow* IdentityGetAuthTokenFunction::CreateMintTokenFlow(
4747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& login_access_token) {
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  OAuth2MintTokenFlow* mint_token_flow = new OAuth2MintTokenFlow(
4781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      GetProfile()->GetRequestContext(),
4791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      this,
4801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      OAuth2MintTokenFlow::Parameters(login_access_token,
4811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                      GetExtension()->id(),
4821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                      oauth2_client_id_,
4831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                      oauth2_info.scopes,
4841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                      gaia_mint_token_mode_));
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return mint_token_flow;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IdentityGetAuthTokenFunction::HasLoginToken() const {
48968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ProfileOAuth2TokenService* token_service =
4901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile());
49168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return token_service->RefreshTokenIsAvailable(
49268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      token_service->GetPrimaryAccountId());
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string IdentityGetAuthTokenFunction::MapOAuth2ErrorToDescription(
49690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& error) {
49790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const char kOAuth2ErrorAccessDenied[] = "access_denied";
49890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const char kOAuth2ErrorInvalidScope[] = "invalid_scope";
49990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
50090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (error == kOAuth2ErrorAccessDenied)
50190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return std::string(identity_constants::kUserRejected);
50290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  else if (error == kOAuth2ErrorInvalidScope)
50390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return std::string(identity_constants::kInvalidScopes);
50490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  else
50590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return std::string(identity_constants::kAuthFailure) + error;
50690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
50790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string IdentityGetAuthTokenFunction::GetOAuth2ClientId() const {
509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(GetExtension());
510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string client_id = oauth2_info.client_id;
511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Component apps using auto_approve may use Chrome's client ID by
513eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // omitting the field.
514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (client_id.empty() && GetExtension()->location() == Manifest::COMPONENT &&
515eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      oauth2_info.auto_approve) {
516eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    client_id = GaiaUrls::GetInstance()->oauth2_chrome_client_id();
517eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
518eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return client_id;
519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityRemoveCachedAuthTokenFunction::IdentityRemoveCachedAuthTokenFunction() {
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityRemoveCachedAuthTokenFunction::
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ~IdentityRemoveCachedAuthTokenFunction() {
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IdentityRemoveCachedAuthTokenFunction::RunImpl() {
5291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (GetProfile()->IsOffTheRecord()) {
530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_ = identity_constants::kOffTheRecord;
531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<identity::RemoveCachedAuthToken::Params> params(
535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      identity::RemoveCachedAuthToken::Params::Create(*args_));
536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
5371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  IdentityAPI::GetFactoryInstance()
5381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ->GetForProfile(GetProfile())
5391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ->EraseCachedToken(GetExtension()->id(), params->details.token);
540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IdentityLaunchWebAuthFlowFunction::IdentityLaunchWebAuthFlowFunction() {}
54490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
54590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IdentityLaunchWebAuthFlowFunction::~IdentityLaunchWebAuthFlowFunction() {
54690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (auth_flow_)
54790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    auth_flow_.release()->DetachDelegateAndDelete();
54890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IdentityLaunchWebAuthFlowFunction::RunImpl() {
5511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (GetProfile()->IsOffTheRecord()) {
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_ = identity_constants::kOffTheRecord;
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<identity::LaunchWebAuthFlow::Params> params(
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      identity::LaunchWebAuthFlow::Params::Create(*args_));
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GURL auth_url(params->details.url);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebAuthFlow::Mode mode =
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      params->details.interactive && *params->details.interactive ?
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebAuthFlow::INTERACTIVE : WebAuthFlow::SILENT;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Set up acceptable target URLs. (Does not include chrome-extension
566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // scheme for this version of the API.)
567b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  InitFinalRedirectURLPrefix(GetExtension()->id());
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRef();  // Balanced in OnAuthFlowSuccess/Failure.
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  auth_flow_.reset(new WebAuthFlow(this, GetProfile(), auth_url, mode));
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_flow_->Start();
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
576b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::InitFinalRedirectURLPrefixForTest(
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& extension_id) {
578b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  InitFinalRedirectURLPrefix(extension_id);
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
581b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::InitFinalRedirectURLPrefix(
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& extension_id) {
583b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (final_url_prefix_.is_empty()) {
584b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    final_url_prefix_ = GURL(base::StringPrintf(
585b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        kChromiumDomainRedirectUrlPattern, extension_id.c_str()));
586b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::OnAuthFlowFailure(
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    WebAuthFlow::Failure failure) {
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (failure) {
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case WebAuthFlow::WINDOW_CLOSED:
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      error_ = identity_constants::kUserRejected;
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case WebAuthFlow::INTERACTION_REQUIRED:
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      error_ = identity_constants::kInteractionRequired;
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case WebAuthFlow::LOAD_FAILED:
599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      error_ = identity_constants::kPageLoadFailure;
600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    default:
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NOTREACHED() << "Unexpected error from web auth flow: " << failure;
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      error_ = identity_constants::kInvalidRedirect;
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(false);
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();  // Balanced in RunImpl.
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::OnAuthFlowURLChange(
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GURL& redirect_url) {
612b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (redirect_url.GetWithEmptyPath() == final_url_prefix_) {
6133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    SetResult(new base::StringValue(redirect_url.spec()));
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SendResponse(true);
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Release();  // Balanced in RunImpl.
616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::IdentityTokenCacheValue()
620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : status_(CACHE_STATUS_NOTFOUND) {
621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::IdentityTokenCacheValue(
624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const IssueAdviceInfo& issue_advice) : status_(CACHE_STATUS_ADVICE),
625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           issue_advice_(issue_advice) {
626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expiration_time_ = base::Time::Now() + base::TimeDelta::FromSeconds(
627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      identity_constants::kCachedIssueAdviceTTLSeconds);
628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::IdentityTokenCacheValue(
631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& token, base::TimeDelta time_to_live)
632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : status_(CACHE_STATUS_TOKEN),
633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      token_(token) {
63468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Remove 20 minutes from the ttl so cached tokens will have some time
63568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // to live any time they are returned.
63668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  time_to_live -= base::TimeDelta::FromMinutes(20);
63768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeDelta zero_delta;
639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (time_to_live < zero_delta)
640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    time_to_live = zero_delta;
641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expiration_time_ = base::Time::Now() + time_to_live;
643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::~IdentityTokenCacheValue() {
646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityTokenCacheValue::CacheValueStatus
649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IdentityTokenCacheValue::status() const {
650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (is_expired())
651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND;
652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else
653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return status_;
654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const IssueAdviceInfo& IdentityTokenCacheValue::issue_advice() const {
657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return issue_advice_;
658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::string& IdentityTokenCacheValue::token() const {
661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return token_;
662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IdentityTokenCacheValue::is_expired() const {
665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return status_ == CACHE_STATUS_NOTFOUND ||
666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      expiration_time_ < base::Time::Now();
667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
66990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const base::Time& IdentityTokenCacheValue::expiration_time() const {
67090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return expiration_time_;
67190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
67290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityAPI::IdentityAPI(Profile* profile)
674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : profile_(profile),
6751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      account_tracker_(profile) {
6768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  account_tracker_.AddObserver(this);
6774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)IdentityAPI::~IdentityAPI() {}
680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityMintRequestQueue* IdentityAPI::mint_queue() {
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return &mint_queue_;
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::SetCachedToken(const std::string& extension_id,
686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 const std::vector<std::string> scopes,
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 const IdentityTokenCacheValue& token_data) {
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopeset(scopes.begin(), scopes.end());
689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TokenCacheKey key(extension_id, scopeset);
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
69190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CachedTokens::iterator it = token_cache_.find(key);
692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (it != token_cache_.end() && it->second.status() <= token_data.status())
693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    token_cache_.erase(it);
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  token_cache_.insert(std::make_pair(key, token_data));
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::EraseCachedToken(const std::string& extension_id,
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   const std::string& token) {
70090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CachedTokens::iterator it;
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (it = token_cache_.begin(); it != token_cache_.end(); ++it) {
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (it->first.extension_id == extension_id &&
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        it->second.status() == IdentityTokenCacheValue::CACHE_STATUS_TOKEN &&
704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        it->second.token() == token) {
705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      token_cache_.erase(it);
706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::EraseAllCachedTokens() {
712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  token_cache_.clear();
713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const IdentityTokenCacheValue& IdentityAPI::GetCachedToken(
716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& extension_id, const std::vector<std::string> scopes) {
717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopeset(scopes.begin(), scopes.end());
718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TokenCacheKey key(extension_id, scopeset);
719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return token_cache_[key];
720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
72290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const IdentityAPI::CachedTokens& IdentityAPI::GetAllCachedTokens() {
72390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return token_cache_;
72490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
72590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::ReportAuthError(const GoogleServiceAuthError& error) {
7278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ProfileOAuth2TokenService* token_service =
7288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
7298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  account_tracker_.ReportAuthError(token_service->GetPrimaryAccountId(), error);
730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityAPI::Shutdown() {
7338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  account_tracker_.RemoveObserver(this);
7348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  account_tracker_.Shutdown();
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static base::LazyInstance<ProfileKeyedAPIFactory<IdentityAPI> >
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_factory = LAZY_INSTANCE_INITIALIZER;
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProfileKeyedAPIFactory<IdentityAPI>* IdentityAPI::GetFactoryInstance() {
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return &g_factory.Get();
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void IdentityAPI::OnAccountAdded(const AccountIds& ids) {}
7464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void IdentityAPI::OnAccountRemoved(const AccountIds& ids) {}
748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void IdentityAPI::OnAccountSignInChanged(const AccountIds& ids,
7508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                         bool is_signed_in) {
7511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  api::identity::AccountInfo account_info;
7521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  account_info.id = ids.gaia;
7531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<base::ListValue> args =
7551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      api::identity::OnSignInChanged::Create(account_info, is_signed_in);
7561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<Event> event(new Event(
7571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      api::identity::OnSignInChanged::kEventName, args.Pass(), profile_));
7581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ExtensionSystem::Get(profile_)->event_router()->BroadcastEvent(event.Pass());
760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <>
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ProfileKeyedAPIFactory<IdentityAPI>::DeclareFactoryDependencies() {
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DependsOn(ExtensionSystemFactory::GetInstance());
7657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityAPI::TokenCacheKey::TokenCacheKey(const std::string& extension_id,
769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                          const std::set<std::string> scopes)
770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : extension_id(extension_id),
771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scopes(scopes) {
772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityAPI::TokenCacheKey::~TokenCacheKey() {
775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IdentityAPI::TokenCacheKey::operator<(
778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const IdentityAPI::TokenCacheKey& rhs) const {
779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (extension_id < rhs.extension_id)
780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else if (rhs.extension_id < extension_id)
782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return scopes < rhs.scopes;
785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
788