Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(193)

Unified Diff: chrome/browser/chromeos/network_settings/onc_validator.cc

Issue 11415148: Adding error handling to ONC validation. (Closed) Base URL: http://git.chromium.org/chromium/src.git@extract_onc_certificate
Patch Set: Initial patch. Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/network_settings/onc_validator.cc
diff --git a/chrome/browser/chromeos/network_settings/onc_validator.cc b/chrome/browser/chromeos/network_settings/onc_validator.cc
index ec4922797a060dbcef90e6a6490000da59e9260f..dbbc548db3c7bbdd2d0f9ba3bea60d8ea3a7658e 100644
--- a/chrome/browser/chromeos/network_settings/onc_validator.cc
+++ b/chrome/browser/chromeos/network_settings/onc_validator.cc
@@ -7,15 +7,47 @@
#include <algorithm>
#include <string>
+#include "base/json/json_writer.h"
#include "base/logging.h"
+#include "base/string_number_conversions.h"
#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/chromeos/cros/onc_constants.h"
#include "chrome/browser/chromeos/network_settings/onc_signature.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
namespace chromeos {
namespace onc {
+namespace {
+
+string16 ValueToString(const base::Value& value) {
+ std::string json;
+ base::JSONWriter::Write(&value, &json);
+ return UTF8ToUTF16(json);
+}
+
+// Copied from policy/configuration_policy_handler.cc.
+// TODO(pneubeck): move to a common place like base/.
+string16 ValueTypeToString(Value::Type type) {
+ static const char* strings[] = {
+ "null",
+ "boolean",
+ "integer",
+ "double",
+ "string",
+ "binary",
+ "dictionary",
+ "list"
+ };
+ DCHECK(static_cast<size_t>(type) < arraysize(strings));
+ return ASCIIToUTF16(strings[type]);
+}
+
+} // namespace
+
Validator::Validator(
bool error_on_unknown_field,
bool error_on_wrong_recommended,
@@ -32,29 +64,45 @@ Validator::~Validator() {
scoped_ptr<base::DictionaryValue> Validator::ValidateAndRepairObject(
const OncValueSignature* object_signature,
- const base::DictionaryValue& onc_object) {
+ const base::DictionaryValue& onc_object,
+ std::string* messages) {
CHECK(object_signature != NULL);
+ messages_.clear();
+ bool error = false;
scoped_ptr<base::Value> result_value =
- MapValue(*object_signature, onc_object);
+ MapValue(*object_signature, onc_object, &error);
+ if (error)
+ result_value.reset();
+
base::DictionaryValue* result_dict = NULL;
if (result_value.get() != NULL) {
result_value.release()->GetAsDictionary(&result_dict);
CHECK(result_dict != NULL);
}
+ if (messages)
+ *messages = JoinMessages();
+
return make_scoped_ptr(result_dict);
}
scoped_ptr<base::Value> Validator::MapValue(
const OncValueSignature& signature,
- const base::Value& onc_value) {
+ const base::Value& onc_value,
+ bool* error) {
if (onc_value.GetType() != signature.onc_type) {
DVLOG(1) << "Wrong type. Expected " << signature.onc_type
<< ", but found " << onc_value.GetType();
+ AddError(l10n_util::GetStringFUTF8(
+ IDS_NETWORK_CONFIG_ERROR_VALUE_HAS_WRONG_TYPE,
+ ValueToString(onc_value), ValueTypeToString(signature.onc_type),
+ ValueTypeToString(onc_value.GetType())));
+ *error = true;
return scoped_ptr<base::Value>();
}
- scoped_ptr<base::Value> repaired = Mapper::MapValue(signature, onc_value);
+ scoped_ptr<base::Value> repaired =
+ Mapper::MapValue(signature, onc_value, error);
if (repaired.get() != NULL)
CHECK_EQ(repaired->GetType(), signature.onc_type);
return repaired.Pass();
@@ -62,11 +110,14 @@ scoped_ptr<base::Value> Validator::MapValue(
scoped_ptr<base::DictionaryValue> Validator::MapObject(
const OncValueSignature& signature,
- const base::DictionaryValue& onc_object) {
+ const base::DictionaryValue& onc_object,
+ bool* error) {
scoped_ptr<base::DictionaryValue> repaired(new base::DictionaryValue);
bool valid;
- if (&signature == &kNetworkConfigurationSignature)
+ if (&signature == &kToplevelConfigurationSignature)
+ valid = ValidateToplevelConfiguration(onc_object, repaired.get());
+ else if (&signature == &kNetworkConfigurationSignature)
valid = ValidateNetworkConfiguration(onc_object, repaired.get());
else if (&signature == &kEthernetSignature)
valid = ValidateEthernet(onc_object, repaired.get());
@@ -93,10 +144,51 @@ scoped_ptr<base::DictionaryValue> Validator::MapObject(
else
valid = ValidateObjectDefault(signature, onc_object, repaired.get());
- if (valid)
+ if (valid) {
return repaired.Pass();
- else
+ } else {
+ *error = true;
return scoped_ptr<base::DictionaryValue>();
+ }
+}
+
+scoped_ptr<base::Value> Validator::MapField(
+ const std::string& field_name,
+ const OncValueSignature& object_signature,
+ const base::Value& onc_value,
+ bool* found_unknown_field,
+ bool* error) {
+ path_.push_back(field_name);
+ bool current_field_unknown = false;
+ scoped_ptr<base::Value> result = Mapper::MapField(
+ field_name, object_signature, onc_value, &current_field_unknown, error);
+
+ DCHECK_EQ(field_name, path_.back());
+ path_.pop_back();
+
+ if (current_field_unknown) {
+ *found_unknown_field = true;
+ DVLOG(1) << (error_on_unknown_field_ ? "Error" : "Warning")
+ << ": Unknown field name '" << field_name << "'.";
+ AddMessage(error_on_unknown_field_, l10n_util::GetStringFUTF8(
+ IDS_NETWORK_CONFIG_ERROR_UNKNOWN_FIELD_NAME,
+ UTF8ToUTF16(field_name)));
+ }
+
+ return result.Pass();
+}
+
+scoped_ptr<base::Value> Validator::MapEntry(int index,
+ const OncValueSignature& signature,
+ const base::Value& onc_value,
+ bool* error) {
+ std::string str = base::IntToString(index);
+ path_.push_back(str);
+ scoped_ptr<base::Value> result = Mapper::MapEntry(index, signature,
+ onc_value, error);
+ DCHECK_EQ(str, path_.back());
+ path_.pop_back();
+ return result.Pass();
}
bool Validator::ValidateObjectDefault(
@@ -107,17 +199,15 @@ bool Validator::ValidateObjectDefault(
bool nested_error_occured = false;
MapFields(signature, onc_object, &found_unknown_field, &nested_error_occured,
result);
- if (nested_error_occured)
- return false;
- if (found_unknown_field) {
- if (error_on_unknown_field_) {
- DVLOG(1) << "Unknown field name. Aborting.";
- return false;
- }
- DVLOG(1) << "Unknown field name. Ignoring.";
+ if (found_unknown_field && error_on_unknown_field_) {
+ DVLOG(1) << "Unknown field names are errors: Aborting.";
+ return false;
}
+ if (nested_error_occured)
+ return false;
+
return ValidateRecommendedField(signature, result);
}
@@ -140,8 +230,11 @@ bool Validator::ValidateRecommendedField(
recommended.reset(recommended_list);
if (!managed_onc_) {
+ AddWarning(l10n_util::GetStringFUTF8(
+ IDS_NETWORK_CONFIG_ERROR_UNEXPECTED_FIELD_IN_UNMANAGED_CONFIG,
+ ASCIIToUTF16(onc::kRecommended)));
DVLOG(1) << "Found a " << onc::kRecommended
- << " field in unmanaged ONC. Removing it.";
+ << " field in an unmanaged ONC. Removing it.";
return true;
}
@@ -169,8 +262,11 @@ bool Validator::ValidateRecommendedField(
}
if (found_error) {
+ AddMessage(error_on_wrong_recommended_, l10n_util::GetStringFUTF8(
+ IDS_NETWORK_CONFIG_ERROR_UNKNOWN_FIELD_RECOMMENDED,
+ ASCIIToUTF16(field_name)));
DVLOG(1) << "Found " << error_cause << " field name '" << field_name
- << "' in kRecommended array. "
+ << "' in a " << onc::kRecommended << " array. "
<< (error_on_wrong_recommended_ ? "Aborting." : "Ignoring.");
if (error_on_wrong_recommended_)
return false;
@@ -185,44 +281,42 @@ bool Validator::ValidateRecommendedField(
return true;
}
-namespace {
+bool Validator::ValidateToplevelConfiguration(
+ const base::DictionaryValue& onc_object,
+ base::DictionaryValue* result) {
+ if (!ValidateObjectDefault(kToplevelConfigurationSignature,
+ onc_object, result)) {
+ return false;
+ }
-std::string JoinStringRange(const char** range_begin,
- const char** range_end,
- const std::string& separator) {
- std::vector<std::string> string_vector;
- std::copy(range_begin, range_end, std::back_inserter(string_vector));
- return JoinString(string_vector, separator);
-}
+ static const char* kValidTypes[] =
+ { kUnencryptedConfiguration, kEncryptedConfiguration, NULL };
+ if (FieldExistsAndHasNoValueOf(*result, kType, kValidTypes))
+ return false;
-bool RequireAnyOf(const std::string &actual, const char** valid_values) {
- const char** it = valid_values;
- for (; *it != NULL; ++it) {
- if (actual == *it)
- return true;
- }
- DVLOG(1) << "Found " << actual << ", but expected one of "
- << JoinStringRange(valid_values, it, ", ");
- return false;
-}
+ bool allRequiredExist = true;
-bool IsInRange(int actual, int lower_bound, int upper_bound) {
- if (lower_bound <= actual && actual <= upper_bound)
- return true;
- DVLOG(1) << "Found " << actual << ", which is out of range [" << lower_bound
- << ", " << upper_bound << "]";
- return false;
-}
+ // Not part of the ONC spec yet:
+ // We don't require the type field and default to UnencryptedConfiguration.
+ std::string type = kUnencryptedConfiguration;
+ result->GetStringWithoutPathExpansion(kType, &type);
+ if (type == kUnencryptedConfiguration &&
+ !result->HasKey(kNetworkConfigurations) &&
+ !result->HasKey(kCertificates)) {
+ DVLOG(1) << "Neither " << kNetworkConfigurations << " nor "
+ << kCertificates << " present.";
+
+ AddMessage(error_on_missing_field_,
+ l10n_util::GetStringFUTF8(
+ IDS_NETWORK_CONFIG_ERROR_NETWORKS_OR_CERTS_REQUIRED,
+ ASCIIToUTF16(kNetworkConfigurations),
+ ASCIIToUTF16(kCertificates)));
+ allRequiredExist = false;
+ }
-bool RequireField(const base::DictionaryValue& dict, std::string key) {
- if (dict.HasKey(key))
- return true;
- DVLOG(1) << "Required field " << key << " missing.";
- return false;
+ return !error_on_missing_field_ || allRequiredExist;
}
-} // namespace
-
bool Validator::ValidateNetworkConfiguration(
const base::DictionaryValue& onc_object,
base::DictionaryValue* result) {
@@ -231,12 +325,9 @@ bool Validator::ValidateNetworkConfiguration(
return false;
}
- std::string type;
static const char* kValidTypes[] = { kEthernet, kVPN, kWiFi, NULL };
- if (result->GetStringWithoutPathExpansion(kType, &type) &&
- !RequireAnyOf(type, kValidTypes)) {
+ if (FieldExistsAndHasNoValueOf(*result, kType, kValidTypes))
return false;
- }
bool allRequiredExist = RequireField(*result, kGUID);
@@ -245,6 +336,9 @@ bool Validator::ValidateNetworkConfiguration(
if (!remove) {
allRequiredExist &= RequireField(*result, kName);
allRequiredExist &= RequireField(*result, kType);
+
+ std::string type;
+ result->GetStringWithoutPathExpansion(kType, &type);
allRequiredExist &= type.empty() || RequireField(*result, type);
}
@@ -258,14 +352,15 @@ bool Validator::ValidateEthernet(
if (!ValidateObjectDefault(kEthernetSignature, onc_object, result))
return false;
- std::string auth;
static const char* kValidAuthentications[] = { kNone, k8021X, NULL };
- if (result->GetStringWithoutPathExpansion(kAuthentication, &auth) &&
- !RequireAnyOf(auth, kValidAuthentications)) {
+ if (FieldExistsAndHasNoValueOf(*result, kAuthentication,
+ kValidAuthentications)) {
return false;
}
bool allRequiredExist = true;
+ std::string auth;
+ result->GetStringWithoutPathExpansion(kAuthentication, &auth);
if (auth == k8021X)
allRequiredExist &= RequireField(*result, kEAP);
@@ -279,19 +374,17 @@ bool Validator::ValidateIPConfig(
if (!ValidateObjectDefault(kIPConfigSignature, onc_object, result))
return false;
- std::string type;
static const char* kValidTypes[] = { kIPv4, kIPv6, NULL };
- if (result->GetStringWithoutPathExpansion(ipconfig::kType, &type) &&
- !RequireAnyOf(type, kValidTypes)) {
+ if (FieldExistsAndHasNoValueOf(*result, ipconfig::kType, kValidTypes))
return false;
- }
- int routing_prefix;
+ std::string type;
+ result->GetStringWithoutPathExpansion(ipconfig::kType, &type);
int lower_bound = 1;
// In case of missing type, choose higher upper_bound.
int upper_bound = (type == kIPv4) ? 32 : 128;
- if (result->GetIntegerWithoutPathExpansion(kRoutingPrefix, &routing_prefix) &&
- !IsInRange(routing_prefix, lower_bound, upper_bound)) {
+ if (FieldExistsAndIsNotInRange(*result, kRoutingPrefix,
+ lower_bound, upper_bound)) {
return false;
}
@@ -309,16 +402,16 @@ bool Validator::ValidateWiFi(
if (!ValidateObjectDefault(kWiFiSignature, onc_object, result))
return false;
- std::string security;
static const char* kValidSecurities[] =
{ kNone, kWEP_PSK, kWEP_8021X, kWPA_PSK, kWPA_EAP, NULL };
- if (result->GetStringWithoutPathExpansion(kSecurity, &security) &&
- !RequireAnyOf(security, kValidSecurities)) {
+ if (FieldExistsAndHasNoValueOf(*result, kSecurity, kValidSecurities))
return false;
- }
bool allRequiredExist = RequireField(*result, kSecurity) &
RequireField(*result, kSSID);
+
+ std::string security;
+ result->GetStringWithoutPathExpansion(kSecurity, &security);
if (security == kWEP_8021X || security == kWPA_EAP)
allRequiredExist &= RequireField(*result, kEAP);
else if (security == kWEP_PSK || security == kWPA_PSK)
@@ -334,16 +427,14 @@ bool Validator::ValidateVPN(
if (!ValidateObjectDefault(kVPNSignature, onc_object, result))
return false;
- std::string type;
static const char* kValidTypes[] =
{ kIPsec, kTypeL2TP_IPsec, kOpenVPN, NULL };
- if (result->GetStringWithoutPathExpansion(vpn::kType, &type) &&
- !RequireAnyOf(type, kValidTypes)) {
+ if (FieldExistsAndHasNoValueOf(*result, vpn::kType, kValidTypes))
return false;
- }
bool allRequiredExist = RequireField(*result, vpn::kType);
-
+ std::string type;
+ result->GetStringWithoutPathExpansion(vpn::kType, &type);
if (type == kOpenVPN) {
allRequiredExist &= RequireField(*result, kOpenVPN);
} else if (type == kIPsec) {
@@ -364,26 +455,24 @@ bool Validator::ValidateIPsec(
if (!ValidateObjectDefault(kIPsecSignature, onc_object, result))
return false;
- std::string auth;
static const char* kValidAuthentications[] = { kPSK, kCert, NULL };
- if (result->GetStringWithoutPathExpansion(kAuthenticationType, &auth) &&
- !RequireAnyOf(auth, kValidAuthentications)) {
- return false;
- }
-
- std::string cert_type;
static const char* kValidCertTypes[] = { kRef, kPattern, NULL };
- if (result->GetStringWithoutPathExpansion(kClientCertType, &cert_type) &&
- !RequireAnyOf(cert_type, kValidCertTypes)) {
+ if (FieldExistsAndHasNoValueOf(*result, kAuthenticationType,
+ kValidAuthentications) |
+ FieldExistsAndHasNoValueOf(*result, kClientCertType, kValidCertTypes)) {
return false;
}
bool allRequiredExist = RequireField(*result, kAuthenticationType) &
RequireField(*result, kIKEVersion);
+ std::string auth;
+ result->GetStringWithoutPathExpansion(kAuthenticationType, &auth);
if (auth == kCert) {
allRequiredExist &= RequireField(*result, kClientCertType) &
RequireField(*result, kServerCARef);
}
+ std::string cert_type;
+ result->GetStringWithoutPathExpansion(kClientCertType, &cert_type);
if (cert_type == kPattern)
allRequiredExist &= RequireField(*result, kClientCertPattern);
else if (cert_type == kRef)
@@ -401,31 +490,23 @@ bool Validator::ValidateOpenVPN(
if (!ValidateObjectDefault(kOpenVPNSignature, onc_object, result))
return false;
- std::string auth_retry;
static const char* kValidAuthRetryValues[] =
{ openvpn::kNone, kInteract, kNoInteract, NULL };
- if (result->GetStringWithoutPathExpansion(kAuthRetry, &auth_retry) &&
- !RequireAnyOf(auth_retry, kValidAuthRetryValues)) {
- return false;
- }
-
- std::string cert_type;
static const char* kValidCertTypes[] =
{ certificate::kNone, kRef, kPattern, NULL };
- if (result->GetStringWithoutPathExpansion(kClientCertType, &cert_type) &&
- !RequireAnyOf(cert_type, kValidCertTypes)) {
- return false;
- }
-
- std::string cert_tls;
static const char* kValidCertTlsValues[] =
{ openvpn::kNone, openvpn::kServer, NULL };
- if (result->GetStringWithoutPathExpansion(kRemoteCertTLS, &cert_tls) &&
- !RequireAnyOf(cert_tls, kValidCertTlsValues)) {
+
+ if (FieldExistsAndHasNoValueOf(*result, kAuthRetry, kValidAuthRetryValues) |
+ FieldExistsAndHasNoValueOf(*result, kClientCertType, kValidCertTypes) |
+ FieldExistsAndHasNoValueOf(*result, kRemoteCertTLS,
+ kValidCertTlsValues)) {
return false;
}
bool allRequiredExist = RequireField(*result, kClientCertType);
+ std::string cert_type;
+ result->GetStringWithoutPathExpansion(kClientCertType, &cert_type);
if (cert_type == kPattern)
allRequiredExist &= RequireField(*result, kClientCertPattern);
else if (cert_type == kRef)
@@ -458,15 +539,13 @@ bool Validator::ValidateProxySettings(const base::DictionaryValue& onc_object,
if (!ValidateObjectDefault(kProxySettingsSignature, onc_object, result))
return false;
- std::string type;
static const char* kValidTypes[] = { kDirect, kManual, kPAC, kWPAD, NULL };
- if (result->GetStringWithoutPathExpansion(proxy::kType, &type) &&
- !RequireAnyOf(type, kValidTypes)) {
+ if (FieldExistsAndHasNoValueOf(*result, proxy::kType, kValidTypes))
return false;
- }
bool allRequiredExist = RequireField(*result, proxy::kType);
-
+ std::string type;
+ result->GetStringWithoutPathExpansion(proxy::kType, &type);
if (type == kManual)
allRequiredExist &= RequireField(*result, kManual);
else if (type == kPAC)
@@ -494,32 +573,22 @@ bool Validator::ValidateEAP(const base::DictionaryValue& onc_object,
if (!ValidateObjectDefault(kEAPSignature, onc_object, result))
return false;
- std::string inner;
static const char* kValidInnerValues[] =
{ kAutomatic, kMD5, kMSCHAPv2, kPAP, NULL };
- if (result->GetStringWithoutPathExpansion(kInner, &inner) &&
- !RequireAnyOf(inner, kValidInnerValues)) {
- return false;
- }
-
- std::string outer;
static const char* kValidOuterValues[] =
{ kPEAP, kEAP_TLS, kEAP_TTLS, kLEAP, kEAP_SIM, kEAP_FAST, kEAP_AKA,
NULL };
- if (result->GetStringWithoutPathExpansion(kOuter, &outer) &&
- !RequireAnyOf(outer, kValidOuterValues)) {
- return false;
- }
-
- std::string cert_type;
static const char* kValidCertTypes[] = { kRef, kPattern, NULL };
- if (result->GetStringWithoutPathExpansion(kClientCertType, &cert_type) &&
- !RequireAnyOf(cert_type, kValidCertTypes )) {
+
+ if (FieldExistsAndHasNoValueOf(*result, kInner, kValidInnerValues) |
+ FieldExistsAndHasNoValueOf(*result, kOuter, kValidOuterValues) |
+ FieldExistsAndHasNoValueOf(*result, kClientCertType, kValidCertTypes)) {
return false;
}
bool allRequiredExist = RequireField(*result, kOuter);
-
+ std::string cert_type;
+ result->GetStringWithoutPathExpansion(kClientCertType, &cert_type);
if (cert_type == kPattern)
allRequiredExist &= RequireField(*result, kClientCertPattern);
else if (cert_type == kRef)
@@ -535,12 +604,9 @@ bool Validator::ValidateCertificate(
if (!ValidateObjectDefault(kCertificateSignature, onc_object, result))
return false;
- std::string type;
static const char* kValidTypes[] = { kClient, kServer, kAuthority, NULL };
- if (result->GetStringWithoutPathExpansion(certificate::kType, &type) &&
- !RequireAnyOf(type, kValidTypes)) {
+ if (FieldExistsAndHasNoValueOf(*result, certificate::kType, kValidTypes))
return false;
- }
bool allRequiredExist = RequireField(*result, kGUID);
@@ -549,6 +615,8 @@ bool Validator::ValidateCertificate(
if (!remove) {
allRequiredExist &= RequireField(*result, certificate::kType);
+ std::string type;
+ result->GetStringWithoutPathExpansion(certificate::kType, &type);
if (type == kClient)
allRequiredExist &= RequireField(*result, kPKCS12);
else if (type == kServer || type == kAuthority)
@@ -558,5 +626,105 @@ bool Validator::ValidateCertificate(
return !error_on_missing_field_ || allRequiredExist;
}
+namespace {
+
+std::string JoinStringRange(const char** range_begin,
+ const char** range_end,
+ const std::string& separator) {
+ std::vector<std::string> string_vector;
+ std::copy(range_begin, range_end, std::back_inserter(string_vector));
+ return JoinString(string_vector, separator);
+}
+
+} // namespace
+
+bool Validator::FieldExistsAndHasNoValueOf(const base::DictionaryValue& object,
+ const std::string &field_name,
+ const char** valid_values) {
+ std::string actual_value;
+ if (!object.GetStringWithoutPathExpansion(field_name, &actual_value))
+ return false;
+
+ const char** it = valid_values;
+ for (; *it != NULL; ++it) {
+ if (actual_value == *it)
+ return false;
+ }
+ std::string valid_values_str =
+ "[" + JoinStringRange(valid_values, it, ", ") + "]";
+ path_.push_back(field_name);
+ AddError(l10n_util::GetStringFUTF8(
+ IDS_NETWORK_CONFIG_ERROR_INVALID_VALUE,
+ UTF8ToUTF16(actual_value),
+ UTF8ToUTF16(valid_values_str)));
+ path_.pop_back();
+ DVLOG(1) << "Found " << actual_value << ", but expected one of "
+ << valid_values_str;
+ return true;
+}
+
+bool Validator::FieldExistsAndIsNotInRange(const base::DictionaryValue& object,
+ const std::string &field_name,
+ int lower_bound,
+ int upper_bound) {
+ int actual_value;
+ if (!object.GetIntegerWithoutPathExpansion(field_name, &actual_value))
+ return false;
+
+ if (lower_bound <= actual_value && actual_value <= upper_bound)
+ return false;
+ path_.push_back(field_name);
+ AddError(l10n_util::GetStringFUTF8(
+ IDS_NETWORK_CONFIG_ERROR_VALUE_OUT_OF_RANGE,
+ base::IntToString16(actual_value),
+ base::IntToString16(lower_bound),
+ base::IntToString16(upper_bound)));
+ path_.pop_back();
+ DVLOG(1) << "Found " << actual_value << ", which is out of range ["
+ << lower_bound << ", " << upper_bound << "]";
+ return true;
+}
+
+bool Validator::RequireField(const base::DictionaryValue& dict,
+ const std::string& field_name) {
+ if (dict.HasKey(field_name))
+ return true;
+ AddError(l10n_util::GetStringFUTF8(
+ IDS_NETWORK_CONFIG_ERROR_REQUIRED_FIELD_MISSING,
+ UTF8ToUTF16(field_name)));
+ DVLOG(1) << "Required field " << field_name << " missing.";
+ return false;
+}
+
+void Validator::AddWarning(const std::string& msg) {
+ AddMessage(false, msg);
+}
+
+void Validator::AddError(const std::string& msg) {
+ AddMessage(true, msg);
+}
+
+void Validator::AddMessage(bool is_error, const std::string& sub_message) {
+ std::string message;
+ if (path_.empty()) {
+ int message_id = is_error ? IDS_NETWORK_CONFIG_ERROR_AT_TOPLEVEL
+ : IDS_NETWORK_CONFIG_WARNING_AT_TOPLEVEL;
+ message = l10n_util::GetStringUTF8(message_id);
+ } else {
+ int message_id = is_error ?
+ IDS_NETWORK_CONFIG_ERROR_AT_PATH :
+ IDS_NETWORK_CONFIG_WARNING_AT_PATH;
+ message = l10n_util::GetStringFUTF8(message_id,
+ ASCIIToUTF16(JoinString(path_, ".")));
+ }
+ message.append(" ");
+ message.append(sub_message);
+ messages_.push_back(message);
+}
+
+std::string Validator::JoinMessages() {
+ return JoinString(messages_, "\n");
+}
+
} // namespace onc
} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698