Commit 9fb965f1 authored by mnissler@chromium.org's avatar mnissler@chromium.org

Add support for public account policy to CloudPolicyClient.

BUG=chromium:152937
TEST=Manual, user policy still works.

Review URL: https://codereview.chromium.org/11434053

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@170991 0039d316-1c4b-4281-b951-d872f2087c98
parent 878dc3c0
......@@ -362,9 +362,9 @@ void BrowserPolicyConnector::InitializeUserPolicy(
new UserCloudPolicyManagerChromeOS(store.Pass(),
wait_for_policy_fetch));
user_cloud_policy_manager_->Init();
user_cloud_policy_manager_->Initialize(g_browser_process->local_state(),
device_management_service_.get(),
GetUserAffiliation(user_name));
user_cloud_policy_manager_->Connect(g_browser_process->local_state(),
device_management_service_.get(),
GetUserAffiliation(user_name));
global_user_cloud_policy_provider_.SetDelegate(
user_cloud_policy_manager_.get());
#endif
......
......@@ -39,13 +39,13 @@ CloudPolicyClient::StatusProvider::~StatusProvider() {}
CloudPolicyClient::CloudPolicyClient(const std::string& machine_id,
const std::string& machine_model,
UserAffiliation user_affiliation,
PolicyScope scope,
PolicyType type,
StatusProvider* status_provider,
DeviceManagementService* service)
: machine_id_(machine_id),
machine_model_(machine_model),
user_affiliation_(user_affiliation),
scope_(scope),
type_(type),
device_mode_(DEVICE_MODE_NOT_SET),
submit_machine_id_(false),
public_key_version_(-1),
......@@ -122,6 +122,8 @@ void CloudPolicyClient::FetchPolicy() {
policy_request->set_machine_id(machine_id_);
if (public_key_version_valid_)
policy_request->set_public_key_version(public_key_version_);
if (!entity_id_.empty())
policy_request->set_settings_entity_id(entity_id_);
// Add status data.
if (status_provider_) {
......@@ -161,27 +163,33 @@ void CloudPolicyClient::RemoveObserver(Observer* observer) {
void CloudPolicyClient::SetRegistrationType(
em::DeviceRegisterRequest* request) const {
switch (scope_) {
case POLICY_SCOPE_USER:
switch (type_) {
case POLICY_TYPE_USER:
request->set_type(em::DeviceRegisterRequest::USER);
return;
case POLICY_SCOPE_MACHINE:
case POLICY_TYPE_DEVICE:
request->set_type(em::DeviceRegisterRequest::DEVICE);
return;
case POLICY_TYPE_PUBLIC_ACCOUNT:
LOG(FATAL) << "Cannot register for public account policy.";
return;
}
NOTREACHED() << "Invalid policy scope " << scope_;
NOTREACHED() << "Invalid policy type " << type_;
}
void CloudPolicyClient::SetPolicyType(em::PolicyFetchRequest* request) const {
switch (scope_) {
case POLICY_SCOPE_USER:
switch (type_) {
case POLICY_TYPE_USER:
request->set_policy_type(dm_protocol::kChromeUserPolicyType);
return;
case POLICY_SCOPE_MACHINE:
case POLICY_TYPE_DEVICE:
request->set_policy_type(dm_protocol::kChromeDevicePolicyType);
return;
case POLICY_TYPE_PUBLIC_ACCOUNT:
request->set_policy_type(dm_protocol::kChromePublicAccountPolicyType);
return;
}
NOTREACHED() << "Invalid policy scope " << scope_;
NOTREACHED() << "Invalid policy type " << type_;
}
void CloudPolicyClient::OnRegisterCompleted(
......
......@@ -12,7 +12,6 @@
#include "base/observer_list.h"
#include "base/time.h"
#include "chrome/browser/policy/cloud_policy_constants.h"
#include "chrome/browser/policy/policy_types.h"
namespace enterprise_management {
class DeviceManagementResponse;
......@@ -38,6 +37,13 @@ class DeviceManagementService;
// installed in the cloud policy cache.
class CloudPolicyClient {
public:
// Indicates the type of policy the client should register for and fetch.
enum PolicyType {
POLICY_TYPE_DEVICE,
POLICY_TYPE_USER,
POLICY_TYPE_PUBLIC_ACCOUNT,
};
// Observer interface for state and policy changes.
class Observer {
public:
......@@ -78,7 +84,7 @@ class CloudPolicyClient {
CloudPolicyClient(const std::string& machine_id,
const std::string& machine_model,
UserAffiliation user_affiliation,
PolicyScope scope,
PolicyType policy_type,
StatusProvider* provider,
DeviceManagementService* service);
virtual ~CloudPolicyClient();
......@@ -128,6 +134,10 @@ class CloudPolicyClient {
public_key_version_valid_ = false;
}
void set_entity_id(const std::string& entity_id) {
entity_id_ = entity_id;
}
// Whether the client is registered with the device management service.
bool is_registered() const { return !dm_token_.empty(); }
......@@ -180,7 +190,7 @@ class CloudPolicyClient {
const std::string machine_id_;
const std::string machine_model_;
const UserAffiliation user_affiliation_;
const PolicyScope scope_;
const PolicyType type_;
std::string dm_token_;
DeviceMode device_mode_;
......@@ -189,6 +199,7 @@ class CloudPolicyClient {
base::Time last_policy_timestamp_;
int public_key_version_;
bool public_key_version_valid_;
std::string entity_id_;
// Used for issuing requests to the cloud.
DeviceManagementService* service_;
......
......@@ -87,7 +87,7 @@ class CloudPolicyClientTest : public testing::Test {
.WillRepeatedly(Return(false));
EXPECT_CALL(status_provider_, GetSessionStatus(_))
.WillRepeatedly(Return(false));
CreateClient(USER_AFFILIATION_NONE, POLICY_SCOPE_USER);
CreateClient(USER_AFFILIATION_NONE, CloudPolicyClient::POLICY_TYPE_USER);
}
virtual void TearDown() OVERRIDE {
......@@ -99,12 +99,13 @@ class CloudPolicyClientTest : public testing::Test {
client_->SetupRegistration(kDMToken, client_id_);
}
void CreateClient(UserAffiliation user_affiliation, PolicyScope scope) {
void CreateClient(UserAffiliation user_affiliation,
CloudPolicyClient::PolicyType type) {
if (client_.get())
client_->RemoveObserver(&observer_);
client_.reset(new CloudPolicyClient(kMachineID, kMachineModel,
user_affiliation, scope,
user_affiliation, type,
&status_provider_, &service_));
client_->AddObserver(&observer_);
}
......
......@@ -133,7 +133,8 @@ std::string DeviceCloudPolicyManagerChromeOS::GetMachineModel() {
scoped_ptr<CloudPolicyClient> DeviceCloudPolicyManagerChromeOS::CreateClient() {
return make_scoped_ptr(
new CloudPolicyClient(GetMachineID(), GetMachineModel(),
USER_AFFILIATION_NONE, POLICY_SCOPE_MACHINE, NULL,
USER_AFFILIATION_NONE,
CloudPolicyClient::POLICY_TYPE_DEVICE, NULL,
device_management_service_));
}
......
......@@ -10,7 +10,7 @@ namespace em = enterprise_management;
namespace policy {
MockCloudPolicyClient::MockCloudPolicyClient()
: CloudPolicyClient("", "", USER_AFFILIATION_NONE, POLICY_SCOPE_USER, NULL,
: CloudPolicyClient("", "", USER_AFFILIATION_NONE, POLICY_TYPE_USER, NULL,
NULL) {}
MockCloudPolicyClient::~MockCloudPolicyClient() {}
......
......@@ -10,4 +10,8 @@ MockCloudPolicyStore::MockCloudPolicyStore() {}
MockCloudPolicyStore::~MockCloudPolicyStore() {}
MockCloudPolicyStoreObserver::MockCloudPolicyStoreObserver() {}
MockCloudPolicyStoreObserver::~MockCloudPolicyStoreObserver() {}
} // namespace policy
......@@ -30,6 +30,18 @@ class MockCloudPolicyStore : public CloudPolicyStore {
DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyStore);
};
class MockCloudPolicyStoreObserver : public CloudPolicyStore::Observer {
public:
MockCloudPolicyStoreObserver();
virtual ~MockCloudPolicyStoreObserver();
MOCK_METHOD1(OnStoreLoaded, void(CloudPolicyStore* store));
MOCK_METHOD1(OnStoreError, void(CloudPolicyStore* store));
private:
DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyStoreObserver);
};
} // namespace policy
#endif // CHROME_BROWSER_POLICY_MOCK_CLOUD_POLICY_STORE_H_
......@@ -98,7 +98,7 @@ message PolicyFetchRequest {
// Possible values for Chrome OS are:
// google/chromeos/device => ChromeDeviceSettingsProto
// google/chromeos/user => ChromeSettingsProto
// google/chromeos/unregistered_user => ChromeInitialSettingsProto (unused)
// google/chromeos/publicaccount => ChromeSettingsProto
optional string policy_type = 1;
// This is the last policy timestamp that client received from server.
......@@ -259,6 +259,9 @@ message TimePeriod {
message ActiveTimePeriod {
optional TimePeriod time_period = 1;
// The active duration during the above time period.
// The unit is milli-second.
optional int32 active_duration = 2;
}
......@@ -318,17 +321,21 @@ message DeviceLocation {
// Report device level status.
message DeviceStatusReportRequest {
// The OS version reported by the device is a platform version
// e.g. 1435.0.2011_12_16_1635.
optional string os_version = 1;
optional string firmware_version = 2;
// "Validated", "Dev". Same as verified mode.
// "Verified", "Dev". Same as verified mode.
// If the mode is unknown, this field should not be set.
optional string boot_mode = 3;
// Device active times collection since last report rpc call.
// No longer used -- use active_period instead.
repeated TimePeriod active_time = 4 [deprecated=true];
repeated TimePeriod active_time = 4 [deprecated = true];
// The browser version string as shown in the About dialog.
// e.g. 17.0.963.18.
optional string browser_version = 5;
// A list of periods when the device was active, aggregated by day.
......@@ -418,19 +425,19 @@ message DeviceAutoEnrollmentResponse {
// * Data mime type is application/x-protobuffer
// * HTTP parameters are (all required, all case sensitive):
// * request: MUST BE one of
// * register
// * unregister
// * policy
// * enterprise_check
// * ping
// * policy
// * register
// * status
// * enterprise_check
// * unregister
//
// * devicetype: MUST BE "1" for Android or "2" for Chrome OS.
// * apptype: MUST BE Android or Chrome.
// * deviceid: MUST BE no more than 64-char in [\x21-\x7E].
// * agent: MUST BE no more than 64-char long.
// * HTTP Authorization header MUST be in the following formats:
// * For register and ping requests, using Gaia authentication:
// * For register and ping requests
// Authorization: GoogleLogin auth=<auth cookie for Mobile Sync>
//
// * For unregister, policy and status requests:
......@@ -478,7 +485,7 @@ message DeviceManagementRequest {
// 401 Unauthorized: invalid auth cookie or DM token.
// 403 Forbidden: device management is not allowed.
// 404 Not Found: the request URL is invalid.
// 410 Gone: device is unknown to the server.
// 410 Device Not Found: the device id is not found.
// 491 Request Pending: the request is pending approval.
// 500 Internal Server Error: most likely a bug in DM server.
// 503 Service Unavailable: most likely a backend error.
......
......@@ -33,8 +33,8 @@ void UserCloudPolicyManager::Initialize(
InitializeService(
make_scoped_ptr(new CloudPolicyClient(std::string(), std::string(),
USER_AFFILIATION_NONE,
POLICY_SCOPE_USER, NULL,
device_management_service)));
CloudPolicyClient::POLICY_TYPE_USER,
NULL, device_management_service)));
StartRefreshScheduler(local_state, prefs::kUserPolicyRefreshRate);
}
......
......@@ -7,7 +7,6 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "chrome/browser/policy/cloud_policy_service.h"
#include "chrome/browser/policy/policy_types.h"
#include "chrome/common/pref_names.h"
namespace policy {
......@@ -21,7 +20,7 @@ UserCloudPolicyManagerChromeOS::UserCloudPolicyManagerChromeOS(
UserCloudPolicyManagerChromeOS::~UserCloudPolicyManagerChromeOS() {}
void UserCloudPolicyManagerChromeOS::Initialize(
void UserCloudPolicyManagerChromeOS::Connect(
PrefService* local_state,
DeviceManagementService* device_management_service,
UserAffiliation user_affiliation) {
......@@ -30,7 +29,7 @@ void UserCloudPolicyManagerChromeOS::Initialize(
local_state_ = local_state;
scoped_ptr<CloudPolicyClient> client(
new CloudPolicyClient(std::string(), std::string(), user_affiliation,
POLICY_SCOPE_USER, NULL,
CloudPolicyClient::POLICY_TYPE_USER, NULL,
device_management_service));
InitializeService(client.Pass());
cloud_policy_client()->AddObserver(this);
......
......@@ -33,9 +33,9 @@ class UserCloudPolicyManagerChromeOS : public CloudPolicyManager,
// Initializes the cloud connection. |local_state| and
// |device_management_service| must stay valid until this object is deleted.
void Initialize(PrefService* local_state,
DeviceManagementService* device_management_service,
UserAffiliation user_affiliation);
void Connect(PrefService* local_state,
DeviceManagementService* device_management_service,
UserAffiliation user_affiliation);
// Cancels waiting for the policy fetch and flags the
// ConfigurationPolicyProvider ready (assuming all other initialization tasks
......
......@@ -66,8 +66,8 @@ class UserCloudPolicyManagerChromeOSTest : public testing::Test {
true));
manager_->Init();
manager_->AddObserver(&observer_);
manager_->Initialize(&prefs_, &device_management_service_,
USER_AFFILIATION_NONE);
manager_->Connect(&prefs_, &device_management_service_,
USER_AFFILIATION_NONE);
EXPECT_FALSE(manager_->IsInitializationComplete());
// Finishing the Load() operation shouldn't set the initialized flag.
......
......@@ -10,6 +10,7 @@
#include "base/message_loop.h"
#include "chrome/browser/chromeos/login/mock_user_manager.h"
#include "chrome/browser/policy/cloud_policy_constants.h"
#include "chrome/browser/policy/mock_cloud_policy_store.h"
#include "chrome/browser/policy/policy_builder.h"
#include "chrome/browser/policy/proto/cloud_policy.pb.h"
#include "chrome/browser/policy/proto/device_management_local.pb.h"
......@@ -35,18 +36,6 @@ namespace {
const char kLegacyDeviceId[] = "legacy-device-id";
const char kLegacyToken[] = "legacy-token";
class MockCloudPolicyStoreObserver : public CloudPolicyStore::Observer {
public:
MockCloudPolicyStoreObserver() {}
virtual ~MockCloudPolicyStoreObserver() {}
MOCK_METHOD1(OnStoreLoaded, void(CloudPolicyStore* store));
MOCK_METHOD1(OnStoreError, void(CloudPolicyStore* store));
private:
DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyStoreObserver);
};
class UserCloudPolicyStoreChromeOSTest : public testing::Test {
protected:
UserCloudPolicyStoreChromeOSTest()
......
......@@ -8,6 +8,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop.h"
#include "base/run_loop.h"
#include "chrome/browser/policy/mock_cloud_policy_store.h"
#include "chrome/browser/policy/policy_builder.h"
#include "chrome/browser/signin/signin_manager.h"
#include "chrome/browser/signin/signin_manager_factory.h"
......@@ -31,18 +32,6 @@ void RunUntilIdle() {
run_loop.RunUntilIdle();
}
class MockCloudPolicyStoreObserver : public CloudPolicyStore::Observer {
public:
MockCloudPolicyStoreObserver() {}
virtual ~MockCloudPolicyStoreObserver() {}
MOCK_METHOD1(OnStoreLoaded, void(CloudPolicyStore* store));
MOCK_METHOD1(OnStoreError, void(CloudPolicyStore* store));
private:
DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyStoreObserver);
};
class UserCloudPolicyStoreTest : public testing::Test {
public:
UserCloudPolicyStoreTest()
......
......@@ -25,10 +25,10 @@ Example:
{
"google/chromeos/device" : {
"guest_mode_enabled" : false
"guest_mode_enabled" : false
},
"google/chromeos/user" : {
"mandatory" : {
"mandatory" : {
"HomepageLocation" : "http://www.chromium.org",
"IncognitoEnabled" : false
},
......@@ -36,6 +36,13 @@ Example:
"JavascriptEnabled": false
}
},
"google/chromeos/publicaccount/user@example.com" : {
"mandatory" : {
"HomepageLocation" : "http://www.chromium.org"
},
"recommended" : {
}
},
"managed_users" : [
"secret123456"
]
......@@ -261,7 +268,9 @@ class RequestHandler(object):
"""
for request in msg.request:
if (request.policy_type in
('google/chromeos/user', 'google/chromeos/device')):
('google/chromeos/user',
'google/chromeos/device',
'google/chromeos/publicaccount')):
if request_type != 'policy':
return (400, 'Invalid request type')
else:
......@@ -391,10 +400,10 @@ class RequestHandler(object):
# CloudPolicySettings proto.
# Look for this policy's value in the mandatory or recommended dicts.
if field.name in policies['mandatory']:
if field.name in policies.get('mandatory', {}):
mode = cp.PolicyOptions.MANDATORY
value = policies['mandatory'][field.name]
elif field.name in policies['recommended']:
elif field.name in policies.get('recommended', {}):
mode = cp.PolicyOptions.RECOMMENDED
value = policies['recommended'][field.name]
else:
......@@ -428,22 +437,23 @@ class RequestHandler(object):
self._server.UpdateMachineId(token_info['device_token'], msg.machine_id)
# Response is only given if the scope is specified in the config file.
# Normally 'google/chromeos/device' and 'google/chromeos/user' should be
# accepted.
# Normally 'google/chromeos/device', 'google/chromeos/user' and
# 'google/chromeos/publicaccount' should be accepted.
policy = self._server.GetPolicies()
policy_value = ''
if (msg.policy_type in token_info['allowed_policy_types'] and
msg.policy_type in policy):
policy_key = msg.policy_type
if msg.settings_entity_id:
policy_key += '/' + msg.settings_entity_id
if msg.policy_type in token_info['allowed_policy_types']:
if msg.policy_type == 'google/chromeos/user':
settings = cp.CloudPolicySettings()
self.GatherUserPolicySettings(settings,
policy[msg.policy_type])
policy_value = settings.SerializeToString()
self.GatherUserPolicySettings(settings, policy.get(policy_key, {}))
elif msg.policy_type == 'google/chromeos/device':
settings = dp.ChromeDeviceSettingsProto()
self.GatherDevicePolicySettings(settings,
policy[msg.policy_type])
policy_value = settings.SerializeToString()
self.GatherDevicePolicySettings(settings, policy.get(policy_key, {}))
elif msg.policy_type == 'google/chromeos/publicaccount':
settings = cp.CloudPolicySettings()
self.GatherUserPolicySettings(settings, policy.get(policy_key, {}))
# Figure out the key we want to use. If multiple keys are configured, the
# server will rotate through them in a round-robin fashion.
......@@ -463,18 +473,21 @@ class RequestHandler(object):
policy_data.policy_type = msg.policy_type
policy_data.timestamp = int(time.time() * 1000)
policy_data.request_token = token_info['device_token']
policy_data.policy_value = policy_value
policy_data.policy_value = settings.SerializeToString()
policy_data.machine_name = token_info['machine_name']
policy_data.valid_serial_number_missing = (
token_info['machine_id'] in BAD_MACHINE_IDS)
if signing_key:
policy_data.public_key_version = key_version
# There is no way for the testserver to know the user name belonging to
# the GAIA auth token we received (short of actually talking to GAIA). To
# address this, we read the username from the policy configuration
# dictionary, or use a default.
policy_data.username = policy.get('policy_user', 'user@example.com')
if msg.policy_type == 'google/chromeos/publicaccount':
policy_data.username = msg.settings_entity_id
else:
# For regular user/device policy, there is no way for the testserver to
# know the user name belonging to the GAIA auth token we received (short
# of actually talking to GAIA). To address this, we read the username from
# the policy configuration dictionary, or use a default.
policy_data.username = policy.get('policy_user', 'user@example.com')
policy_data.device_id = token_info['device_id']
signed_data = policy_data.SerializeToString()
......@@ -617,7 +630,10 @@ class TestServer(object):
dmtoken = ''.join(dmtoken_chars)
allowed_policy_types = {
dm.DeviceRegisterRequest.USER: ['google/chromeos/user'],
dm.DeviceRegisterRequest.DEVICE: ['google/chromeos/device'],
dm.DeviceRegisterRequest.DEVICE: [
'google/chromeos/device',
'google/chromeos/publicaccount'
],
dm.DeviceRegisterRequest.TT: ['google/chromeos/user'],
}
if machine_id in KIOSK_MACHINE_IDS:
......
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