This source file includes following definitions.
- IsUnsafeCharacter
- config_file_
- SetSigningKeyAndSignature
- RegisterClient
- UpdatePolicy
- UpdatePolicyData
- GetServiceURL
- SetPythonPath
- GetTestServerPath
- GenerateAdditionalArguments
- GetSelector
#include "chrome/browser/policy/test/local_policy_test_server.h"
#include <ctype.h>
#include <algorithm>
#include <vector>
#include "base/base_paths.h"
#include "base/file_util.h"
#include "base/json/json_writer.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "crypto/rsa_private_key.h"
#include "net/test/python_utils.h"
#include "net/test/spawned_test_server/base_test_server.h"
namespace policy {
namespace {
const base::FilePath::CharType kPolicyFileName[] = FILE_PATH_LITERAL("policy");
const base::FilePath::CharType kSigningKeyFileName[] =
FILE_PATH_LITERAL("signing_key");
const base::FilePath::CharType kSigningKeySignatureFileName[] =
FILE_PATH_LITERAL("signing_key.sig");
const base::FilePath::CharType kClientStateFileName[] =
FILE_PATH_LITERAL("clients");
const char kClientStateKeyAllowedPolicyTypes[] = "allowed_policy_types";
const char kClientStateKeyDeviceId[] = "device_id";
const char kClientStateKeyDeviceToken[] = "device_token";
const char kClientStateKeyMachineName[] = "machine_name";
const char kClientStateKeyMachineId[] = "machine_id";
bool IsUnsafeCharacter(char c) {
return !(isalnum(c) || c == '.' || c == '@' || c == '-');
}
}
LocalPolicyTestServer::LocalPolicyTestServer()
: net::LocalTestServer(net::BaseTestServer::TYPE_HTTP,
net::BaseTestServer::kLocalhost,
base::FilePath()) {
CHECK(server_data_dir_.CreateUniqueTempDir());
config_file_ = server_data_dir_.path().Append(kPolicyFileName);
}
LocalPolicyTestServer::LocalPolicyTestServer(const base::FilePath& config_file)
: net::LocalTestServer(net::BaseTestServer::TYPE_HTTP,
net::BaseTestServer::kLocalhost,
base::FilePath()),
config_file_(config_file) {}
LocalPolicyTestServer::LocalPolicyTestServer(const std::string& test_name)
: net::LocalTestServer(net::BaseTestServer::TYPE_HTTP,
net::BaseTestServer::kLocalhost,
base::FilePath()) {
base::FilePath source_root;
CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &source_root));
config_file_ = source_root
.AppendASCII("chrome")
.AppendASCII("test")
.AppendASCII("data")
.AppendASCII("policy")
.AppendASCII(base::StringPrintf("policy_%s.json", test_name.c_str()));
}
LocalPolicyTestServer::~LocalPolicyTestServer() {}
bool LocalPolicyTestServer::SetSigningKeyAndSignature(
const crypto::RSAPrivateKey* key, const std::string& signature) {
CHECK(server_data_dir_.IsValid());
std::vector<uint8> signing_key_bits;
if (!key->ExportPrivateKey(&signing_key_bits))
return false;
policy_key_ = server_data_dir_.path().Append(kSigningKeyFileName);
int bytes_written = base::WriteFile(
policy_key_,
reinterpret_cast<const char*>(vector_as_array(&signing_key_bits)),
signing_key_bits.size());
if (bytes_written != static_cast<int>(signing_key_bits.size()))
return false;
base::FilePath signature_file = server_data_dir_.path().Append(
kSigningKeySignatureFileName);
bytes_written = base::WriteFile(
signature_file,
signature.c_str(),
signature.size());
return bytes_written == static_cast<int>(signature.size());
}
void LocalPolicyTestServer::RegisterClient(const std::string& dm_token,
const std::string& device_id) {
CHECK(server_data_dir_.IsValid());
scoped_ptr<base::DictionaryValue> client_dict(new base::DictionaryValue());
client_dict->SetString(kClientStateKeyDeviceId, device_id);
client_dict->SetString(kClientStateKeyDeviceToken, dm_token);
client_dict->SetString(kClientStateKeyMachineName, std::string());
client_dict->SetString(kClientStateKeyMachineId, std::string());
scoped_ptr<base::ListValue> types(new base::ListValue());
types->AppendString(dm_protocol::kChromeDevicePolicyType);
types->AppendString(dm_protocol::kChromeUserPolicyType);
types->AppendString(dm_protocol::kChromePublicAccountPolicyType);
types->AppendString(dm_protocol::kChromeExtensionPolicyType);
client_dict->Set(kClientStateKeyAllowedPolicyTypes, types.release());
clients_.Set(dm_token, client_dict.release());
}
bool LocalPolicyTestServer::UpdatePolicy(const std::string& type,
const std::string& entity_id,
const std::string& policy) {
CHECK(server_data_dir_.IsValid());
std::string selector = GetSelector(type, entity_id);
base::FilePath policy_file = server_data_dir_.path().AppendASCII(
base::StringPrintf("policy_%s.bin", selector.c_str()));
return base::WriteFile(policy_file, policy.c_str(), policy.size()) ==
static_cast<int>(policy.size());
}
bool LocalPolicyTestServer::UpdatePolicyData(const std::string& type,
const std::string& entity_id,
const std::string& data) {
CHECK(server_data_dir_.IsValid());
std::string selector = GetSelector(type, entity_id);
base::FilePath data_file = server_data_dir_.path().AppendASCII(
base::StringPrintf("policy_%s.data", selector.c_str()));
return base::WriteFile(data_file, data.c_str(), data.size()) ==
static_cast<int>(data.size());
}
GURL LocalPolicyTestServer::GetServiceURL() const {
return GetURL("device_management");
}
bool LocalPolicyTestServer::SetPythonPath() const {
if (!net::LocalTestServer::SetPythonPath())
return false;
base::FilePath net_testserver_path;
if (!LocalTestServer::GetTestServerPath(&net_testserver_path)) {
LOG(ERROR) << "Failed to get net testserver path.";
return false;
}
AppendToPythonPath(net_testserver_path.DirName());
base::FilePath third_party_dir;
if (!PathService::Get(base::DIR_SOURCE_ROOT, &third_party_dir)) {
LOG(ERROR) << "Failed to get DIR_SOURCE_ROOT";
return false;
}
AppendToPythonPath(third_party_dir
.AppendASCII("third_party")
.AppendASCII("protobuf")
.AppendASCII("python"));
base::FilePath pyproto_dir;
if (!GetPyProtoPath(&pyproto_dir)) {
LOG(ERROR) << "Cannot find pyproto dir for generated code.";
return false;
}
AppendToPythonPath(pyproto_dir
.AppendASCII("chrome")
.AppendASCII("browser")
.AppendASCII("policy")
.AppendASCII("proto")
.AppendASCII("cloud"));
AppendToPythonPath(pyproto_dir
.AppendASCII("policy")
.AppendASCII("proto"));
#if defined(OS_CHROMEOS)
AppendToPythonPath(pyproto_dir
.AppendASCII("chrome")
.AppendASCII("browser")
.AppendASCII("policy")
.AppendASCII("proto")
.AppendASCII("chromeos"));
#endif
return true;
}
bool LocalPolicyTestServer::GetTestServerPath(
base::FilePath* testserver_path) const {
base::FilePath source_root;
if (!PathService::Get(base::DIR_SOURCE_ROOT, &source_root)) {
LOG(ERROR) << "Failed to get DIR_SOURCE_ROOT";
return false;
}
*testserver_path = source_root
.AppendASCII("chrome")
.AppendASCII("browser")
.AppendASCII("policy")
.AppendASCII("test")
.AppendASCII("policy_testserver.py");
return true;
}
bool LocalPolicyTestServer::GenerateAdditionalArguments(
base::DictionaryValue* arguments) const {
if (!net::LocalTestServer::GenerateAdditionalArguments(arguments))
return false;
arguments->SetString("config-file", config_file_.AsUTF8Unsafe());
if (!policy_key_.empty())
arguments->SetString("policy-key", policy_key_.AsUTF8Unsafe());
if (server_data_dir_.IsValid()) {
arguments->SetString("data-dir", server_data_dir_.path().AsUTF8Unsafe());
if (!clients_.empty()) {
std::string json;
base::JSONWriter::Write(&clients_, &json);
base::FilePath client_state_file =
server_data_dir_.path().Append(kClientStateFileName);
if (base::WriteFile(client_state_file, json.c_str(), json.size()) !=
static_cast<int>(json.size())) {
return false;
}
arguments->SetString("client-state", client_state_file.AsUTF8Unsafe());
}
}
return true;
}
std::string LocalPolicyTestServer::GetSelector(const std::string& type,
const std::string& entity_id) {
std::string selector = type;
if (!entity_id.empty())
selector = base::StringPrintf("%s/%s", type.c_str(), entity_id.c_str());
std::replace_if(selector.begin(), selector.end(), IsUnsafeCharacter, '_');
return selector;
}
}