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