1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/webui/chromeos/login/inline_login_handler_chromeos.h"
6
7#include "chrome/browser/chromeos/login/signin/oauth2_token_fetcher.h"
8#include "chrome/browser/profiles/profile.h"
9#include "chrome/browser/signin/chrome_signin_client_factory.h"
10#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
11#include "chrome/browser/signin/signin_manager_factory.h"
12#include "chrome/browser/signin/signin_promo.h"
13#include "chrome/common/url_constants.h"
14#include "components/signin/core/browser/profile_oauth2_token_service.h"
15#include "components/signin/core/browser/signin_client.h"
16#include "components/signin/core/browser/signin_manager.h"
17#include "content/public/browser/storage_partition.h"
18#include "content/public/browser/web_contents.h"
19#include "content/public/browser/web_ui.h"
20#include "google_apis/gaia/gaia_urls.h"
21#include "net/base/url_util.h"
22
23namespace chromeos {
24
25class InlineLoginHandlerChromeOS::InlineLoginUIOAuth2Delegate
26    : public OAuth2TokenFetcher::Delegate {
27 public:
28  explicit InlineLoginUIOAuth2Delegate(content::WebUI* web_ui,
29                                       const std::string& account_id)
30      : web_ui_(web_ui), account_id_(account_id) {}
31
32  virtual ~InlineLoginUIOAuth2Delegate() {}
33
34  // OAuth2TokenFetcher::Delegate overrides:
35  virtual void OnOAuth2TokensAvailable(
36      const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) OVERRIDE {
37    // Closes sign-in dialog before update token service. Token service update
38    // might trigger a permission dialog and if this dialog does not close,
39    // a DCHECK would be triggered because attempting to activate a window
40    // while there is a modal dialog.
41    web_ui_->CallJavascriptFunction("inline.login.closeDialog");
42
43    Profile* profile = Profile::FromWebUI(web_ui_);
44    ProfileOAuth2TokenService* token_service =
45        ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
46    token_service->UpdateCredentials(account_id_, oauth2_tokens.refresh_token);
47  }
48
49  virtual void OnOAuth2TokensFetchFailed() OVERRIDE {
50    LOG(ERROR) << "Failed to fetch oauth2 token with inline login.";
51    web_ui_->CallJavascriptFunction("inline.login.handleOAuth2TokenFailure");
52  }
53
54 private:
55  content::WebUI* web_ui_;
56  std::string account_id_;
57
58  DISALLOW_COPY_AND_ASSIGN(InlineLoginUIOAuth2Delegate);
59};
60
61InlineLoginHandlerChromeOS::InlineLoginHandlerChromeOS() {}
62
63InlineLoginHandlerChromeOS::~InlineLoginHandlerChromeOS() {}
64
65void InlineLoginHandlerChromeOS::CompleteLogin(const base::ListValue* args) {
66  Profile* profile = Profile::FromWebUI(web_ui());
67
68  const base::DictionaryValue* dict = NULL;
69  args->GetDictionary(0, &dict);
70
71  std::string session_index;
72  dict->GetString("sessionIndex", &session_index);
73  CHECK(!session_index.empty()) << "Session index is empty.";
74
75  std::string account_id;
76  dict->GetString("email", &account_id);
77  CHECK(!account_id.empty()) << "Account ID is empty.";
78
79  oauth2_delegate_.reset(new InlineLoginUIOAuth2Delegate(web_ui(), account_id));
80  net::URLRequestContextGetter* request_context =
81      content::BrowserContext::GetStoragePartitionForSite(
82          profile, GURL(chrome::kChromeUIChromeSigninURL))
83          ->GetURLRequestContext();
84  oauth2_token_fetcher_.reset(
85      new OAuth2TokenFetcher(oauth2_delegate_.get(), request_context));
86  SigninClient* signin_client =
87      ChromeSigninClientFactory::GetForProfile(profile);
88  std::string signin_scoped_device_id =
89      signin_client->GetSigninScopedDeviceId();
90  oauth2_token_fetcher_->StartExchangeFromCookies(session_index,
91                                                  signin_scoped_device_id);
92}
93
94} // namespace chromeos
95