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