blob: 2722174905eba8328e31bf22018d22bec7822f18 [file] [log] [blame]
// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "entd/browser.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "entd/entd.h"
#include "entd/utils.h"
namespace entd {
Browser::Policy::Policy()
: entd_(NULL),
policy_path_("/") {
}
bool Browser::Policy::Initialize(Entd *entd, PolicyType policy_type) {
entd_ = entd;
char* home = getenv("HOME");
if (!home) {
LOG(ERROR) << "HOME is not set.";
return false;
}
policy_path_ = FilePath(home).Append(kPolicySubdirectory);
if (policy_type == kManagedPolicy) {
policy_path_ = policy_path_.Append(kPolicyNameManaged);
} else {
policy_path_ = policy_path_.Append(kPolicyNameRecommended);
}
policy_path_ = policy_path_.Append(kPolicyFilename);
// We ignore the return value of Load, since we don't want to fail all of
// entd startup just because we couldn't read the previous policy.
Load();
return true;
}
// static
bool Browser::Policy::InitializeTemplate(
v8::Handle<v8::FunctionTemplate> ctor_t) {
v8::Handle<v8::ObjectTemplate> instance_t = ctor_t->InstanceTemplate();
instance_t->SetNamedPropertyHandler(0, // GetNamedProperty,
SetNamedProperty,
0, // QueryNamedProperty,
DeleteNamedProperty,
0); // EnumerateNamedProperties);
return true;
}
// static
v8::Handle<v8::Value> Browser::Policy::SetNamedProperty(
v8::Local<v8::String> name, v8::Local<v8::Value> value,
const v8::AccessorInfo& info) {
Browser::Policy* policy = Browser::Policy::UnwrapOrThrow(info.This(), "this");
if (!policy)
return v8::Undefined();
v8::Handle<v8::Object> self = policy->js_object();
v8::Handle<v8::Value> old_value = self->Get(name);
self->ForceSet(name, value);
v8::Handle<v8::Value> serialized_object;
if (!policy->entd_->JsonStringify(self, &serialized_object)) {
self->ForceSet(name, old_value);
return ThrowException("Invalid value");
}
v8::String::Utf8Value utf8_object(serialized_object);
if (!policy->Persist(std::string(*utf8_object, utf8_object.length()))) {
self->ForceSet(name, old_value);
return ThrowException("Error persisting policy");
}
return value;
}
// static
v8::Handle<v8::Boolean> Browser::Policy::DeleteNamedProperty(
v8::Local<v8::String> name, const v8::AccessorInfo& info) {
Browser::Policy* policy = Browser::Policy::UnwrapOrThrow(info.This(), "this");
if (!policy)
return v8::False();
v8::Handle<v8::Object> self = policy->js_object();
v8::Handle<v8::Value> old_value = self->Get(name);
self->ForceDelete(name);
v8::Handle<v8::Value> serialized_object;
if (!policy->entd_->JsonStringify(self, &serialized_object)) {
self->ForceSet(name, old_value);
// v8 doesn't like you to throw exceptions from `delete`.
LOG(ERROR) << "Error serializing browser policy";
return v8::False();
}
v8::String::Utf8Value utf8_object(serialized_object);
if (!policy->Persist(std::string(*utf8_object, utf8_object.length()))) {
self->ForceSet(name, old_value);
return v8::False();
}
return v8::True();
}
bool Browser::Policy::Load() {
if (!file_util::PathExists(policy_path_))
return true;
LOG(INFO) << "Loading browser policy file: " << policy_path_.value();
std::string serialized_object;
if (!file_util::ReadFileToString(policy_path_, &serialized_object)) {
PLOG(ERROR) << "Error loading browser policy file: " <<
policy_path_.value();
return false;
}
v8::Handle<v8::Value> value;
if (!entd_->JsonParse(v8::String::New(serialized_object.c_str()), &value)) {
LOG(ERROR) << "Error parsing browser policy file";
return false;
}
if (!value->IsObject()) {
LOG(ERROR) << "Browser policy file did not represent an object";
return false;
}
v8::Handle<v8::Object> policy_values = value->ToObject();
v8::Handle<v8::Object> self = js_object();
v8::Local<v8::Array> ary = policy_values->GetPropertyNames();
for (uint32_t i = 0; i < ary->Length(); ++i) {
v8::Local<v8::Value> name = ary->Get(i);
self->Set(name, policy_values->Get(name));
}
return true;
}
bool Browser::Policy::Persist(const std::string& serialized_object) {
FilePath base_dir = policy_path_.DirName();
if (!file_util::CreateDirectory(base_dir)) {
PLOG(ERROR) << "Error creating path: " << base_dir.value();
return false;
}
if (file_util::WriteFile(
policy_path_, serialized_object.c_str(),
serialized_object.length()) == -1) {
PLOG(ERROR) << "Error saving browser policy file: " <<
policy_path_.value();
return false;
}
return true;
}
bool Browser::Initialize(Entd* entd) {
v8::Handle<v8::Object> self = js_object();
Browser::Policy::Reference managed_policy = Browser::Policy::New();
if (!managed_policy->Initialize(entd, kManagedPolicy))
return false;
Browser::Policy::Reference recommended_policy = Browser::Policy::New();
if (!recommended_policy->Initialize(entd, kRecommendedPolicy))
return false;
self->Set(v8::String::New("managedPolicy"),
managed_policy->js_object());
self->Set(v8::String::New("recommendedPolicy"),
recommended_policy->js_object());
return true;
}
bool Browser::InitializeTemplate(v8::Handle<v8::FunctionTemplate> ctor_t) {
ctor_t->Set(v8::String::New("Policy"),
Policy::constructor_template()->GetFunction());
return true;
}
} // namespace entd