Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / login / signin / token_handle_util.cc
blob4e688a747cf7e6da7bfd3aa19760e65547f027ef
1 // Copyright 2015 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.
5 #include "chrome/browser/chromeos/login/signin/token_handle_util.h"
7 #include "base/memory/weak_ptr.h"
8 #include "base/metrics/histogram_macros.h"
9 #include "base/values.h"
10 #include "chrome/browser/chromeos/profiles/profile_helper.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "components/user_manager/user_id.h"
13 #include "components/user_manager/user_manager.h"
14 #include "google_apis/gaia/gaia_oauth_client.h"
16 namespace {
18 const char kTokenHandlePref[] = "PasswordTokenHandle";
19 const char kTokenHandleStatusPref[] = "TokenHandleStatus";
21 const char kHandleStatusValid[] = "valid";
22 const char kHandleStatusInvalid[] = "invalid";
23 const char* kDefaultHandleStatus = kHandleStatusValid;
25 static const int kMaxRetries = 3;
27 } // namespace
29 TokenHandleUtil::TokenHandleUtil(user_manager::UserManager* user_manager)
30 : user_manager_(user_manager), weak_factory_(this) {
33 TokenHandleUtil::~TokenHandleUtil() {
34 weak_factory_.InvalidateWeakPtrs();
35 gaia_client_.reset();
38 bool TokenHandleUtil::HasToken(const user_manager::UserID& user_id) {
39 const base::DictionaryValue* dict = nullptr;
40 std::string token;
41 if (!user_manager_->FindKnownUserPrefs(user_id, &dict))
42 return false;
43 if (!dict->GetString(kTokenHandlePref, &token))
44 return false;
45 return !token.empty();
48 bool TokenHandleUtil::ShouldObtainHandle(const user_manager::UserID& user_id) {
49 const base::DictionaryValue* dict = nullptr;
50 std::string token;
51 if (!user_manager_->FindKnownUserPrefs(user_id, &dict))
52 return true;
53 if (!dict->GetString(kTokenHandlePref, &token))
54 return true;
55 if (token.empty())
56 return true;
57 std::string status(kDefaultHandleStatus);
58 dict->GetString(kTokenHandleStatusPref, &status);
59 return kHandleStatusInvalid == status;
62 void TokenHandleUtil::DeleteHandle(const user_manager::UserID& user_id) {
63 const base::DictionaryValue* dict = nullptr;
64 if (!user_manager_->FindKnownUserPrefs(user_id, &dict))
65 return;
66 scoped_ptr<base::DictionaryValue> dict_copy(dict->DeepCopy());
67 dict_copy->Remove(kTokenHandlePref, nullptr);
68 dict_copy->Remove(kTokenHandleStatusPref, nullptr);
69 user_manager_->UpdateKnownUserPrefs(user_id, *dict_copy.get(),
70 /* replace values */ true);
73 void TokenHandleUtil::MarkHandleInvalid(const user_manager::UserID& user_id) {
74 user_manager_->SetKnownUserStringPref(user_id, kTokenHandleStatusPref,
75 kHandleStatusInvalid);
78 void TokenHandleUtil::CheckToken(const user_manager::UserID& user_id,
79 const TokenValidationCallback& callback) {
80 const base::DictionaryValue* dict = nullptr;
81 std::string token;
82 if (!user_manager_->FindKnownUserPrefs(user_id, &dict)) {
83 callback.Run(user_id, UNKNOWN);
84 return;
86 if (!dict->GetString(kTokenHandlePref, &token)) {
87 callback.Run(user_id, UNKNOWN);
88 return;
91 if (!gaia_client_.get()) {
92 auto request_context =
93 chromeos::ProfileHelper::Get()->GetSigninProfile()->GetRequestContext();
94 gaia_client_.reset(new gaia::GaiaOAuthClient(request_context));
97 validation_delegates_.set(
98 token, scoped_ptr<TokenDelegate>(new TokenDelegate(
99 weak_factory_.GetWeakPtr(), user_id, token, callback)));
100 gaia_client_->GetTokenHandleInfo(token, kMaxRetries,
101 validation_delegates_.get(token));
104 void TokenHandleUtil::StoreTokenHandle(const user_manager::UserID& user_id,
105 const std::string& handle) {
106 user_manager_->SetKnownUserStringPref(user_id, kTokenHandlePref, handle);
107 user_manager_->SetKnownUserStringPref(user_id, kTokenHandleStatusPref,
108 kHandleStatusValid);
111 void TokenHandleUtil::OnValidationComplete(const std::string& token) {
112 validation_delegates_.erase(token);
115 void TokenHandleUtil::OnObtainTokenComplete(
116 const user_manager::UserID& user_id) {
117 obtain_delegates_.erase(user_id);
120 TokenHandleUtil::TokenDelegate::TokenDelegate(
121 const base::WeakPtr<TokenHandleUtil>& owner,
122 const user_manager::UserID& user_id,
123 const std::string& token,
124 const TokenValidationCallback& callback)
125 : owner_(owner),
126 user_id_(user_id),
127 token_(token),
128 tokeninfo_response_start_time_(base::TimeTicks::Now()),
129 callback_(callback) {
132 TokenHandleUtil::TokenDelegate::~TokenDelegate() {
135 void TokenHandleUtil::TokenDelegate::OnOAuthError() {
136 callback_.Run(user_id_, INVALID);
137 NotifyDone();
140 // Warning: NotifyDone() deletes |this|
141 void TokenHandleUtil::TokenDelegate::NotifyDone() {
142 if (owner_)
143 owner_->OnValidationComplete(token_);
146 void TokenHandleUtil::TokenDelegate::OnNetworkError(int response_code) {
147 callback_.Run(user_id_, UNKNOWN);
148 NotifyDone();
151 void TokenHandleUtil::TokenDelegate::OnGetTokenInfoResponse(
152 scoped_ptr<base::DictionaryValue> token_info) {
153 TokenHandleStatus outcome = UNKNOWN;
154 if (!token_info->HasKey("error")) {
155 int expires_in = 0;
156 if (token_info->GetInteger("expires_in", &expires_in))
157 outcome = (expires_in < 0) ? INVALID : VALID;
160 const base::TimeDelta duration =
161 base::TimeTicks::Now() - tokeninfo_response_start_time_;
162 UMA_HISTOGRAM_TIMES("Login.TokenCheckResponseTime", duration);
163 callback_.Run(user_id_, outcome);
164 NotifyDone();