1 // Copyright 2014 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/signin/easy_unlock_toggle_flow.h"
9 #include "base/logging.h"
10 #include "base/strings/stringprintf.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
14 #include "chrome/browser/signin/signin_manager_factory.h"
15 #include "chrome/common/extensions/extension_constants.h"
16 #include "components/signin/core/browser/profile_oauth2_token_service.h"
17 #include "components/signin/core/browser/signin_manager.h"
18 #include "extensions/browser/extension_system.h"
19 #include "extensions/common/manifest_handlers/oauth2_manifest_handler.h"
20 #include "google_apis/gaia/oauth2_api_call_flow.h"
21 #include "net/url_request/url_fetcher.h"
25 const char kEasyUnlockToggleUrl
[] =
26 "https://www.googleapis.com/cryptauth/v1/deviceSync/toggleeasyunlock";
28 std::vector
<std::string
> GetScopes() {
29 std::vector
<std::string
> scopes
;
30 scopes
.push_back("https://www.googleapis.com/auth/proximity_auth");
31 scopes
.push_back("https://www.googleapis.com/auth/cryptauth");
35 std::string
GetEasyUnlockAppClientId(Profile
* profile
) {
36 extensions::ExtensionSystem
* extension_system
=
37 extensions::ExtensionSystem::Get(profile
);
38 ExtensionService
* extension_service
= extension_system
->extension_service();
39 const extensions::Extension
* easy_unlock_app
=
40 extension_service
->GetInstalledExtension(
41 extension_misc::kEasyUnlockAppId
);
45 const extensions::OAuth2Info
& oauth2_info
=
46 extensions::OAuth2Info::GetOAuth2Info(easy_unlock_app
);
47 return oauth2_info
.client_id
;
52 class EasyUnlockToggleFlow::ToggleApiCall
: public OAuth2ApiCallFlow
{
54 ToggleApiCall(EasyUnlockToggleFlow
* flow
,
55 const std::string
& phone_public_key
,
57 ~ToggleApiCall() override
;
60 GURL
CreateApiCallUrl() override
;
61 std::string
CreateApiCallBody() override
;
62 std::string
CreateApiCallBodyContentType() override
;
63 void ProcessApiCallSuccess(const net::URLFetcher
* source
) override
;
64 void ProcessApiCallFailure(const net::URLFetcher
* source
) override
;
67 EasyUnlockToggleFlow
* flow_
;
68 const std::string phone_public_key_
;
69 const bool toggle_enable_
;
71 DISALLOW_COPY_AND_ASSIGN(ToggleApiCall
);
74 EasyUnlockToggleFlow::ToggleApiCall::ToggleApiCall(
75 EasyUnlockToggleFlow
* flow
,
76 const std::string
& phone_public_key
,
79 phone_public_key_(phone_public_key
),
80 toggle_enable_(toggle_enable
) {
83 EasyUnlockToggleFlow::ToggleApiCall::~ToggleApiCall() {
86 GURL
EasyUnlockToggleFlow::ToggleApiCall::CreateApiCallUrl() {
87 return GURL(kEasyUnlockToggleUrl
);
90 std::string
EasyUnlockToggleFlow::ToggleApiCall::CreateApiCallBody() {
91 const char kBodyFormat
[] = "{\"enable\":%s,\"publicKey\":\"%s\"}";
92 return base::StringPrintf(
94 toggle_enable_
? "true" : "false",
95 phone_public_key_
.c_str());
99 EasyUnlockToggleFlow::ToggleApiCall::CreateApiCallBodyContentType() {
100 return "application/json";
103 void EasyUnlockToggleFlow::ToggleApiCall::ProcessApiCallSuccess(
104 const net::URLFetcher
* source
) {
105 flow_
->ReportToggleApiCallResult(true);
108 void EasyUnlockToggleFlow::ToggleApiCall::ProcessApiCallFailure(
109 const net::URLFetcher
* source
) {
110 flow_
->ReportToggleApiCallResult(false);
113 EasyUnlockToggleFlow::EasyUnlockToggleFlow(Profile
* profile
,
114 const std::string
& phone_public_key
,
116 const ToggleFlowCallback
& callback
)
117 : OAuth2TokenService::Consumer("easy_unlock_toggle"),
119 phone_public_key_(phone_public_key
),
120 toggle_enable_(toggle_enable
),
121 callback_(callback
) {
124 EasyUnlockToggleFlow::~EasyUnlockToggleFlow() {
127 void EasyUnlockToggleFlow::Start() {
128 ProfileOAuth2TokenService
* token_service
=
129 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
);
130 SigninManagerBase
* signin_manager
=
131 SigninManagerFactory::GetForProfile(profile_
);
133 token_service
->StartRequest(signin_manager
->GetAuthenticatedAccountId(),
134 OAuth2TokenService::ScopeSet(),
138 void EasyUnlockToggleFlow::OnGetTokenSuccess(
139 const OAuth2TokenService::Request
* request
,
140 const std::string
& access_token
,
141 const base::Time
& expiration_time
) {
142 DCHECK_EQ(token_request_
.get(), request
);
143 token_request_
.reset();
145 mint_token_flow_
.reset(
146 new OAuth2MintTokenFlow(this,
147 OAuth2MintTokenFlow::Parameters(
148 extension_misc::kEasyUnlockAppId
,
149 GetEasyUnlockAppClientId(profile_
),
151 OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE
)));
152 mint_token_flow_
->Start(profile_
->GetRequestContext(), access_token
);
155 void EasyUnlockToggleFlow::OnGetTokenFailure(
156 const OAuth2TokenService::Request
* request
,
157 const GoogleServiceAuthError
& error
) {
158 DCHECK_EQ(token_request_
.get(), request
);
159 token_request_
.reset();
161 LOG(ERROR
) << "Easy unlock toggle flow, failed to get access token,"
162 << "error=" << error
.state();
163 callback_
.Run(false);
166 void EasyUnlockToggleFlow::OnMintTokenSuccess(const std::string
& access_token
,
168 toggle_api_call_
.reset(new ToggleApiCall(this,
171 toggle_api_call_
->Start(profile_
->GetRequestContext(), access_token
);
174 void EasyUnlockToggleFlow::OnMintTokenFailure(
175 const GoogleServiceAuthError
& error
) {
176 LOG(ERROR
) << "Easy unlock toggle flow, failed to mint access token,"
177 << "error=" << error
.state();
178 callback_
.Run(false);
181 void EasyUnlockToggleFlow::OnIssueAdviceSuccess(
182 const IssueAdviceInfo
& issue_advice
) {
186 void EasyUnlockToggleFlow::ReportToggleApiCallResult(bool success
) {
187 callback_
.Run(success
);