aboutsummaryrefslogtreecommitdiff
path: root/src/component_manager_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/component_manager_impl.cc')
-rw-r--r--src/component_manager_impl.cc112
1 files changed, 108 insertions, 4 deletions
diff --git a/src/component_manager_impl.cc b/src/component_manager_impl.cc
index 3ea1f46..9712a3c 100644
--- a/src/component_manager_impl.cc
+++ b/src/component_manager_impl.cc
@@ -27,6 +27,60 @@ const EnumToStringMap<UserRole>::Map kMap[] = {
{UserRole::kOwner, "owner"},
{UserRole::kManager, "manager"},
};
+
+void RemoveInaccessibleState(const ComponentManagerImpl* manager,
+ base::DictionaryValue* component,
+ UserRole role) {
+ std::vector<std::string> state_props_to_remove;
+ base::DictionaryValue* state = nullptr;
+ if (component->GetDictionary("state", &state)) {
+ for (base::DictionaryValue::Iterator it_trait(*state);
+ !it_trait.IsAtEnd(); it_trait.Advance()) {
+ const base::DictionaryValue* trait = nullptr;
+ CHECK(it_trait.value().GetAsDictionary(&trait));
+ for (base::DictionaryValue::Iterator it_prop(*trait);
+ !it_prop.IsAtEnd(); it_prop.Advance()) {
+ std::string prop_name = base::StringPrintf("%s.%s",
+ it_trait.key().c_str(),
+ it_prop.key().c_str());
+ UserRole minimal_role;
+ if (manager->GetStateMinimalRole(prop_name, &minimal_role, nullptr) &&
+ minimal_role > role) {
+ state_props_to_remove.push_back(prop_name);
+ }
+ }
+ }
+ }
+ // Now remove any inaccessible properties from the state collection.
+ for (const std::string& path : state_props_to_remove) {
+ // Remove starting from component level in order for "state" to be removed
+ // if no sub-properties remain.
+ CHECK(component->RemovePath(base::StringPrintf("state.%s", path.c_str()),
+ nullptr));
+ }
+
+ // If this component has any sub-components, filter them too.
+ base::DictionaryValue* sub_components = nullptr;
+ if (component->GetDictionary("components", &sub_components)) {
+ for (base::DictionaryValue::Iterator it_component(*sub_components);
+ !it_component.IsAtEnd(); it_component.Advance()) {
+ base::Value* sub_component = nullptr;
+ CHECK(sub_components->Get(it_component.key(), &sub_component));
+ if (sub_component->GetType() == base::Value::TYPE_LIST) {
+ base::ListValue* component_array = nullptr;
+ CHECK(sub_component->GetAsList(&component_array));
+ for (base::Value* item : *component_array) {
+ CHECK(item->GetAsDictionary(&component));
+ RemoveInaccessibleState(manager, component, role);
+ }
+ } else if (sub_component->GetType() == base::Value::TYPE_DICTIONARY) {
+ CHECK(sub_component->GetAsDictionary(&component));
+ RemoveInaccessibleState(manager, component, role);
+ }
+ }
+ }
+}
+
} // anonymous namespace
template <>
@@ -230,7 +284,7 @@ std::unique_ptr<CommandInstance> ComponentManagerImpl::ParseCommandInstance(
return nullptr;
UserRole minimal_role;
- if (!GetMinimalRole(command_instance->GetName(), &minimal_role, error))
+ if (!GetCommandMinimalRole(command_instance->GetName(), &minimal_role, error))
return nullptr;
if (role < minimal_role) {
@@ -346,9 +400,24 @@ const base::DictionaryValue* ComponentManagerImpl::FindCommandDefinition(
return definition;
}
-bool ComponentManagerImpl::GetMinimalRole(const std::string& command_name,
- UserRole* minimal_role,
- ErrorPtr* error) const {
+const base::DictionaryValue* ComponentManagerImpl::FindStateDefinition(
+ const std::string& state_property_name) const {
+ const base::DictionaryValue* definition = nullptr;
+ std::vector<std::string> components =
+ Split(state_property_name, ".", true, false);
+ // Make sure the |state_property_name| came in form of trait_name.state_name.
+ if (components.size() != 2)
+ return definition;
+ std::string key = base::StringPrintf("%s.state.%s", components[0].c_str(),
+ components[1].c_str());
+ traits_.GetDictionary(key, &definition);
+ return definition;
+}
+
+bool ComponentManagerImpl::GetCommandMinimalRole(
+ const std::string& command_name,
+ UserRole* minimal_role,
+ ErrorPtr* error) const {
const base::DictionaryValue* command = FindCommandDefinition(command_name);
if (!command) {
return Error::AddToPrintf(
@@ -363,12 +432,47 @@ bool ComponentManagerImpl::GetMinimalRole(const std::string& command_name,
return true;
}
+bool ComponentManagerImpl::GetStateMinimalRole(
+ const std::string& state_property_name,
+ UserRole* minimal_role,
+ ErrorPtr* error) const {
+ const base::DictionaryValue* state = FindStateDefinition(state_property_name);
+ if (!state) {
+ return Error::AddToPrintf(
+ error, FROM_HERE, errors::commands::kInvalidState,
+ "State definition for '%s' not found", state_property_name.c_str());
+ }
+ std::string value;
+ if (state->GetString(kMinimalRole, &value)) {
+ CHECK(StringToEnum(value, minimal_role));
+ } else {
+ *minimal_role = UserRole::kUser;
+ }
+ return true;
+}
+
void ComponentManagerImpl::AddStateChangedCallback(
const base::Closure& callback) {
on_state_changed_.push_back(callback);
callback.Run(); // Force to read current state.
}
+std::unique_ptr<base::DictionaryValue>
+ComponentManagerImpl::GetComponentsForUserRole(UserRole role) const {
+ std::unique_ptr<base::DictionaryValue> components{components_.DeepCopy()};
+ // Build a list of all state properties that are inaccessible to the given
+ // user. These properties will be removed from the components collection
+ // returned from this method.
+ for (base::DictionaryValue::Iterator it_component(components_);
+ !it_component.IsAtEnd(); it_component.Advance()) {
+ base::DictionaryValue* component = nullptr;
+ CHECK(components->GetDictionary(it_component.key(), &component));
+ RemoveInaccessibleState(this, component, role);
+ }
+
+ return components;
+}
+
bool ComponentManagerImpl::SetStateProperties(const std::string& component_path,
const base::DictionaryValue& dict,
ErrorPtr* error) {