Commit 22e0542a authored by Aga Wronska's avatar Aga Wronska Committed by Commit Bot

child user: Allow adding multiple authentication data to DeviceManagementRequestJob.

Allow one auth source that is passed in 'Authorization' header (it can
be: GAIA token, DM token or enrollment token) and one auth source that
is passed as query param (it can be OAuth2 token).
It will be further used to fetch child user policy with DMToken and
user OAuth2 token.

This is a part of larger change: passing credentials with child user policy
fetch.

Bug: 839025
Test: DeviceManagementRequestAuthTest/DeviceManagementServiceTest/DeviceManagementServiceIntegrationTest + manually
Change-Id: I84d77822452b6c1a320b30627cf7dfe54462f986
Reviewed-on: https://chromium-review.googlesource.com/c/1341063Reviewed-by: default avatarMaksim Ivanov <emaxx@chromium.org>
Reviewed-by: default avatarLutz Justen <ljusten@chromium.org>
Commit-Queue: Aga Wronska <agawronska@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612834}
parent 1f571012
......@@ -10,7 +10,6 @@
#include "base/guid.h"
#include "base/logging.h"
#include "components/policy/core/common/cloud/device_management_service.h"
#include "components/policy/core/common/cloud/dm_auth.h"
#include "components/policy/proto/device_management_backend.pb.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/google_service_auth_error.h"
......@@ -79,7 +78,7 @@ void AndroidManagementClient::CheckAndroidManagement(
request_job_.reset(device_management_service_->CreateJob(
DeviceManagementRequestJob::TYPE_ANDROID_MANAGEMENT_CHECK,
url_loader_factory_));
request_job_->SetAuthData(DMAuth::FromOAuthToken(access_token));
request_job_->SetOAuthTokenParameter(access_token);
request_job_->SetClientID(base::GenerateGUID());
request_job_->GetRequest()->mutable_check_android_management_request();
......
......@@ -47,6 +47,7 @@
#include "components/policy/core/common/cloud/cloud_policy_client.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/cloud/cloud_policy_core.h"
#include "components/policy/core/common/cloud/dm_auth.h"
#include "components/policy/core/common/cloud/mock_device_management_service.h"
#include "components/policy/core/common/cloud/mock_signing_service.h"
#include "components/policy/core/common/external_data_fetcher.h"
......
......@@ -218,7 +218,7 @@ void EnrollmentHandlerChromeOS::CheckAvailableLicenses(
CHECK_EQ(STEP_PENDING, enrollment_step_);
available_licenses_callback_ = license_callback;
client_->RequestAvailableLicenses(
dm_auth_->Clone(),
dm_auth_->oauth_token(),
base::Bind(&EnrollmentHandlerChromeOS::HandleAvailableLicensesResult,
weak_ptr_factory_.GetWeakPtr()));
}
......@@ -439,7 +439,7 @@ void EnrollmentHandlerChromeOS::StartRegistration() {
em::DeviceRegisterRequest::DEVICE,
EnrollmentModeToRegistrationFlavor(enrollment_config_.mode),
em::DeviceRegisterRequest::LIFETIME_INDEFINITE, license_type_,
dm_auth_->Clone(), client_id_, requisition_, current_state_key_);
dm_auth_->oauth_token(), client_id_, requisition_, current_state_key_);
}
}
......
......@@ -43,7 +43,6 @@
#include "components/policy/core/common/cloud/cloud_policy_core.h"
#include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
#include "components/policy/core/common/cloud/device_management_service.h"
#include "components/policy/core/common/cloud/dm_auth.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/policy/core/common/policy_types.h"
......@@ -627,9 +626,9 @@ void UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched(
client_id = client()->client_id();
client()->Register(em::DeviceRegisterRequest::USER,
em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
lifetime, em::LicenseType::UNDEFINED,
DMAuth::FromOAuthToken(policy_token), client_id,
std::string(), std::string());
lifetime, em::LicenseType::UNDEFINED, policy_token,
client_id, std::string() /* requisition */,
std::string() /* current_state_key */);
} else {
UMA_HISTOGRAM_ENUMERATION(kUMAInitialFetchOAuth2Error, error.state(),
GoogleServiceAuthError::NUM_STATES);
......
......@@ -24,7 +24,6 @@
#include "components/policy/core/common/cloud/cloud_policy_client.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/cloud/cloud_policy_core.h"
#include "components/policy/core/common/cloud/dm_auth.h"
#include "components/policy/core/common/policy_service.h"
#include "components/policy/core/common/policy_switches.h"
#include "components/policy/proto/device_management_backend.pb.h"
......@@ -107,8 +106,8 @@ void UserPolicyTestHelper::WaitForInitialPolicy(Profile* profile) {
enterprise_management::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
enterprise_management::DeviceRegisterRequest::LIFETIME_INDEFINITE,
enterprise_management::LicenseType::UNDEFINED,
DMAuth::FromOAuthToken("bogus"), std::string(), std::string(),
std::string());
"oauth_token_unused" /* oauth_token */, std::string() /* client_id */,
std::string() /* requisition */, std::string() /* current_state_key */);
policy::ProfilePolicyConnector* const profile_connector =
policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile);
......
......@@ -39,7 +39,6 @@
#include "components/policy/core/common/cloud/cloud_policy_client.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
#include "components/policy/core/common/cloud/dm_auth.h"
#include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
#include "components/policy/core/common/external_data_fetcher.h"
#include "components/policy/core/common/policy_map.h"
......@@ -266,8 +265,9 @@ class CloudPolicyTest : public InProcessBrowserTest,
policy_manager->core()->client()->Register(
registration_type, em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
em::LicenseType::UNDEFINED, DMAuth::FromOAuthToken("bogus"),
std::string(), std::string(), std::string());
em::LicenseType::UNDEFINED, "oauth_token_unused" /* oauth_token */,
std::string() /* client_id */, std::string() /* requisition */,
std::string() /* current_state_key */);
run_loop.Run();
Mock::VerifyAndClearExpectations(&observer);
policy_manager->core()->client()->RemoveObserver(&observer);
......
......@@ -16,7 +16,6 @@
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/common/cloud/cloud_policy_client.h"
#include "components/policy/core/common/cloud/device_management_service.h"
#include "components/policy/core/common/cloud/dm_auth.h"
#include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
#include "components/policy/core/common/policy_switches.h"
#include "components/policy/core/common/policy_test_utils.h"
......@@ -239,8 +238,9 @@ class CloudPolicyManagerTest : public InProcessBrowserTest {
policy_manager()->core()->client()->Register(
registration_type, em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
em::LicenseType::UNDEFINED, DMAuth::FromOAuthToken("bogus"),
std::string(), std::string(), std::string());
em::LicenseType::UNDEFINED, "oauth_token_unused" /* oauth_token */,
std::string() /* client_id */, std::string() /* requisition */,
std::string() /* current_state_key */);
run_loop.Run();
Mock::VerifyAndClearExpectations(&observer);
policy_manager()->core()->client()->RemoveObserver(&observer);
......
......@@ -17,6 +17,7 @@
#include "chrome/test/base/in_process_browser_test.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/cloud/device_management_service.h"
#include "components/policy/core/common/cloud/dm_auth.h"
#include "components/policy/core/common/cloud/mock_device_management_service.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/upload_bytes_element_reader.h"
......@@ -127,7 +128,7 @@ class DeviceManagementServiceIntegrationTest
InvokeWithoutArgs(&run_loop, &base::RunLoop::QuitWhenIdle)));
std::unique_ptr<DeviceManagementRequestJob> job(service_->CreateJob(
DeviceManagementRequestJob::TYPE_REGISTRATION, GetFactory()));
job->SetAuthData(DMAuth::FromOAuthToken("oauth_token"));
job->SetOAuthTokenParameter("oauth_token");
job->SetClientID("testid");
job->GetRequest()->mutable_register_request();
job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
......
......@@ -203,19 +203,19 @@ void CloudPolicyClient::Register(em::DeviceRegisterRequest::Type type,
em::DeviceRegisterRequest::Flavor flavor,
em::DeviceRegisterRequest::Lifetime lifetime,
em::LicenseType::LicenseTypeEnum license_type,
std::unique_ptr<DMAuth> auth,
const std::string& oauth_token,
const std::string& client_id,
const std::string& requisition,
const std::string& current_state_key) {
DCHECK(service_);
DCHECK(auth->has_oauth_token());
DCHECK(!oauth_token.empty());
DCHECK(!is_registered());
SetClientId(client_id);
policy_fetch_request_job_.reset(service_->CreateJob(
DeviceManagementRequestJob::TYPE_REGISTRATION, GetURLLoaderFactory()));
policy_fetch_request_job_->SetAuthData(std::move(auth));
policy_fetch_request_job_->SetOAuthTokenParameter(oauth_token);
policy_fetch_request_job_->SetClientID(client_id_);
em::DeviceRegisterRequest* request =
......@@ -662,7 +662,11 @@ void CloudPolicyClient::GetDeviceAttributeUpdatePermission(
DeviceManagementRequestJob::TYPE_ATTRIBUTE_UPDATE_PERMISSION,
GetURLLoaderFactory()));
request_job->SetAuthData(std::move(auth));
if (auth->has_oauth_token()) {
request_job->SetOAuthTokenParameter(auth->oauth_token());
} else {
request_job->SetAuthData(std::move(auth));
}
request_job->SetClientID(client_id_);
request_job->GetRequest()->
......@@ -688,7 +692,11 @@ void CloudPolicyClient::UpdateDeviceAttributes(
service_->CreateJob(DeviceManagementRequestJob::TYPE_ATTRIBUTE_UPDATE,
GetURLLoaderFactory()));
request_job->SetAuthData(std::move(auth));
if (auth->has_oauth_token()) {
request_job->SetOAuthTokenParameter(auth->oauth_token());
} else {
request_job->SetAuthData(std::move(auth));
}
request_job->SetClientID(client_id_);
em::DeviceAttributeUpdateRequest* request =
......@@ -706,15 +714,15 @@ void CloudPolicyClient::UpdateDeviceAttributes(
}
void CloudPolicyClient::RequestAvailableLicenses(
std::unique_ptr<DMAuth> auth,
const std::string& oauth_token,
const LicenseRequestCallback& callback) {
DCHECK(auth->has_oauth_token());
DCHECK(!oauth_token.empty());
std::unique_ptr<DeviceManagementRequestJob> request_job(service_->CreateJob(
DeviceManagementRequestJob::TYPE_REQUEST_LICENSE_TYPES,
GetURLLoaderFactory()));
request_job->SetAuthData(std::move(auth));
request_job->SetOAuthTokenParameter(oauth_token);
request_job->GetRequest()->mutable_check_device_license_request();
const DeviceManagementRequestJob::Callback job_callback =
......
......@@ -133,7 +133,7 @@ class POLICY_EXPORT CloudPolicyClient {
enterprise_management::DeviceRegisterRequest::Flavor flavor,
enterprise_management::DeviceRegisterRequest::Lifetime lifetime,
enterprise_management::LicenseType::LicenseTypeEnum license_type,
std::unique_ptr<DMAuth> auth,
const std::string& oauth_token,
const std::string& client_id,
const std::string& requisition,
const std::string& current_state_key);
......@@ -269,10 +269,10 @@ class POLICY_EXPORT CloudPolicyClient {
const std::string& location,
const StatusCallback& callback);
// Requests a list of licenses available for enrollment. Uses |auth| to
// Requests a list of licenses available for enrollment. Uses |oauth_token| to
// identify user who issues the request, the |callback| will
// be called when the operation completes.
void RequestAvailableLicenses(std::unique_ptr<DMAuth> auth,
void RequestAvailableLicenses(const std::string& oauth_token,
const LicenseRequestCallback& callback);
// Sends a GCM id update request to the DM server. The server will
......
......@@ -269,9 +269,9 @@ void CloudPolicyClientRegistrationHelper::OnGetUserInfoSuccess(
registration_type_,
enterprise_management::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
enterprise_management::DeviceRegisterRequest::LIFETIME_INDEFINITE,
enterprise_management::LicenseType::UNDEFINED,
DMAuth::FromOAuthToken(oauth_access_token_), std::string(), std::string(),
std::string());
enterprise_management::LicenseType::UNDEFINED, oauth_access_token_,
std::string() /* client_id */, std::string() /* requisition */,
std::string() /* current_state_key */);
}
void CloudPolicyClientRegistrationHelper::OnPolicyFetched(
......
......@@ -19,6 +19,7 @@
#include "base/message_loop/message_loop.h"
#include "build/build_config.h"
#include "components/policy/core/common/cloud/cloud_policy_util.h"
#include "components/policy/core/common/cloud/dm_auth.h"
#include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
#include "components/policy/core/common/cloud/mock_device_management_service.h"
#include "components/policy/core/common/cloud/mock_signing_service.h"
......@@ -641,8 +642,7 @@ TEST_F(CloudPolicyClientTest, RegistrationAndPolicyFetch) {
client_->Register(em::DeviceRegisterRequest::USER,
em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
em::LicenseType::UNDEFINED,
DMAuth::FromOAuthToken(kOAuthToken), std::string(),
em::LicenseType::UNDEFINED, kOAuthToken, std::string(),
std::string(), std::string());
EXPECT_TRUE(client_->is_registered());
EXPECT_FALSE(client_->GetPolicyFor(policy_type_, std::string()));
......@@ -704,8 +704,7 @@ TEST_F(CloudPolicyClientTest, RegistrationParametersPassedThrough) {
client_->Register(em::DeviceRegisterRequest::USER,
em::DeviceRegisterRequest::FLAVOR_ENROLLMENT_MANUAL,
em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
em::LicenseType::UNDEFINED,
DMAuth::FromOAuthToken(kOAuthToken), kClientID,
em::LicenseType::UNDEFINED, kOAuthToken, kClientID,
kRequisition, kStateKey);
EXPECT_EQ(kClientID, client_id_);
}
......@@ -718,8 +717,7 @@ TEST_F(CloudPolicyClientTest, RegistrationNoToken) {
client_->Register(em::DeviceRegisterRequest::USER,
em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
em::LicenseType::UNDEFINED,
DMAuth::FromOAuthToken(kOAuthToken), std::string(),
em::LicenseType::UNDEFINED, kOAuthToken, std::string(),
std::string(), std::string());
EXPECT_FALSE(client_->is_registered());
EXPECT_FALSE(client_->GetPolicyFor(policy_type_, std::string()));
......@@ -735,8 +733,7 @@ TEST_F(CloudPolicyClientTest, RegistrationFailure) {
client_->Register(em::DeviceRegisterRequest::USER,
em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
em::LicenseType::UNDEFINED,
DMAuth::FromOAuthToken(kOAuthToken), std::string(),
em::LicenseType::UNDEFINED, kOAuthToken, std::string(),
std::string(), std::string());
EXPECT_FALSE(client_->is_registered());
EXPECT_FALSE(client_->GetPolicyFor(policy_type_, std::string()));
......@@ -758,8 +755,7 @@ TEST_F(CloudPolicyClientTest, RetryRegistration) {
client_->Register(em::DeviceRegisterRequest::USER,
em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
em::LicenseType::UNDEFINED,
DMAuth::FromOAuthToken(kOAuthToken), std::string(),
em::LicenseType::UNDEFINED, kOAuthToken, std::string(),
std::string(), std::string());
EXPECT_FALSE(client_->is_registered());
Mock::VerifyAndClearExpectations(&service_);
......@@ -1303,8 +1299,7 @@ TEST_F(CloudPolicyClientTest, RequestAvailableLicenses) {
base::Bind(&MockAvailableLicensesObserver::OnAvailableLicensesFetched,
base::Unretained(&license_callback_observer_));
client_->RequestAvailableLicenses(DMAuth::FromOAuthToken(kOAuthToken),
callback);
client_->RequestAvailableLicenses(kOAuthToken, callback);
EXPECT_EQ(DM_STATUS_SUCCESS, client_->status());
}
......@@ -1319,8 +1314,7 @@ TEST_F(CloudPolicyClientTest, RequestAvailableLicensesBrokenResponse) {
base::Bind(&MockAvailableLicensesObserver::OnAvailableLicensesFetched,
base::Unretained(&license_callback_observer_));
client_->RequestAvailableLicenses(DMAuth::FromOAuthToken(kOAuthToken),
callback);
client_->RequestAvailableLicenses(kOAuthToken, callback);
EXPECT_EQ(DM_STATUS_RESPONSE_DECODING_ERROR, client_->status());
}
......@@ -1422,8 +1416,7 @@ TEST_F(CloudPolicyClientTest, PolicyReregistration) {
client_->Register(em::DeviceRegisterRequest::USER,
em::DeviceRegisterRequest::FLAVOR_ENROLLMENT_RECOVERY,
em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
em::LicenseType::UNDEFINED,
DMAuth::FromOAuthToken(kOAuthToken), client_id_,
em::LicenseType::UNDEFINED, kOAuthToken, client_id_,
std::string(), std::string());
EXPECT_TRUE(client_->is_registered());
EXPECT_FALSE(client_->requires_reregistration());
......@@ -1455,8 +1448,7 @@ TEST_F(CloudPolicyClientTest, PolicyReregistrationFailsWithNonMatchingDMToken) {
client_->Register(em::DeviceRegisterRequest::USER,
em::DeviceRegisterRequest::FLAVOR_ENROLLMENT_RECOVERY,
em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
em::LicenseType::UNDEFINED,
DMAuth::FromOAuthToken(kOAuthToken), client_id_,
em::LicenseType::UNDEFINED, kOAuthToken, client_id_,
std::string(), std::string());
EXPECT_FALSE(client_->is_registered());
EXPECT_TRUE(client_->requires_reregistration());
......
......@@ -28,6 +28,12 @@ const char kParamPlatform[] = "platform";
const char kParamRequest[] = "request";
const char kParamRetry[] = "retry";
// Policy constants used in authorization header.
const char kAuthHeader[] = "Authorization";
const char kServiceTokenAuthHeaderPrefix[] = "GoogleLogin auth=";
const char kDMTokenAuthHeaderPrefix[] = "GoogleDMToken token=";
const char kEnrollmentTokenAuthHeaderPrefix[] = "GoogleEnrollmentToken token=";
// String constants for the device and app type we report to the server.
const char kValueAppType[] = "Chrome";
const char kValueDeviceType[] = "2";
......
......@@ -26,6 +26,12 @@ POLICY_EXPORT extern const char kParamPlatform[];
POLICY_EXPORT extern const char kParamRequest[];
POLICY_EXPORT extern const char kParamRetry[];
// Policy constants used in authorization header.
POLICY_EXPORT extern const char kAuthHeader[];
POLICY_EXPORT extern const char kServiceTokenAuthHeaderPrefix[];
POLICY_EXPORT extern const char kDMTokenAuthHeaderPrefix[];
POLICY_EXPORT extern const char kEnrollmentTokenAuthHeaderPrefix[];
// String extern constants for the device and app type we report to the server.
POLICY_EXPORT extern const char kValueAppType[];
POLICY_EXPORT extern const char kValueDeviceType[];
......
......@@ -9,7 +9,6 @@
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
......@@ -32,11 +31,6 @@ namespace {
const char kPostContentType[] = "application/protobuf";
const char kAuthHeader[] = "Authorization";
const char kServiceTokenAuthHeaderPrefix[] = "GoogleLogin auth=";
const char kDMTokenAuthHeaderPrefix[] = "GoogleDMToken token=";
const char kEnrollmentTokenAuthHeaderPrefix[] = "GoogleEnrollmentToken token=";
// Number of times to retry on ERR_NETWORK_CHANGED errors.
const int kMaxRetries = 3;
......@@ -414,21 +408,27 @@ void DeviceManagementRequestJobImpl::ConfigureRequest(
resource_request->load_flags =
net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES |
net::LOAD_DISABLE_CACHE | (bypass_proxy_ ? net::LOAD_BYPASS_PROXY : 0);
CHECK(auth_data_);
CHECK(auth_data_ || oauth_token_);
if (!auth_data_)
return;
if (!auth_data_->gaia_token().empty()) {
resource_request->headers.SetHeader(
kAuthHeader,
std::string(kServiceTokenAuthHeaderPrefix) + auth_data_->gaia_token());
dm_protocol::kAuthHeader,
std::string(dm_protocol::kServiceTokenAuthHeaderPrefix) +
auth_data_->gaia_token());
}
if (!auth_data_->dm_token().empty()) {
resource_request->headers.SetHeader(
kAuthHeader,
std::string(kDMTokenAuthHeaderPrefix) + auth_data_->dm_token());
dm_protocol::kAuthHeader,
std::string(dm_protocol::kDMTokenAuthHeaderPrefix) +
auth_data_->dm_token());
}
if (!auth_data_->enrollment_token().empty()) {
resource_request->headers.SetHeader(
kAuthHeader, std::string(kEnrollmentTokenAuthHeaderPrefix) +
auth_data_->enrollment_token());
dm_protocol::kAuthHeader,
std::string(dm_protocol::kEnrollmentTokenAuthHeaderPrefix) +
auth_data_->enrollment_token());
}
}
......@@ -498,9 +498,14 @@ void DeviceManagementRequestJobImpl::ReportError(DeviceManagementStatus code) {
DeviceManagementRequestJob::~DeviceManagementRequestJob() {}
void DeviceManagementRequestJob::SetAuthData(std::unique_ptr<DMAuth> auth) {
CHECK(!auth->has_oauth_token()) << "This method does not accept OAuth2";
auth_data_ = std::move(auth);
if (auth_data_->has_oauth_token())
AddParameter(dm_protocol::kParamOAuthToken, auth_data_->oauth_token());
}
void DeviceManagementRequestJob::SetOAuthTokenParameter(
const std::string& oauth_token) {
oauth_token_ = oauth_token;
AddParameter(dm_protocol::kParamOAuthToken, *oauth_token_);
}
void DeviceManagementRequestJob::SetClientID(const std::string& client_id) {
......
......@@ -18,6 +18,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/strings/string_split.h"
#include "base/threading/thread_checker.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
......@@ -82,8 +83,15 @@ class POLICY_EXPORT DeviceManagementRequestJob {
// Functions for configuring the job. These should only be called before
// Start()ing the job, but never afterwards.
void SetClientID(const std::string& client_id);
// Sets authorization data that will be passed in 'Authorization' header of
// the request. This method does not accept OAuth token. Use
// SetOAuthTokenParameter() to pass OAuth token.
void SetAuthData(std::unique_ptr<DMAuth> auth);
// Sets OAuth token that will be passed as a request query parameter.
void SetOAuthTokenParameter(const std::string& oauth_token);
// Sets the critical request parameter, which is used to differentiate regular
// DMServer requests (like scheduled policy fetches) from time-sensitive ones
// (like policy fetch during device enrollment). Should only be called before
......@@ -118,7 +126,14 @@ class POLICY_EXPORT DeviceManagementRequestJob {
JobType type_;
ParameterMap query_params_;
// Auth data that will be passed as 'Authorization' header. Both |auth_data_|
// and |oauth_token_| can be specified for one request.
std::unique_ptr<DMAuth> auth_data_;
// OAuth token that will be passed as a query parameter. Both |auth_data_|
// and |oauth_token_| can be specified for one request.
base::Optional<std::string> oauth_token_;
enterprise_management::DeviceManagementRequest request_;
RetryCallback retry_callback_;
......
......@@ -12,9 +12,12 @@
#include "base/callback_helpers.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/strings/string_split.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/cloud/dm_auth.h"
#include "components/policy/core/common/cloud/mock_device_management_service.h"
#include "net/base/escape.h"
#include "net/base/load_flags.h"
......@@ -91,7 +94,7 @@ class DeviceManagementServiceTestBase : public testing::Test {
DeviceManagementRequestJob* job =
service_->CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION,
shared_url_loader_factory_);
job->SetAuthData(DMAuth::FromOAuthToken(kOAuthToken));
job->SetOAuthTokenParameter(kOAuthToken);
job->SetClientID(kClientID);
job->GetRequest()->mutable_register_request();
job->SetRetryCallback(base::Bind(
......@@ -133,7 +136,7 @@ class DeviceManagementServiceTestBase : public testing::Test {
DeviceManagementRequestJob* job = service_->CreateJob(
DeviceManagementRequestJob::TYPE_API_AUTH_CODE_FETCH,
shared_url_loader_factory_);
job->SetAuthData(DMAuth::FromOAuthToken(kOAuthToken));
job->SetOAuthTokenParameter(kOAuthToken);
job->SetClientID(kClientID);
job->GetRequest()->mutable_service_api_access_request();
job->SetRetryCallback(base::Bind(
......@@ -161,7 +164,7 @@ class DeviceManagementServiceTestBase : public testing::Test {
DeviceManagementRequestJob* job =
service_->CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH,
shared_url_loader_factory_);
job->SetAuthData(DMAuth::FromOAuthToken(kOAuthToken));
job->SetOAuthTokenParameter(kOAuthToken);
job->SetClientID(kClientID);
em::PolicyFetchRequest* fetch_request =
job->GetRequest()->mutable_policy_request()->add_request();
......@@ -177,7 +180,7 @@ class DeviceManagementServiceTestBase : public testing::Test {
DeviceManagementRequestJob* job =
service_->CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH,
shared_url_loader_factory_);
job->SetAuthData(DMAuth::FromOAuthToken(kOAuthToken));
job->SetOAuthTokenParameter(kOAuthToken);
job->SetClientID(kClientID);
job->SetCritical(true);
em::PolicyFetchRequest* fetch_request =
......@@ -445,26 +448,29 @@ class QueryParams {
base::SplitStringIntoKeyValuePairs(query, '=', '&', &params_);
}
// Returns true if there is exactly one query parameter with |name| and its
// value is equal to |expected_value|.
bool Check(const std::string& name, const std::string& expected_value) {
bool found = false;
for (ParamMap::const_iterator i(params_.begin()); i != params_.end(); ++i) {
std::vector<std::string> params = GetParams(name);
return params.size() == 1 && params[0] == expected_value;
}
// Returns vector containing all values for the query param with |name|.
std::vector<std::string> GetParams(const std::string& name) {
std::vector<std::string> results;
for (const auto& param : params_) {
std::string unescaped_name;
net::UnescapeBinaryURLComponent(
i->first, net::UnescapeRule::REPLACE_PLUS_WITH_SPACE,
param.first, net::UnescapeRule::REPLACE_PLUS_WITH_SPACE,
&unescaped_name);
if (unescaped_name == name) {
if (found)
return false;
found = true;
std::string unescaped_value;
std::string value;
net::UnescapeBinaryURLComponent(
i->second, net::UnescapeRule::REPLACE_PLUS_WITH_SPACE,
&unescaped_value);
if (unescaped_value != expected_value)
return false;
param.second, net::UnescapeRule::REPLACE_PLUS_WITH_SPACE, &value);
results.push_back(value);
}
}
return found;
return results;
}
private:
......@@ -1017,4 +1023,179 @@ TEST_F(DeviceManagementServiceTest, CancelDuringRetry) {
base::RunLoop().RunUntilIdle();
}
// Tests that authorization data is correctly added to the request.
class DeviceManagementRequestAuthTest : public DeviceManagementServiceTestBase {
protected:
DeviceManagementRequestAuthTest() = default;
~DeviceManagementRequestAuthTest() override = default;
DeviceManagementRequestJob* StartJobWithAuthData(
std::unique_ptr<DMAuth> auth,
base::Optional<std::string> oauth_token) {
EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, _));
EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
// Job type is not really relevant for the test.
DeviceManagementRequestJob* job =
service_->CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH,
shared_url_loader_factory_);
if (auth)
job->SetAuthData(std::move(auth));
if (oauth_token)
job->SetOAuthTokenParameter(*oauth_token);
job->Start(base::BindRepeating(&DeviceManagementRequestAuthTest::OnJobDone,
base::Unretained(this)));
return job;
}
// Returns vector containing all values for the OAuth query param.
std::vector<std::string> GetOAuthParams(
const network::TestURLLoaderFactory::PendingRequest& request) {
QueryParams query_params(request.request.url.query());
return query_params.GetParams(dm_protocol::kParamOAuthToken);
}
// Returns the value of 'Authorization' header if found.
base::Optional<std::string> GetAuthHeader(
const network::TestURLLoaderFactory::PendingRequest& request) {
std::string header;
bool result =
request.request.headers.GetHeader(dm_protocol::kAuthHeader, &header);
return result ? base::Optional<std::string>(header) : base::nullopt;
}
private:
DISALLOW_COPY_AND_ASSIGN(DeviceManagementRequestAuthTest);
};
TEST_F(DeviceManagementRequestAuthTest, OnlyOAuthToken) {
std::unique_ptr<DeviceManagementRequestJob> request_job(
StartJobWithAuthData(nullptr /* auth */, kOAuthToken));
const network::TestURLLoaderFactory::PendingRequest* request =
GetPendingRequest();
ASSERT_TRUE(request);
const std::vector<std::string> params = GetOAuthParams(*request);
ASSERT_EQ(1u, params.size());
EXPECT_EQ(kOAuthToken, params[0]);
EXPECT_FALSE(GetAuthHeader(*request));
SendResponse(net::OK, 200, std::string());
}
TEST_F(DeviceManagementRequestAuthTest, OnlyDMToken) {
std::unique_ptr<DeviceManagementRequestJob> request_job(StartJobWithAuthData(
DMAuth::FromDMToken(kDMToken), base::nullopt /* oauth_token */));
const network::TestURLLoaderFactory::PendingRequest* request =
GetPendingRequest();
ASSERT_TRUE(request);
const std::vector<std::string> params = GetOAuthParams(*request);
EXPECT_EQ(0u, params.size());
EXPECT_EQ(base::StrCat({dm_protocol::kDMTokenAuthHeaderPrefix, kDMToken}),
GetAuthHeader(*request));
SendResponse(net::OK, 200, std::string());
}
TEST_F(DeviceManagementRequestAuthTest, OnlyEnrollmentToken) {
std::unique_ptr<DeviceManagementRequestJob> request_job(
StartJobWithAuthData(DMAuth::FromEnrollmentToken(kEnrollmentToken),
base::nullopt /* oauth_token */));
const network::TestURLLoaderFactory::PendingRequest* request =
GetPendingRequest();
ASSERT_TRUE(request);
const std::vector<std::string> params = GetOAuthParams(*request);
EXPECT_EQ(0u, params.size());
EXPECT_EQ(base::StrCat({dm_protocol::kEnrollmentTokenAuthHeaderPrefix,
kEnrollmentToken}),
GetAuthHeader(*request));
SendResponse(net::OK, 200, std::string());
}
TEST_F(DeviceManagementRequestAuthTest, OnlyGaiaToken) {
std::unique_ptr<DeviceManagementRequestJob> request_job(StartJobWithAuthData(
DMAuth::FromGaiaToken(kGaiaAuthToken), base::nullopt /* oauth_token */));
const network::TestURLLoaderFactory::PendingRequest* request =
GetPendingRequest();
ASSERT_TRUE(request);
const std::vector<std::string> params = GetOAuthParams(*request);
EXPECT_EQ(0u, params.size());
EXPECT_EQ(base::StrCat(
{dm_protocol::kServiceTokenAuthHeaderPrefix, kGaiaAuthToken}),
GetAuthHeader(*request));
SendResponse(net::OK, 200, std::string());
}
TEST_F(DeviceManagementRequestAuthTest, OAuthAndDMToken) {
std::unique_ptr<DeviceManagementRequestJob> request_job(
StartJobWithAuthData(DMAuth::FromDMToken(kDMToken), kOAuthToken));
const network::TestURLLoaderFactory::PendingRequest* request =
GetPendingRequest();
ASSERT_TRUE(request);
std::vector<std::string> params = GetOAuthParams(*request);
ASSERT_EQ(1u, params.size());
EXPECT_EQ(kOAuthToken, params[0]);
EXPECT_EQ(base::StrCat({dm_protocol::kDMTokenAuthHeaderPrefix, kDMToken}),
GetAuthHeader(*request));
SendResponse(net::OK, 200, std::string());
}
TEST_F(DeviceManagementRequestAuthTest, OAuthAndEnrollmentToken) {
std::unique_ptr<DeviceManagementRequestJob> request_job(StartJobWithAuthData(
DMAuth::FromEnrollmentToken(kEnrollmentToken), kOAuthToken));
const network::TestURLLoaderFactory::PendingRequest* request =
GetPendingRequest();
ASSERT_TRUE(request);
std::vector<std::string> params = GetOAuthParams(*request);
ASSERT_EQ(1u, params.size());
EXPECT_EQ(kOAuthToken, params[0]);
EXPECT_EQ(base::StrCat({dm_protocol::kEnrollmentTokenAuthHeaderPrefix,
kEnrollmentToken}),
GetAuthHeader(*request));
SendResponse(net::OK, 200, std::string());
}
TEST_F(DeviceManagementRequestAuthTest, OAuthAndGaiaToken) {
std::unique_ptr<DeviceManagementRequestJob> request_job(
StartJobWithAuthData(DMAuth::FromGaiaToken(kGaiaAuthToken), kOAuthToken));
const network::TestURLLoaderFactory::PendingRequest* request =
GetPendingRequest();
ASSERT_TRUE(request);
std::vector<std::string> params = GetOAuthParams(*request);
ASSERT_EQ(1u, params.size());
EXPECT_EQ(kOAuthToken, params[0]);
EXPECT_EQ(base::StrCat(
{dm_protocol::kServiceTokenAuthHeaderPrefix, kGaiaAuthToken}),
GetAuthHeader(*request));
SendResponse(net::OK, 200, std::string());
}
TEST_F(DeviceManagementRequestAuthTest, CannotUseOAuthTokenAsAuthData) {
// Job type is not really relevant for the test.
std::unique_ptr<DeviceManagementRequestJob> request_job(
service_->CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH,
shared_url_loader_factory_));
ASSERT_DEATH(request_job->SetAuthData(DMAuth::FromOAuthToken(kOAuthToken)),
"This method does not accept OAuth2");
}
} // namespace policy
......@@ -11,7 +11,6 @@
#include "base/macros.h"
#include "components/policy/core/common/cloud/cloud_policy_client.h"
#include "components/policy/core/common/cloud/dm_auth.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace network {
......@@ -37,7 +36,7 @@ class MockCloudPolicyClient : public CloudPolicyClient {
enterprise_management::DeviceRegisterRequest::Flavor flavor,
enterprise_management::DeviceRegisterRequest::Lifetime lifetime,
enterprise_management::LicenseType::LicenseTypeEnum license_type,
std::unique_ptr<DMAuth>,
const std::string&,
const std::string&,
const std::string&,
const std::string&));
......
......@@ -6,6 +6,7 @@
#include "base/macros.h"
#include "base/strings/string_util.h"
#include "components/policy/core/common/cloud/dm_auth.h"
#include "net/base/net_errors.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
......@@ -32,9 +33,10 @@ class MockRequestJobBase : public DeviceManagementRequestJob {
protected:
void Run() override {
service_->StartJob(ExtractParameter(dm_protocol::kParamRequest),
auth_data_->gaia_token(),
auth_data_ ? auth_data_->gaia_token() : "",
ExtractParameter(dm_protocol::kParamOAuthToken),
auth_data_->dm_token(), auth_data_->enrollment_token(),
auth_data_ ? auth_data_->dm_token() : "",
auth_data_ ? auth_data_->enrollment_token() : "",
ExtractParameter(dm_protocol::kParamDeviceID), request_);
}
......
......@@ -9,7 +9,6 @@
#include "base/macros.h"
#include "components/policy/core/common/cloud/device_management_service.h"
#include "components/policy/core/common/cloud/dm_auth.h"
#include "components/policy/proto/device_management_backend.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment