Home | History | Annotate | Download | only in cloud
      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 
     27 using content::BrowserThread;
     28 using testing::DoAll;
     29 using testing::Invoke;
     30 using testing::InvokeWithoutArgs;
     31 using testing::_;
     32 
     33 namespace em = enterprise_management;
     34 
     35 namespace policy {
     36 
     37 namespace {
     38 
     39 // Parses the DeviceManagementRequest in |request_data| and writes a serialized
     40 // DeviceManagementResponse to |response_data|.
     41 void 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.
     66 net::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 
     92 class 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 
    177 IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest, Registration) {
    178   PerformRegistration();
    179   EXPECT_FALSE(token_.empty());
    180 }
    181 
    182 IN_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 
    208 IN_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 
    229 IN_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 
    247 IN_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 
    263 INSTANTIATE_TEST_CASE_P(
    264     DeviceManagementServiceIntegrationTestInstance,
    265     DeviceManagementServiceIntegrationTest,
    266     testing::Values(&DeviceManagementServiceIntegrationTest::InitCannedResponse,
    267                     &DeviceManagementServiceIntegrationTest::InitTestServer));
    268 
    269 }  // namespace policy
    270