Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / signin / easy_unlock_toggle_flow.cc
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.
4
5 #include "chrome/browser/signin/easy_unlock_toggle_flow.h"
6
7 #include <vector>
8
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/chrome_signin_client_factory.h"
14 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
15 #include "chrome/browser/signin/signin_manager_factory.h"
16 #include "chrome/common/extensions/extension_constants.h"
17 #include "components/signin/core/browser/profile_oauth2_token_service.h"
18 #include "components/signin/core/browser/signin_manager.h"
19 #include "extensions/browser/extension_system.h"
20 #include "extensions/common/manifest_handlers/oauth2_manifest_handler.h"
21 #include "google_apis/gaia/oauth2_api_call_flow.h"
22 #include "net/url_request/url_fetcher.h"
23
24 namespace {
25
26 const char kEasyUnlockToggleUrl[] =
27     "https://www.googleapis.com/cryptauth/v1/deviceSync/toggleeasyunlock";
28
29 std::vector<std::string> GetScopes() {
30   std::vector<std::string> scopes;
31   scopes.push_back("https://www.googleapis.com/auth/proximity_auth");
32   scopes.push_back("https://www.googleapis.com/auth/cryptauth");
33   return scopes;
34 }
35
36 std::string GetEasyUnlockAppClientId(Profile * profile) {
37   extensions::ExtensionSystem* extension_system =
38       extensions::ExtensionSystem::Get(profile);
39   ExtensionService* extension_service = extension_system->extension_service();
40   const extensions::Extension* easy_unlock_app =
41       extension_service->GetInstalledExtension(
42           extension_misc::kEasyUnlockAppId);
43   if (!easy_unlock_app)
44     return std::string();
45
46   const extensions::OAuth2Info& oauth2_info =
47       extensions::OAuth2Info::GetOAuth2Info(easy_unlock_app);
48   return oauth2_info.client_id;
49 }
50
51 }  // namespace
52
53 class EasyUnlockToggleFlow::ToggleApiCall : public OAuth2ApiCallFlow {
54  public:
55   ToggleApiCall(EasyUnlockToggleFlow* flow,
56                 const std::string& phone_public_key,
57                 bool toggle_enable);
58   ~ToggleApiCall() override;
59
60   // OAuth2ApiCallFlow
61   GURL CreateApiCallUrl() override;
62   std::string CreateApiCallBody() override;
63   std::string CreateApiCallBodyContentType() override;
64   void ProcessApiCallSuccess(const net::URLFetcher* source) override;
65   void ProcessApiCallFailure(const net::URLFetcher* source) override;
66
67  private:
68   EasyUnlockToggleFlow* flow_;
69   const std::string phone_public_key_;
70   const bool toggle_enable_;
71
72   DISALLOW_COPY_AND_ASSIGN(ToggleApiCall);
73 };
74
75 EasyUnlockToggleFlow::ToggleApiCall::ToggleApiCall(
76     EasyUnlockToggleFlow* flow,
77     const std::string& phone_public_key,
78     bool toggle_enable)
79     : flow_(flow),
80       phone_public_key_(phone_public_key),
81       toggle_enable_(toggle_enable) {
82 }
83
84 EasyUnlockToggleFlow::ToggleApiCall::~ToggleApiCall() {
85 }
86
87 GURL EasyUnlockToggleFlow::ToggleApiCall::CreateApiCallUrl() {
88   return GURL(kEasyUnlockToggleUrl);
89 }
90
91 std::string EasyUnlockToggleFlow::ToggleApiCall::CreateApiCallBody() {
92   const char kEnableBodyFormat[] = "{\"enable\": true,\"publicKey\":\"%s\"}";
93   const char kDisableBodyFormat[] =
94       "{ \"enable\": false, \"applyToAll\": true }";
95
96   if (toggle_enable_)
97     return base::StringPrintf(kEnableBodyFormat, phone_public_key_.c_str());
98   else
99     return std::string(kDisableBodyFormat);
100 }
101
102 std::string
103 EasyUnlockToggleFlow::ToggleApiCall::CreateApiCallBodyContentType() {
104   return "application/json";
105 }
106
107 void EasyUnlockToggleFlow::ToggleApiCall::ProcessApiCallSuccess(
108     const net::URLFetcher* source) {
109   flow_->ReportToggleApiCallResult(true);
110 }
111
112 void EasyUnlockToggleFlow::ToggleApiCall::ProcessApiCallFailure(
113     const net::URLFetcher* source) {
114   flow_->ReportToggleApiCallResult(false);
115 }
116
117 EasyUnlockToggleFlow::EasyUnlockToggleFlow(Profile* profile,
118                                            const std::string& phone_public_key,
119                                            bool toggle_enable,
120                                            const ToggleFlowCallback& callback)
121     : OAuth2TokenService::Consumer("easy_unlock_toggle"),
122       profile_(profile),
123       phone_public_key_(phone_public_key),
124       toggle_enable_(toggle_enable),
125       callback_(callback) {
126 }
127
128 EasyUnlockToggleFlow::~EasyUnlockToggleFlow() {
129 }
130
131 void EasyUnlockToggleFlow::Start() {
132   ProfileOAuth2TokenService* token_service =
133       ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
134   SigninManagerBase* signin_manager =
135       SigninManagerFactory::GetForProfile(profile_);
136   token_request_ =
137       token_service->StartRequest(signin_manager->GetAuthenticatedAccountId(),
138                                   OAuth2TokenService::ScopeSet(),
139                                   this);
140 }
141
142 void EasyUnlockToggleFlow::OnGetTokenSuccess(
143     const OAuth2TokenService::Request* request,
144     const std::string& access_token,
145     const base::Time& expiration_time) {
146   DCHECK_EQ(token_request_.get(), request);
147   token_request_.reset();
148
149   SigninClient* signin_client =
150       ChromeSigninClientFactory::GetForProfile(profile_);
151   std::string signin_scoped_device_id =
152       signin_client->GetSigninScopedDeviceId();
153
154   mint_token_flow_.reset(new OAuth2MintTokenFlow(
155       this,
156       OAuth2MintTokenFlow::Parameters(
157           extension_misc::kEasyUnlockAppId, GetEasyUnlockAppClientId(profile_),
158           GetScopes(), signin_scoped_device_id,
159           OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE)));
160   mint_token_flow_->Start(profile_->GetRequestContext(), access_token);
161 }
162
163 void EasyUnlockToggleFlow::OnGetTokenFailure(
164     const OAuth2TokenService::Request* request,
165     const GoogleServiceAuthError& error) {
166   DCHECK_EQ(token_request_.get(), request);
167   token_request_.reset();
168
169   LOG(ERROR) << "Easy unlock toggle flow, failed to get access token,"
170              << "error=" << error.state();
171   callback_.Run(false);
172 }
173
174 void EasyUnlockToggleFlow::OnMintTokenSuccess(const std::string& access_token,
175                                               int time_to_live) {
176   toggle_api_call_.reset(new ToggleApiCall(this,
177                                            phone_public_key_,
178                                            toggle_enable_));
179   toggle_api_call_->Start(profile_->GetRequestContext(), access_token);
180 }
181
182 void EasyUnlockToggleFlow::OnMintTokenFailure(
183     const GoogleServiceAuthError& error) {
184   LOG(ERROR) << "Easy unlock toggle flow, failed to mint access token,"
185              << "error=" << error.state();
186   callback_.Run(false);
187 }
188
189 void EasyUnlockToggleFlow::OnIssueAdviceSuccess(
190     const IssueAdviceInfo& issue_advice) {
191   NOTREACHED();
192 }
193
194 void EasyUnlockToggleFlow::ReportToggleApiCallResult(bool success) {
195   callback_.Run(success);
196 }