summaryrefslogtreecommitdiffstats
path: root/chromeos/network/onc/onc_merger.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromeos/network/onc/onc_merger.cc')
-rw-r--r--chromeos/network/onc/onc_merger.cc201
1 files changed, 152 insertions, 49 deletions
diff --git a/chromeos/network/onc/onc_merger.cc b/chromeos/network/onc/onc_merger.cc
index 8403f91..e7703d3 100644
--- a/chromeos/network/onc/onc_merger.cc
+++ b/chromeos/network/onc/onc_merger.cc
@@ -12,6 +12,7 @@
#include "base/logging.h"
#include "base/values.h"
#include "chromeos/network/onc/onc_constants.h"
+#include "chromeos/network/onc/onc_signature.h"
namespace chromeos {
namespace onc {
@@ -96,7 +97,7 @@ class MergeListOfDictionaries {
(*it_inner)->GetDictionaryWithoutPathExpansion(key, &nested_dict);
nested_dicts.push_back(nested_dict);
}
- DictionaryPtr merged_dict(MergeDictionaries(nested_dicts));
+ DictionaryPtr merged_dict(MergeNestedDictionaries(key, nested_dicts));
if (!merged_dict->empty())
merged_value = merged_dict.Pass();
} else {
@@ -108,7 +109,7 @@ class MergeListOfDictionaries {
(*it_inner)->GetWithoutPathExpansion(key, &value);
values.push_back(value);
}
- merged_value = MergeListOfValues(values);
+ merged_value = MergeListOfValues(key, values);
}
if (merged_value)
@@ -124,8 +125,14 @@ class MergeListOfDictionaries {
// values is the same as of the given dictionaries |dicts|. If a dictionary
// doesn't contain a path then it's value is NULL.
virtual scoped_ptr<base::Value> MergeListOfValues(
+ const std::string& key,
const std::vector<const base::Value*>& values) = 0;
+ virtual DictionaryPtr MergeNestedDictionaries(const std::string& key,
+ const DictPtrs &dicts) {
+ return MergeDictionaries(dicts);
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(MergeListOfDictionaries);
};
@@ -136,12 +143,15 @@ class MergeSettingsAndPolicies : public MergeListOfDictionaries {
struct ValueParams {
const base::Value* user_policy;
const base::Value* device_policy;
- const base::Value* user_settings;
- const base::Value* shared_settings;
+ const base::Value* user_setting;
+ const base::Value* shared_setting;
+ const base::Value* active_setting;
bool user_editable;
bool device_editable;
};
+ MergeSettingsAndPolicies() {}
+
// Merge the provided dictionaries. For each path in any of the dictionaries,
// MergeValues is called. Its results are collected in a new dictionary which
// is then returned. The resulting dictionary never contains empty
@@ -150,7 +160,8 @@ class MergeSettingsAndPolicies : public MergeListOfDictionaries {
const base::DictionaryValue* user_policy,
const base::DictionaryValue* device_policy,
const base::DictionaryValue* user_settings,
- const base::DictionaryValue* shared_settings) {
+ const base::DictionaryValue* shared_settings,
+ const base::DictionaryValue* active_settings) {
hasUserPolicy_ = (user_policy != NULL);
hasDevicePolicy_ = (device_policy != NULL);
@@ -167,6 +178,7 @@ class MergeSettingsAndPolicies : public MergeListOfDictionaries {
dicts[kDevicePolicyIndex] = device_policy;
dicts[kUserSettingsIndex] = user_settings;
dicts[kSharedSettingsIndex] = shared_settings;
+ dicts[kActiveSettingsIndex] = active_settings;
dicts[kUserEditableIndex] = user_editable.get();
dicts[kDeviceEditableIndex] = device_editable.get();
return MergeListOfDictionaries::MergeDictionaries(dicts);
@@ -176,7 +188,8 @@ class MergeSettingsAndPolicies : public MergeListOfDictionaries {
// This function is called by MergeDictionaries for each list of values that
// are located at the same path in each of the dictionaries. Implementations
// can use the Has*Policy functions.
- virtual scoped_ptr<base::Value> MergeValues(ValueParams values) = 0;
+ virtual scoped_ptr<base::Value> MergeValues(const std::string& key,
+ const ValueParams& values) = 0;
// Whether a user policy was provided.
bool HasUserPolicy() {
@@ -190,6 +203,7 @@ class MergeSettingsAndPolicies : public MergeListOfDictionaries {
// MergeListOfDictionaries override.
virtual scoped_ptr<base::Value> MergeListOfValues(
+ const std::string& key,
const std::vector<const base::Value*>& values) OVERRIDE {
bool user_editable = !HasUserPolicy();
if (values[kUserEditableIndex])
@@ -202,11 +216,12 @@ class MergeSettingsAndPolicies : public MergeListOfDictionaries {
ValueParams params;
params.user_policy = values[kUserPolicyIndex];
params.device_policy = values[kDevicePolicyIndex];
- params.user_settings = values[kUserSettingsIndex];
- params.shared_settings = values[kSharedSettingsIndex];
+ params.user_setting = values[kUserSettingsIndex];
+ params.shared_setting = values[kSharedSettingsIndex];
+ params.active_setting = values[kActiveSettingsIndex];
params.user_editable = user_editable;
params.device_editable = device_editable;
- return MergeValues(params);
+ return MergeValues(key, params);
}
private:
@@ -215,17 +230,24 @@ class MergeSettingsAndPolicies : public MergeListOfDictionaries {
kDevicePolicyIndex,
kUserSettingsIndex,
kSharedSettingsIndex,
+ kActiveSettingsIndex,
kUserEditableIndex,
kDeviceEditableIndex,
kLastIndex
};
bool hasUserPolicy_, hasDevicePolicy_;
+
+ DISALLOW_COPY_AND_ASSIGN(MergeSettingsAndPolicies);
};
// Call MergeDictionaries to merge policies and settings to the effective
-// values. See the description of MergeSettingsAndPoliciesToEffective.
+// values. This ignores the active settings of Shill. See the description of
+// MergeSettingsAndPoliciesToEffective.
class MergeToEffective : public MergeSettingsAndPolicies {
+ public:
+ MergeToEffective() {}
+
protected:
// Merges |values| to the effective value (Mandatory policy overwrites user
// settings overwrites shared settings overwrites recommended policy). |which|
@@ -234,7 +256,9 @@ class MergeToEffective : public MergeSettingsAndPolicies {
// pointer and set |which| to kAugmentationUserPolicy, which means that the
// user policy didn't set a value but also didn't recommend it, thus enforcing
// the empty value.
- scoped_ptr<base::Value> MergeValues(ValueParams values, std::string* which) {
+ scoped_ptr<base::Value> MergeValues(const std::string& key,
+ const ValueParams& values,
+ std::string* which) {
const base::Value* result = NULL;
which->clear();
if (!values.user_editable) {
@@ -243,11 +267,11 @@ class MergeToEffective : public MergeSettingsAndPolicies {
} else if (!values.device_editable) {
result = values.device_policy;
*which = kAugmentationDevicePolicy;
- } else if (values.user_settings) {
- result = values.user_settings;
+ } else if (values.user_setting) {
+ result = values.user_setting;
*which = kAugmentationUserSetting;
- } else if (values.shared_settings) {
- result = values.shared_settings;
+ } else if (values.shared_setting) {
+ result = values.shared_setting;
*which = kAugmentationSharedSetting;
} else if (values.user_policy) {
result = values.user_policy;
@@ -266,53 +290,129 @@ class MergeToEffective : public MergeSettingsAndPolicies {
// MergeSettingsAndPolicies override.
virtual scoped_ptr<base::Value> MergeValues(
- ValueParams values) OVERRIDE {
+ const std::string& key,
+ const ValueParams& values) OVERRIDE {
std::string which;
- return MergeValues(values, &which);
+ return MergeValues(key, values, &which);
}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MergeToEffective);
};
// Call MergeDictionaries to merge policies and settings to an augmented
// dictionary which contains a dictionary for each value in the original
// dictionaries. See the description of MergeSettingsAndPoliciesToAugmented.
class MergeToAugmented : public MergeToEffective {
+ public:
+ MergeToAugmented() {}
+
+ DictionaryPtr MergeDictionaries(
+ const OncValueSignature& signature,
+ const base::DictionaryValue* user_policy,
+ const base::DictionaryValue* device_policy,
+ const base::DictionaryValue* user_settings,
+ const base::DictionaryValue* shared_settings,
+ const base::DictionaryValue* active_settings) {
+ signature_ = &signature;
+ return MergeToEffective::MergeDictionaries(user_policy,
+ device_policy,
+ user_settings,
+ shared_settings,
+ active_settings);
+ }
+
protected:
// MergeSettingsAndPolicies override.
virtual scoped_ptr<base::Value> MergeValues(
- ValueParams values) OVERRIDE {
+ const std::string& key,
+ const ValueParams& values) OVERRIDE {
scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue);
- std::string which_effective;
- MergeToEffective::MergeValues(values, &which_effective).reset();
- if (!which_effective.empty()) {
- result->SetStringWithoutPathExpansion(kAugmentationEffectiveSetting,
- which_effective);
- }
- if (values.user_policy) {
- result->SetWithoutPathExpansion(kAugmentationUserPolicy,
- values.user_policy->DeepCopy());
- }
- if (values.device_policy) {
- result->SetWithoutPathExpansion(kAugmentationDevicePolicy,
- values.device_policy->DeepCopy());
- }
- if (values.user_settings) {
- result->SetWithoutPathExpansion(kAugmentationUserSetting,
- values.user_settings->DeepCopy());
- }
- if (values.shared_settings) {
- result->SetWithoutPathExpansion(kAugmentationSharedSetting,
- values.shared_settings->DeepCopy());
+ if (values.active_setting) {
+ result->SetWithoutPathExpansion(kAugmentationActiveSetting,
+ values.active_setting->DeepCopy());
}
- if (HasUserPolicy() && values.user_editable) {
- result->SetBooleanWithoutPathExpansion(kAugmentationUserEditable,
- values.user_editable);
- }
- if (HasDevicePolicy() && values.device_editable) {
- result->SetBooleanWithoutPathExpansion(kAugmentationDeviceEditable,
- values.device_editable);
+
+ const OncFieldSignature* field = NULL;
+ if (signature_)
+ field = GetFieldSignature(*signature_, key);
+
+ if (field) {
+ // This field is part of the provided ONCSignature, thus it can be
+ // controlled by policy.
+ std::string which_effective;
+ MergeToEffective::MergeValues(key, values, &which_effective).reset();
+ if (!which_effective.empty()) {
+ result->SetStringWithoutPathExpansion(kAugmentationEffectiveSetting,
+ which_effective);
+ }
+ bool is_credential = onc::FieldIsCredential(*signature_, key);
+
+ // Prevent credentials from being forwarded in cleartext to
+ // UI. User/shared credentials are not stored separately, so they cannot
+ // leak here.
+ if (!is_credential) {
+ if (values.user_policy) {
+ result->SetWithoutPathExpansion(kAugmentationUserPolicy,
+ values.user_policy->DeepCopy());
+ }
+ if (values.device_policy) {
+ result->SetWithoutPathExpansion(kAugmentationDevicePolicy,
+ values.device_policy->DeepCopy());
+ }
+ }
+ if (values.user_setting) {
+ result->SetWithoutPathExpansion(kAugmentationUserSetting,
+ values.user_setting->DeepCopy());
+ }
+ if (values.shared_setting) {
+ result->SetWithoutPathExpansion(kAugmentationSharedSetting,
+ values.shared_setting->DeepCopy());
+ }
+ if (HasUserPolicy() && values.user_editable) {
+ result->SetBooleanWithoutPathExpansion(kAugmentationUserEditable,
+ true);
+ }
+ if (HasDevicePolicy() && values.device_editable) {
+ result->SetBooleanWithoutPathExpansion(kAugmentationDeviceEditable,
+ true);
+ }
+ } else {
+ // This field is not part of the provided ONCSignature, thus it cannot be
+ // controlled by policy.
+ result->SetStringWithoutPathExpansion(kAugmentationEffectiveSetting,
+ kAugmentationUnmanaged);
}
+ if (result->empty())
+ result.reset();
return result.PassAs<base::Value>();
}
+
+ // MergeListOfDictionaries override.
+ virtual DictionaryPtr MergeNestedDictionaries(
+ const std::string& key,
+ const DictPtrs &dicts) OVERRIDE {
+ DictionaryPtr result;
+ if (signature_) {
+ const OncValueSignature* enclosing_signature = signature_;
+ signature_ = NULL;
+
+ const OncFieldSignature* field =
+ GetFieldSignature(*enclosing_signature, key);
+ if (field)
+ signature_ = field->value_signature;
+ result = MergeToEffective::MergeNestedDictionaries(key, dicts);
+
+ signature_ = enclosing_signature;
+ } else {
+ result = MergeToEffective::MergeNestedDictionaries(key, dicts);
+ }
+ return result.Pass();
+ }
+
+ private:
+ const OncValueSignature* signature_;
+ DISALLOW_COPY_AND_ASSIGN(MergeToAugmented);
};
} // namespace
@@ -324,17 +424,20 @@ DictionaryPtr MergeSettingsAndPoliciesToEffective(
const base::DictionaryValue* shared_settings) {
MergeToEffective merger;
return merger.MergeDictionaries(
- user_policy, device_policy, user_settings, shared_settings);
+ user_policy, device_policy, user_settings, shared_settings, NULL);
}
DictionaryPtr MergeSettingsAndPoliciesToAugmented(
+ const OncValueSignature& signature,
const base::DictionaryValue* user_policy,
const base::DictionaryValue* device_policy,
const base::DictionaryValue* user_settings,
- const base::DictionaryValue* shared_settings) {
+ const base::DictionaryValue* shared_settings,
+ const base::DictionaryValue* active_settings) {
MergeToAugmented merger;
return merger.MergeDictionaries(
- user_policy, device_policy, user_settings, shared_settings);
+ signature, user_policy, device_policy, user_settings, shared_settings,
+ active_settings);
}
} // namespace onc