device_management_service_browsertest.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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/cloud_policy_constants.h"
12#include "chrome/browser/policy/cloud/device_management_service.h"
13#include "chrome/browser/policy/cloud/mock_device_management_service.h"
14#include "chrome/browser/policy/cloud/test_request_interceptor.h"
15#include "chrome/browser/policy/test/local_policy_test_server.h"
16#include "chrome/test/base/in_process_browser_test.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("localhost"));
102    return "http://localhost";
103  }
104
105  std::string InitTestServer() {
106    StartTestServer();
107    return test_server_->GetServiceURL().spec();
108  }
109
110  void RecordAuthCode(DeviceManagementStatus status,
111                      int net_error,
112                      const em::DeviceManagementResponse& response) {
113    robot_auth_code_ = response.service_api_access_response().auth_code();
114  }
115
116 protected:
117  void ExpectRequest() {
118    if (interceptor_)
119      interceptor_->PushJobCallback(base::Bind(&ResponseJob));
120  }
121
122  void PerformRegistration() {
123    ExpectRequest();
124    EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, _))
125        .WillOnce(
126            DoAll(Invoke(this,
127                         &DeviceManagementServiceIntegrationTest::RecordToken),
128                  InvokeWithoutArgs(base::MessageLoop::current(),
129                                    &base::MessageLoop::Quit)));
130    scoped_ptr<DeviceManagementRequestJob> job(
131        service_->CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION));
132    job->SetGaiaToken("gaia_auth_token");
133    job->SetOAuthToken("oauth_token");
134    job->SetClientID("testid");
135    job->GetRequest()->mutable_register_request();
136    job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
137                          base::Unretained(this)));
138    base::MessageLoop::current()->Run();
139  }
140
141  virtual void SetUpOnMainThread() OVERRIDE {
142    std::string service_url((this->*(GetParam()))());
143    service_.reset(new DeviceManagementService(
144        scoped_ptr<DeviceManagementService::Configuration>(
145            new MockDeviceManagementServiceConfiguration(service_url)),
146        g_browser_process->system_request_context()));
147    service_->ScheduleInitialization(0);
148  }
149
150  virtual void CleanUpOnMainThread() OVERRIDE {
151    service_.reset();
152    test_server_.reset();
153    interceptor_.reset();
154  }
155
156  void StartTestServer() {
157    test_server_.reset(
158        new LocalPolicyTestServer("device_management_service_browsertest"));
159    ASSERT_TRUE(test_server_->Start());
160  }
161
162  void RecordToken(DeviceManagementStatus status,
163                   int net_error,
164                   const em::DeviceManagementResponse& response) {
165    token_ = response.register_response().device_management_token();
166  }
167
168  std::string token_;
169  std::string robot_auth_code_;
170  scoped_ptr<DeviceManagementService> service_;
171  scoped_ptr<LocalPolicyTestServer> test_server_;
172  scoped_ptr<TestRequestInterceptor> interceptor_;
173};
174
175IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest, Registration) {
176  PerformRegistration();
177  EXPECT_FALSE(token_.empty());
178}
179
180IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest,
181                       ApiAuthCodeFetch) {
182  PerformRegistration();
183
184  ExpectRequest();
185  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, _))
186      .WillOnce(
187          DoAll(Invoke(this,
188                       &DeviceManagementServiceIntegrationTest::RecordAuthCode),
189                InvokeWithoutArgs(base::MessageLoop::current(),
190                                  &base::MessageLoop::Quit)));
191  scoped_ptr<DeviceManagementRequestJob> job(service_->CreateJob(
192      DeviceManagementRequestJob::TYPE_API_AUTH_CODE_FETCH));
193  job->SetDMToken(token_);
194  job->SetClientID("testid");
195  em::DeviceServiceApiAccessRequest* request =
196      job->GetRequest()->mutable_service_api_access_request();
197  request->add_auth_scope("authScope4Test");
198  request->set_oauth2_client_id("oauth2ClientId4Test");
199  job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
200                        base::Unretained(this)));
201  base::MessageLoop::current()->Run();
202  ASSERT_EQ("fake_auth_code", robot_auth_code_);
203}
204
205IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest, PolicyFetch) {
206  PerformRegistration();
207
208  ExpectRequest();
209  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, _))
210      .WillOnce(InvokeWithoutArgs(base::MessageLoop::current(),
211                                  &base::MessageLoop::Quit));
212  scoped_ptr<DeviceManagementRequestJob> job(
213      service_->CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH));
214  job->SetDMToken(token_);
215  job->SetUserAffiliation(USER_AFFILIATION_NONE);
216  job->SetClientID("testid");
217  em::DevicePolicyRequest* request =
218      job->GetRequest()->mutable_policy_request();
219  request->add_request()->set_policy_type(dm_protocol::kChromeUserPolicyType);
220  job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
221                        base::Unretained(this)));
222  base::MessageLoop::current()->Run();
223}
224
225IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest, Unregistration) {
226  PerformRegistration();
227
228  ExpectRequest();
229  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, _))
230      .WillOnce(InvokeWithoutArgs(base::MessageLoop::current(),
231                                  &base::MessageLoop::Quit));
232  scoped_ptr<DeviceManagementRequestJob> job(
233      service_->CreateJob(DeviceManagementRequestJob::TYPE_UNREGISTRATION));
234  job->SetDMToken(token_);
235  job->SetClientID("testid");
236  job->GetRequest()->mutable_unregister_request();
237  job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
238                        base::Unretained(this)));
239  base::MessageLoop::current()->Run();
240}
241
242IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest, AutoEnrollment) {
243  ExpectRequest();
244  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, _))
245      .WillOnce(InvokeWithoutArgs(base::MessageLoop::current(),
246                                  &base::MessageLoop::Quit));
247  scoped_ptr<DeviceManagementRequestJob> job(
248      service_->CreateJob(DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT));
249  job->SetClientID("testid");
250  job->GetRequest()->mutable_auto_enrollment_request()->set_remainder(0);
251  job->GetRequest()->mutable_auto_enrollment_request()->set_modulus(1);
252  job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
253                        base::Unretained(this)));
254  base::MessageLoop::current()->Run();
255}
256
257INSTANTIATE_TEST_CASE_P(
258    DeviceManagementServiceIntegrationTestInstance,
259    DeviceManagementServiceIntegrationTest,
260    testing::Values(&DeviceManagementServiceIntegrationTest::InitCannedResponse,
261                    &DeviceManagementServiceIntegrationTest::InitTestServer));
262
263}  // namespace policy
264