Wire up component cloud policy to device local accounts.

Note: this is a reland of https://codereview.chromium.org/341043005 which was
reverted due to memory leaks in tests. Those leaks were fixed in
https://codereview.chromium.org/348713004.

This enables policy-for-extensions running in Public Sessions, and for
extensions running as Kiosk Apps too.

TBR=bartfab@chromium.org
BUG=224596

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278734 0039d316-1c4b-4281-b951-d872f2087c98
parent 0338bc66
......@@ -65,6 +65,9 @@ const char* kPublicSessionWhitelist[] = {
"dhmdaeekeihmajjnmichlhiffffdbpde", // Store.app demo
"jeabmjjifhfcejonjjhccaeigpnnjaak", // TweetDeck demo
"pbdihpaifchmclcmkfdgffnnpfbobefh", // YouTube demo
// Testing extensions:
"ongnjlefhnoajpbodoldndkbkdgfomlp", // Show Managed Storage
};
} // namespace
......
......@@ -17,7 +17,6 @@
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/location.h"
......@@ -33,7 +32,6 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_path_override.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
......@@ -311,15 +309,6 @@ class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest,
PolicyBuilder::kFakeDeviceId);
ASSERT_TRUE(test_server_.Start());
ASSERT_TRUE(extension_cache_root_dir_.CreateUniqueTempDir());
extension_cache_root_dir_override_.reset(new base::ScopedPathOverride(
chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTENSIONS,
extension_cache_root_dir_.path()));
ASSERT_TRUE(external_data_cache_dir_.CreateUniqueTempDir());
external_data_cache_dir_override_.reset(new base::ScopedPathOverride(
chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTERNAL_DATA,
external_data_cache_dir_.path()));
BrowserList::AddObserver(this);
DevicePolicyCrosBrowserTest::SetUp();
......@@ -433,8 +422,11 @@ class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest,
}
base::FilePath GetCacheDirectoryForAccountID(const std::string& account_id) {
return extension_cache_root_dir_.path()
.Append(base::HexEncode(account_id.c_str(), account_id.size()));
base::FilePath extension_cache_root_dir;
PathService::Get(chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTENSIONS,
&extension_cache_root_dir);
return extension_cache_root_dir.Append(
base::HexEncode(account_id.c_str(), account_id.size()));
}
base::FilePath GetCacheCRXFile(const std::string& account_id,
......@@ -459,11 +451,6 @@ class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest,
LocalPolicyTestServer test_server_;
private:
base::ScopedTempDir extension_cache_root_dir_;
base::ScopedTempDir external_data_cache_dir_;
scoped_ptr<base::ScopedPathOverride> extension_cache_root_dir_override_;
scoped_ptr<base::ScopedPathOverride> external_data_cache_dir_override_;
DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountTest);
};
......
......@@ -5,6 +5,7 @@
#include "chrome/browser/chromeos/policy/device_local_account_policy_provider.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/values.h"
#include "chrome/browser/chromeos/policy/device_local_account.h"
#include "chrome/browser/chromeos/policy/device_local_account_external_data_manager.h"
......@@ -14,6 +15,9 @@
#include "components/policy/core/common/policy_bundle.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_namespace.h"
#include "components/policy/core/common/policy_switches.h"
#include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request_context_getter.h"
#include "policy/policy_constants.h"
namespace policy {
......@@ -94,10 +98,19 @@ DeviceLocalAccountPolicyProvider::Create(
return provider.Pass();
}
void DeviceLocalAccountPolicyProvider::Init(SchemaRegistry* schema_registry) {
ConfigurationPolicyProvider::Init(schema_registry);
MaybeCreateComponentPolicyService();
}
bool DeviceLocalAccountPolicyProvider::IsInitializationComplete(
PolicyDomain domain) const {
if (domain == POLICY_DOMAIN_CHROME)
return store_initialized_;
if (ComponentCloudPolicyService::SupportsDomain(domain) &&
component_policy_service_) {
return component_policy_service_->is_initialized();
}
return true;
}
......@@ -113,13 +126,34 @@ void DeviceLocalAccountPolicyProvider::RefreshPolicies() {
}
}
void DeviceLocalAccountPolicyProvider::Shutdown() {
component_policy_service_.reset();
ConfigurationPolicyProvider::Shutdown();
}
void DeviceLocalAccountPolicyProvider::OnPolicyUpdated(
const std::string& user_id) {
if (user_id == user_id_)
if (user_id == user_id_) {
MaybeCreateComponentPolicyService();
UpdateFromBroker();
}
}
void DeviceLocalAccountPolicyProvider::OnDeviceLocalAccountsChanged() {
MaybeCreateComponentPolicyService();
UpdateFromBroker();
}
void DeviceLocalAccountPolicyProvider::OnBrokerShutdown(
DeviceLocalAccountPolicyBroker* broker) {
if (broker->user_id() == user_id_) {
// The |component_policy_service_| relies on the broker's CloudPolicyCore,
// so destroy it if the broker is going away.
component_policy_service_.reset();
}
}
void DeviceLocalAccountPolicyProvider::OnComponentCloudPolicyUpdated() {
UpdateFromBroker();
}
......@@ -153,6 +187,9 @@ void DeviceLocalAccountPolicyProvider::UpdateFromBroker() {
bundle->CopyFrom(policies());
}
if (component_policy_service_)
bundle->MergeFrom(component_policy_service_->policy());
// Apply overrides.
if (chrome_policy_overrides_) {
PolicyMap& chrome_policy =
......@@ -169,4 +206,35 @@ void DeviceLocalAccountPolicyProvider::UpdateFromBroker() {
UpdatePolicy(bundle.Pass());
}
void DeviceLocalAccountPolicyProvider::MaybeCreateComponentPolicyService() {
if (component_policy_service_)
return; // Already started.
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableComponentCloudPolicy)) {
// Disabled via the command line.
return;
}
DeviceLocalAccountPolicyBroker* broker = GetBroker();
if (!broker || !schema_registry())
return; // Missing broker or not initialized yet.
scoped_ptr<ResourceCache> resource_cache(
new ResourceCache(broker->GetComponentPolicyCachePath(),
content::BrowserThread::GetMessageLoopProxyForThread(
content::BrowserThread::FILE)));
component_policy_service_.reset(new ComponentCloudPolicyService(
this,
schema_registry(),
broker->core(),
resource_cache.Pass(),
service_->request_context(),
content::BrowserThread::GetMessageLoopProxyForThread(
content::BrowserThread::FILE),
content::BrowserThread::GetMessageLoopProxyForThread(
content::BrowserThread::IO)));
}
} // namespace policy
......@@ -14,6 +14,8 @@
#include "base/memory/weak_ptr.h"
#include "chrome/browser/chromeos/policy/device_local_account_external_data_manager.h"
#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
#include "components/policy/core/common/cloud/component_cloud_policy_service.h"
#include "components/policy/core/common/cloud/resource_cache.h"
#include "components/policy/core/common/configuration_policy_provider.h"
namespace policy {
......@@ -27,7 +29,8 @@ class PolicyMap;
// and RefreshPolicies becomes a no-op.
class DeviceLocalAccountPolicyProvider
: public ConfigurationPolicyProvider,
public DeviceLocalAccountPolicyService::Observer {
public DeviceLocalAccountPolicyService::Observer,
public ComponentCloudPolicyService::Delegate {
public:
DeviceLocalAccountPolicyProvider(
const std::string& user_id,
......@@ -43,12 +46,19 @@ class DeviceLocalAccountPolicyProvider
DeviceLocalAccountPolicyService* service);
// ConfigurationPolicyProvider:
virtual void Init(SchemaRegistry* registry) OVERRIDE;
virtual bool IsInitializationComplete(PolicyDomain domain) const OVERRIDE;
virtual void RefreshPolicies() OVERRIDE;
virtual void Shutdown() OVERRIDE;
// DeviceLocalAccountPolicyService::Observer:
virtual void OnPolicyUpdated(const std::string& user_id) OVERRIDE;
virtual void OnDeviceLocalAccountsChanged() OVERRIDE;
virtual void OnBrokerShutdown(
DeviceLocalAccountPolicyBroker* broker) OVERRIDE;
// ComponentCloudPolicyService::Delegate:
virtual void OnComponentCloudPolicyUpdated() OVERRIDE;
private:
// Returns the broker for |user_id_| or NULL if not available.
......@@ -62,6 +72,10 @@ class DeviceLocalAccountPolicyProvider
// policy from the broker if available or keeping the current policy.
void UpdateFromBroker();
// Creates the |component_policy_service_| if it hasn't been created yet
// and all the dependencies are in place.
void MaybeCreateComponentPolicyService();
const std::string user_id_;
scoped_refptr<DeviceLocalAccountExternalDataManager> external_data_manager_;
......@@ -75,6 +89,8 @@ class DeviceLocalAccountPolicyProvider
bool store_initialized_;
bool waiting_for_policy_refresh_;
scoped_ptr<ComponentCloudPolicyService> component_policy_service_;
base::WeakPtrFactory<DeviceLocalAccountPolicyProvider> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountPolicyProvider);
......
......@@ -9,12 +9,12 @@
#include "base/bind.h"
#include "base/file_util.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/path_service.h"
#include "base/sequenced_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/policy/device_local_account.h"
......@@ -31,6 +31,7 @@
#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/system_policy_request_context.h"
#include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request_context_getter.h"
#include "policy/policy_constants.h"
#include "policy/proto/device_management_backend.pb.h"
......@@ -72,30 +73,27 @@ scoped_ptr<CloudPolicyClient> CreateClient(
}
// Get the subdirectory of the cache directory in which force-installed
// extensions are cached for |account_id|.
std::string GetCacheSubdirectoryForAccountID(const std::string& account_id) {
// extensions are cached for |account_id|. This is also used for the
// component policy cache.
std::string EncodeAccountId(const std::string& account_id) {
return base::HexEncode(account_id.c_str(), account_id.size());
}
// Cleans up the cache directory by removing subdirectories that are not found
// in |subdirectories_to_keep|. Only caches whose cache directory is found in
// |subdirectories_to_keep| may be running while the clean-up is in progress.
void DeleteOrphanedExtensionCaches(
void DeleteOrphanedCaches(
const base::FilePath& cache_root_dir,
const std::set<std::string>& subdirectories_to_keep) {
base::FilePath cache_root_dir;
CHECK(PathService::Get(chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTENSIONS,
&cache_root_dir));
base::FileEnumerator enumerator(cache_root_dir,
false,
base::FileEnumerator::DIRECTORIES);
for (base::FilePath path = enumerator.Next(); !path.empty();
path = enumerator.Next()) {
const std::string subdirectory(path.BaseName().MaybeAsASCII());
if (subdirectories_to_keep.find(subdirectory) ==
subdirectories_to_keep.end()) {
if (!ContainsKey(subdirectories_to_keep, subdirectory))
base::DeleteFile(path, true);
}
}
}
// Removes the subdirectory belonging to |account_id_to_delete| from the cache
......@@ -105,8 +103,8 @@ void DeleteObsoleteExtensionCache(const std::string& account_id_to_delete) {
base::FilePath cache_root_dir;
CHECK(PathService::Get(chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTENSIONS,
&cache_root_dir));
const base::FilePath path = cache_root_dir
.Append(GetCacheSubdirectoryForAccountID(account_id_to_delete));
const base::FilePath path =
cache_root_dir.Append(EncodeAccountId(account_id_to_delete));
if (base::DirectoryExists(path))
base::DeleteFile(path, true);
}
......@@ -115,11 +113,13 @@ void DeleteObsoleteExtensionCache(const std::string& account_id_to_delete) {
DeviceLocalAccountPolicyBroker::DeviceLocalAccountPolicyBroker(
const DeviceLocalAccount& account,
const base::FilePath& component_policy_cache_path,
scoped_ptr<DeviceLocalAccountPolicyStore> store,
scoped_refptr<DeviceLocalAccountExternalDataManager> external_data_manager,
const scoped_refptr<base::SequencedTaskRunner>& task_runner)
: account_id_(account.account_id),
user_id_(account.user_id),
component_policy_cache_path_(component_policy_cache_path),
store_(store.Pass()),
external_data_manager_(external_data_manager),
core_(PolicyNamespaceKey(dm_protocol::kChromePublicAccountPolicyType,
......@@ -130,9 +130,7 @@ DeviceLocalAccountPolicyBroker::DeviceLocalAccountPolicyBroker(
CHECK(PathService::Get(chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTENSIONS,
&cache_root_dir));
extension_loader_ = new chromeos::DeviceLocalAccountExternalPolicyLoader(
store_.get(),
cache_root_dir.Append(
GetCacheSubdirectoryForAccountID(account.account_id)));
store_.get(), cache_root_dir.Append(EncodeAccountId(account.account_id)));
}
DeviceLocalAccountPolicyBroker::~DeviceLocalAccountPolicyBroker() {
......@@ -182,6 +180,11 @@ std::string DeviceLocalAccountPolicyBroker::GetDisplayName() const {
return display_name;
}
base::FilePath DeviceLocalAccountPolicyBroker::GetComponentPolicyCachePath()
const {
return component_policy_cache_path_;
}
DeviceLocalAccountPolicyService::DeviceLocalAccountPolicyService(
chromeos::SessionManagerClient* session_manager_client,
chromeos::DeviceSettingsService* device_settings_service,
......@@ -207,6 +210,8 @@ DeviceLocalAccountPolicyService::DeviceLocalAccountPolicyService(
UpdateAccountListIfNonePending,
base::Unretained(this)))),
weak_factory_(this) {
CHECK(PathService::Get(chromeos::DIR_DEVICE_LOCAL_ACCOUNT_COMPONENT_POLICY,
&component_policy_cache_root_));
external_data_service_.reset(new DeviceLocalAccountExternalDataService(
this,
external_data_service_backend_task_runner,
......@@ -255,6 +260,11 @@ bool DeviceLocalAccountPolicyService::IsPolicyAvailableForUser(
return broker && broker->core()->store()->is_managed();
}
scoped_refptr<net::URLRequestContextGetter>
DeviceLocalAccountPolicyService::request_context() const {
return request_context_;
}
void DeviceLocalAccountPolicyService::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
......@@ -414,6 +424,7 @@ void DeviceLocalAccountPolicyService::UpdateAccountList() {
store.get());
broker.reset(new DeviceLocalAccountPolicyBroker(
*it,
component_policy_cache_root_.Append(EncodeAccountId(it->account_id)),
store.Pass(),
external_data_manager,
base::MessageLoopProxy::current()));
......@@ -432,16 +443,7 @@ void DeviceLocalAccountPolicyService::UpdateAccountList() {
policy_brokers_[it->user_id]->Initialize();
}
if (orphan_cache_deletion_state_ == NOT_STARTED) {
subdirectories_to_keep.insert(
GetCacheSubdirectoryForAccountID(it->account_id));
}
}
std::set<std::string> obsolete_account_ids;
for (PolicyBrokerMap::const_iterator it = old_policy_brokers.begin();
it != old_policy_brokers.end(); ++it) {
obsolete_account_ids.insert(it->second->account_id());
subdirectories_to_keep.insert(EncodeAccountId(it->account_id));
}
if (orphan_cache_deletion_state_ == NOT_STARTED) {
......@@ -453,11 +455,16 @@ void DeviceLocalAccountPolicyService::UpdateAccountList() {
// orphaned cache directories not found in |subdirectories_to_keep| from the
// cache directory.
orphan_cache_deletion_state_ = IN_PROGRESS;
base::FilePath cache_root_dir;
CHECK(PathService::Get(chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTENSIONS,
&cache_root_dir));
extension_cache_task_runner_->PostTaskAndReply(
FROM_HERE,
base::Bind(&DeleteOrphanedExtensionCaches, subdirectories_to_keep),
base::Bind(&DeviceLocalAccountPolicyService::
OnOrphanedExtensionCachesDeleted,
base::Bind(
&DeleteOrphanedCaches, cache_root_dir, subdirectories_to_keep),
base::Bind(
&DeviceLocalAccountPolicyService::OnOrphanedExtensionCachesDeleted,
weak_factory_.GetWeakPtr()));
// Start the extension caches for all brokers. These belong to accounts in
......@@ -476,6 +483,16 @@ void DeviceLocalAccountPolicyService::UpdateAccountList() {
}
}
// Purge the component policy caches of any accounts that have been removed.
// Do this only after any obsolete brokers have been destroyed.
// TODO(joaodasilva): for now this must be posted to the FILE thread,
// to avoid racing with the ComponentCloudPolicyStore. Use a task runner
// once that class supports another background thread too.
content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
base::Bind(&DeleteOrphanedCaches,
component_policy_cache_root_,
subdirectories_to_keep));
FOR_EACH_OBSERVER(Observer, observers_, OnDeviceLocalAccountsChanged());
}
......@@ -492,6 +509,7 @@ void DeviceLocalAccountPolicyService::DeleteBrokers(PolicyBrokerMap* map) {
weak_factory_.GetWeakPtr(),
it->second->account_id()));
}
FOR_EACH_OBSERVER(Observer, observers_, OnBrokerShutdown(it->second));
delete it->second;
}
map->clear();
......
......@@ -11,6 +11,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
......@@ -48,6 +49,7 @@ class DeviceLocalAccountPolicyBroker {
// |task_runner| is the runner for policy refresh tasks.
DeviceLocalAccountPolicyBroker(
const DeviceLocalAccount& account,
const base::FilePath& component_policy_cache_path,
scoped_ptr<DeviceLocalAccountPolicyStore> store,
scoped_refptr<DeviceLocalAccountExternalDataManager>
external_data_manager,
......@@ -86,9 +88,15 @@ class DeviceLocalAccountPolicyBroker {
// empty string if the policy is not present.
std::string GetDisplayName() const;
// Returns a directory where component policy for this account can be cached.
// The DeviceLocalAccountPolicyService takes care of cleaning up caches of
// accounts that have been removed.
base::FilePath GetComponentPolicyCachePath() const;
private:
const std::string account_id_;
const std::string user_id_;
const base::FilePath component_policy_cache_path_;
const scoped_ptr<DeviceLocalAccountPolicyStore> store_;
scoped_refptr<DeviceLocalAccountExternalDataManager> external_data_manager_;
scoped_refptr<chromeos::DeviceLocalAccountExternalPolicyLoader>
......@@ -114,6 +122,9 @@ class DeviceLocalAccountPolicyService : public CloudPolicyStore::Observer {
// The list of accounts has been updated.
virtual void OnDeviceLocalAccountsChanged() = 0;
// The given |broker| is about to be destroyed.
virtual void OnBrokerShutdown(DeviceLocalAccountPolicyBroker* broker) {}
};
DeviceLocalAccountPolicyService(
......@@ -142,6 +153,8 @@ class DeviceLocalAccountPolicyService : public CloudPolicyStore::Observer {
// |user_id|.
bool IsPolicyAvailableForUser(const std::string& user_id);
scoped_refptr<net::URLRequestContextGetter> request_context() const;
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
......@@ -229,6 +242,10 @@ class DeviceLocalAccountPolicyService : public CloudPolicyStore::Observer {
const scoped_ptr<chromeos::CrosSettings::ObserverSubscription>
local_accounts_subscription_;
// Path to the directory that contains the cached policies for components
// for device local accounts.
base::FilePath component_policy_cache_root_;
base::WeakPtrFactory<DeviceLocalAccountPolicyService> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountPolicyService);
......
......@@ -443,6 +443,14 @@ class PolicyRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
self.server.UpdateStateKeys(token_info['device_token'],
key_update_request.server_backed_state_key)
# If this is a publicaccount request then get the username now and use it
# in every PolicyFetchResponse produced. This is required to validate
# policy for extensions in public accounts.
username = self.server.GetPolicies().get('policy_user', None)
for request in msg.policy_request.request:
if request.policy_type == 'google/chromeos/publicaccount':
username = request.settings_entity_id
response = dm.DeviceManagementResponse()
for request in msg.policy_request.request:
if (request.policy_type in
......@@ -456,7 +464,7 @@ class PolicyRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
self.ProcessCloudPolicy(request, token_info, fetch_response)
elif request.policy_type == 'google/chrome/extension':
self.ProcessCloudPolicyForExtensions(
request, response.policy_response, token_info)
request, response.policy_response, token_info, username)
else:
fetch_response.error_code = 400
fetch_response.error_message = 'Invalid policy_type'
......@@ -628,7 +636,8 @@ class PolicyRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
self.SetProtobufMessageField(policy_message, field_descriptor, value)
settings.__getattribute__(field.name).CopyFrom(policy_message)
def ProcessCloudPolicyForExtensions(self, request, response, token_info):
def ProcessCloudPolicyForExtensions(self, request, response, token_info,
username):
"""Handles a request for policy for extensions.
A request for policy for extensions is slightly different from the other
......@@ -640,6 +649,7 @@ class PolicyRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
response: The DevicePolicyResponse message for the response. Multiple
PolicyFetchResponses will be appended to this message.
token_info: The token extracted from the request.
username: The username for the response.
"""
# Send one PolicyFetchResponse for each extension that has
# configuration data at the server.
......@@ -649,13 +659,13 @@ class PolicyRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
# type in the response.
request.settings_entity_id = settings_entity_id
fetch_response = response.response.add()
self.ProcessCloudPolicy(request, token_info, fetch_response)
self.ProcessCloudPolicy(request, token_info, fetch_response, username)
# Don't do key rotations for these messages.
fetch_response.ClearField('new_public_key')
fetch_response.ClearField('new_public_key_signature')
fetch_response.ClearField('new_public_key_verification_signature')
def ProcessCloudPolicy(self, msg, token_info, response):
def ProcessCloudPolicy(self, msg, token_info, response, username=None):
"""Handles a cloud policy request. (New protocol for policy requests.)
Encodes the policy into protobuf representation, signs it and constructs
......@@ -666,6 +676,7 @@ class PolicyRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
token_info: The token extracted from the request.
response: A PolicyFetchResponse message that should be filled with the
response data.
username: The username for the response. May be None.
"""
if msg.machine_id:
......@@ -746,7 +757,10 @@ class PolicyRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
if signing_key:
policy_data.public_key_version = current_key_index + 1
if msg.policy_type == 'google/chromeos/publicaccount':
if username:
policy_data.username = username
elif 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
......@@ -960,7 +974,8 @@ class PolicyTestServer(testserver_base.BrokenPipeHandlerMixIn,
],
dm.DeviceRegisterRequest.DEVICE: [
'google/chromeos/device',
'google/chromeos/publicaccount'
'google/chromeos/publicaccount',
'google/chrome/extension'
],
dm.DeviceRegisterRequest.ANDROID_BROWSER: [
'google/android/user'
......
......@@ -41,6 +41,9 @@ const base::FilePath::CharType kDeviceLocalAccountExtensionDir[] =
const base::FilePath::CharType kDeviceLocalAccountExternalDataDir[] =
FILE_PATH_LITERAL("/var/cache/device_local_account_external_policy_data");
const base::FilePath::CharType kDeviceLocalAccountComponentPolicy[] =
FILE_PATH_LITERAL("/var/cache/device_local_account_component_policy");
bool PathProvider(int key, base::FilePath* result) {
switch (key) {
case FILE_DEFAULT_APP_ORDER:
......@@ -67,6 +70,9 @@ bool PathProvider(int key, base::FilePath* result) {
case DIR_DEVICE_LOCAL_ACCOUNT_EXTERNAL_DATA:
*result = base::FilePath(kDeviceLocalAccountExternalDataDir);
break;
case DIR_DEVICE_LOCAL_ACCOUNT_COMPONENT_POLICY:
*result = base::FilePath(kDeviceLocalAccountComponentPolicy);
break;
default:
return false;
}
......@@ -99,6 +105,15 @@ void RegisterStubPathOverrides(const base::FilePath& stubs_dir) {
parent.AppendASCII("stub_install_attributes.pb"),
is_absolute,
create);
PathService::Override(
DIR_DEVICE_LOCAL_ACCOUNT_EXTENSIONS,
parent.AppendASCII("stub_device_local_account_extensions"));
PathService::Override(
DIR_DEVICE_LOCAL_ACCOUNT_EXTERNAL_DATA,
parent.AppendASCII("stub_device_local_account_external_data"));
PathService::Override(
DIR_DEVICE_LOCAL_ACCOUNT_COMPONENT_POLICY,
parent.AppendASCII("stub_device_local_account_component_policy"));
}
} // namespace chromeos
......@@ -38,6 +38,11 @@ enum {
DIR_DEVICE_LOCAL_ACCOUNT_EXTERNAL_DATA, // Directory where external data
// referenced by policies is cached
// for device-local accounts.
DIR_DEVICE_LOCAL_ACCOUNT_COMPONENT_POLICY, // Directory where policy for the
// components of device-local
// account is stored. Currently
// this is used for policy for
// extensions.
PATH_END
};
......
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