device_management_service_browsertest.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1// Copyright (c) 2012 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 "base/bind.h"
6#include "base/bind_helpers.h"
7#include "base/memory/scoped_ptr.h"
8#include "base/message_loop/message_loop.h"
9#include "base/stl_util.h"
10#include "chrome/browser/browser_process.h"
11#include "chrome/browser/policy/cloud/test_request_interceptor.h"
12#include "chrome/browser/policy/test/local_policy_test_server.h"
13#include "chrome/test/base/in_process_browser_test.h"
14#include "components/policy/core/common/cloud/cloud_policy_constants.h"
15#include "components/policy/core/common/cloud/device_management_service.h"
16#include "components/policy/core/common/cloud/mock_device_management_service.h"
17#include "content/public/browser/browser_thread.h"
18#include "net/base/upload_bytes_element_reader.h"
19#include "net/base/upload_data_stream.h"
20#include "net/url_request/url_fetcher.h"
21#include "net/url_request/url_request.h"
22#include "net/url_request/url_request_context_getter.h"
23#include "net/url_request/url_request_test_job.h"
24#include "testing/gmock/include/gmock/gmock.h"
25#include "testing/gtest/include/gtest/gtest.h"
26
27using content::BrowserThread;
28using testing::DoAll;
29using testing::Invoke;
30using testing::InvokeWithoutArgs;
31using testing::_;
32
33namespace em = enterprise_management;
34
35namespace policy {
36
37namespace {
38
39// Parses the DeviceManagementRequest in |request_data| and writes a serialized
40// DeviceManagementResponse to |response_data|.
41void ConstructResponse(const char* request_data,
42                       uint64 request_data_length,
43                       std::string* response_data) {
44  em::DeviceManagementRequest request;
45  ASSERT_TRUE(request.ParseFromArray(request_data, request_data_length));
46  em::DeviceManagementResponse response;
47  if (request.has_register_request()) {
48    response.mutable_register_response()->set_device_management_token(
49        "fake_token");
50  } else if (request.has_service_api_access_request()) {
51    response.mutable_service_api_access_response()->set_auth_code(
52        "fake_auth_code");
53  } else if (request.has_unregister_request()) {
54    response.mutable_unregister_response();
55  } else if (request.has_policy_request()) {
56    response.mutable_policy_response()->add_response();
57  } else if (request.has_auto_enrollment_request()) {
58    response.mutable_auto_enrollment_response();
59  } else {
60    FAIL() << "Failed to parse request.";
61  }
62  ASSERT_TRUE(response.SerializeToString(response_data));
63}
64
65// JobCallback for the interceptor.
66net::URLRequestJob* ResponseJob(
67    net::URLRequest* request,
68    net::NetworkDelegate* network_delegate) {
69  const net::UploadDataStream* upload = request->get_upload();
70  if (upload != NULL &&
71      upload->element_readers().size() == 1 &&
72      upload->element_readers()[0]->AsBytesReader()) {
73    std::string response_data;
74    const net::UploadBytesElementReader* bytes_reader =
75        upload->element_readers()[0]->AsBytesReader();
76    ConstructResponse(bytes_reader->bytes(),
77                      bytes_reader->length(),
78                      &response_data);
79    return new net::URLRequestTestJob(
80        request,
81        network_delegate,
82        net::URLRequestTestJob::test_headers(),
83        response_data,
84        true);
85  }
86
87  return NULL;
88}
89
90}  // namespace
91
92class DeviceManagementServiceIntegrationTest
93    : public InProcessBrowserTest,
94      public testing::WithParamInterface<
95          std::string (DeviceManagementServiceIntegrationTest::*)(void)> {
96 public:
97  MOCK_METHOD3(OnJobDone, void(DeviceManagementStatus, int,
98                               const em::DeviceManagementResponse&));
99
100  std::string InitCannedResponse() {
101    interceptor_.reset(new TestRequestInterceptor(
102        "localhost",
103        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
104    return "http://localhost";
105  }
106
107  std::string InitTestServer() {
108    StartTestServer();
109    return test_server_->GetServiceURL().spec();
110  }
111
112  void RecordAuthCode(DeviceManagementStatus status,
113                      int net_error,
114                      const em::DeviceManagementResponse& response) {
115    robot_auth_code_ = response.service_api_access_response().auth_code();
116  }
117
118 protected:
119  void ExpectRequest() {
120    if (interceptor_)
121      interceptor_->PushJobCallback(base::Bind(&ResponseJob));
122  }
123
124  void PerformRegistration() {
125    ExpectRequest();
126    EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, _))
127        .WillOnce(
128            DoAll(Invoke(this,
129                         &DeviceManagementServiceIntegrationTest::RecordToken),
130                  InvokeWithoutArgs(base::MessageLoop::current(),
131                                    &base::MessageLoop::Quit)));
132    scoped_ptr<DeviceManagementRequestJob> job(
133        service_->CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION,
134                            g_browser_process->system_request_context()));
135    job->SetGaiaToken("gaia_auth_token");
136    job->SetOAuthToken("oauth_token");
137    job->SetClientID("testid");
138    job->GetRequest()->mutable_register_request();
139    job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
140                          base::Unretained(this)));
141    base::MessageLoop::current()->Run();
142  }
143
144  virtual void SetUpOnMainThread() OVERRIDE {
145    std::string service_url((this->*(GetParam()))());
146    service_.reset(new DeviceManagementService(
147        scoped_ptr<DeviceManagementService::Configuration>(
148            new MockDeviceManagementServiceConfiguration(service_url))));
149    service_->ScheduleInitialization(0);
150  }
151
152  virtual void CleanUpOnMainThread() OVERRIDE {
153    service_.reset();
154    test_server_.reset();
155    interceptor_.reset();
156  }
157
158  void StartTestServer() {
159    test_server_.reset(
160        new LocalPolicyTestServer("device_management_service_browsertest"));
161    ASSERT_TRUE(test_server_->Start());
162  }
163
164  void RecordToken(DeviceManagementStatus status,
165                   int net_error,
166                   const em::DeviceManagementResponse& response) {
167    token_ = response.register_response().device_management_token();
168  }
169
170  std::string token_;
171  std::string robot_auth_code_;
172  scoped_ptr<DeviceManagementService> service_;
173  scoped_ptr<LocalPolicyTestServer> test_server_;
174  scoped_ptr<TestRequestInterceptor> interceptor_;
175};
176
177IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest, Registration) {
178  PerformRegistration();
179  EXPECT_FALSE(token_.empty());
180}
181
182IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest,
183                       ApiAuthCodeFetch) {
184  PerformRegistration();
185
186  ExpectRequest();
187  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, _))
188      .WillOnce(
189          DoAll(Invoke(this,
190                       &DeviceManagementServiceIntegrationTest::RecordAuthCode),
191                InvokeWithoutArgs(base::MessageLoop::current(),
192                                  &base::MessageLoop::Quit)));
193  scoped_ptr<DeviceManagementRequestJob> job(service_->CreateJob(
194      DeviceManagementRequestJob::TYPE_API_AUTH_CODE_FETCH,
195      g_browser_process->system_request_context()));
196  job->SetDMToken(token_);
197  job->SetClientID("testid");
198  em::DeviceServiceApiAccessRequest* request =
199      job->GetRequest()->mutable_service_api_access_request();
200  request->add_auth_scope("authScope4Test");
201  request->set_oauth2_client_id("oauth2ClientId4Test");
202  job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
203                        base::Unretained(this)));
204  base::MessageLoop::current()->Run();
205  ASSERT_EQ("fake_auth_code", robot_auth_code_);
206}
207
208IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest, PolicyFetch) {
209  PerformRegistration();
210
211  ExpectRequest();
212  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, _))
213      .WillOnce(InvokeWithoutArgs(base::MessageLoop::current(),
214                                  &base::MessageLoop::Quit));
215  scoped_ptr<DeviceManagementRequestJob> job(
216      service_->CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH,
217                          g_browser_process->system_request_context()));
218  job->SetDMToken(token_);
219  job->SetUserAffiliation(USER_AFFILIATION_NONE);
220  job->SetClientID("testid");
221  em::DevicePolicyRequest* request =
222      job->GetRequest()->mutable_policy_request();
223  request->add_request()->set_policy_type(dm_protocol::kChromeUserPolicyType);
224  job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
225                        base::Unretained(this)));
226  base::MessageLoop::current()->Run();
227}
228
229IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest, Unregistration) {
230  PerformRegistration();
231
232  ExpectRequest();
233  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, _))
234      .WillOnce(InvokeWithoutArgs(base::MessageLoop::current(),
235                                  &base::MessageLoop::Quit));
236  scoped_ptr<DeviceManagementRequestJob> job(
237      service_->CreateJob(DeviceManagementRequestJob::TYPE_UNREGISTRATION,
238                          g_browser_process->system_request_context()));
239  job->SetDMToken(token_);
240  job->SetClientID("testid");
241  job->GetRequest()->mutable_unregister_request();
242  job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
243                        base::Unretained(this)));
244  base::MessageLoop::current()->Run();
245}
246
247IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest, AutoEnrollment) {
248  ExpectRequest();
249  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, _))
250      .WillOnce(InvokeWithoutArgs(base::MessageLoop::current(),
251                                  &base::MessageLoop::Quit));
252  scoped_ptr<DeviceManagementRequestJob> job(
253      service_->CreateJob(DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT,
254                          g_browser_process->system_request_context()));
255  job->SetClientID("testid");
256  job->GetRequest()->mutable_auto_enrollment_request()->set_remainder(0);
257  job->GetRequest()->mutable_auto_enrollment_request()->set_modulus(1);
258  job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
259                        base::Unretained(this)));
260  base::MessageLoop::current()->Run();
261}
262
263INSTANTIATE_TEST_CASE_P(
264    DeviceManagementServiceIntegrationTestInstance,
265    DeviceManagementServiceIntegrationTest,
266    testing::Values(&DeviceManagementServiceIntegrationTest::InitCannedResponse,
267                    &DeviceManagementServiceIntegrationTest::InitTestServer));
268
269}  // namespace policy
270