blob: 1b6a3db52d25ab0bdabf93b9bcc1665d60b84880 [file] [log] [blame]
// Copyright 2017 The Chromium 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 "content/browser/origin_manifest/origin_manifest_parser.h"
#include "base/json/json_reader.h"
#include "base/strings/string_util.h"
namespace content {
namespace origin_manifest_parser {
std::unique_ptr<blink::OriginManifest> Parse(std::string json) {
// TODO throw some meaningful errors when parsing does not go well
std::unique_ptr<base::DictionaryValue> directives_dict =
base::DictionaryValue::From(
base::JSONReader::Read(json, base::JSON_ALLOW_TRAILING_COMMAS));
std::unique_ptr<blink::OriginManifest> origin_manifest;
// TODO(dhausknecht) that's playing safe. But we should do something to tell
// things went wrong here.
if (!directives_dict)
return origin_manifest;
origin_manifest.reset(new blink::OriginManifest());
for (base::detail::dict_iterator_proxy::iterator it =
directives_dict->DictItems().begin();
it != directives_dict->DictItems().end(); ++it) {
switch (GetDirectiveType(it->first)) {
// content-security-policy
case DirectiveType::kContentSecurityPolicy:
ParseContentSecurityPolicy(origin_manifest.get(),
std::move(it->second));
break;
case DirectiveType::kUnknown:
// Ignore unknown directives for forward-compatibility
break;
}
}
return origin_manifest;
}
DirectiveType GetDirectiveType(const std::string& name) {
if (name == "content-security-policy") {
return DirectiveType::kContentSecurityPolicy;
}
return DirectiveType::kUnknown;
}
void ParseContentSecurityPolicy(blink::OriginManifest* const om,
base::Value value) {
// TODO give respective parsing errors
if (!value.is_list())
return;
for (auto& elem : value.GetList()) {
if (!elem.is_dict())
continue;
std::string policy = "";
blink::OriginManifest::ContentSecurityPolicyType disposition =
blink::OriginManifest::ContentSecurityPolicyType::kEnforce;
blink::OriginManifest::ActivationType activation_type =
blink::OriginManifest::ActivationType::kFallback;
const base::Value* v = elem.FindKey("policy");
if (v && v->is_string())
policy = v->GetString();
v = elem.FindKey("disposition");
if (v && v->is_string())
disposition = GetCSPDisposition(v->GetString());
v = elem.FindKey("allow-override");
if (v && v->is_bool()) {
activation_type = GetCSPActivationType(v->GetBool());
}
om->AddContentSecurityPolicy(policy, disposition, activation_type);
}
}
blink::OriginManifest::ContentSecurityPolicyType GetCSPDisposition(
const std::string& name) {
if (name == "enforce")
return blink::OriginManifest::ContentSecurityPolicyType::kEnforce;
if (name == "report-only")
return blink::OriginManifest::ContentSecurityPolicyType::kReport;
return blink::OriginManifest::ContentSecurityPolicyType::kEnforce;
}
blink::OriginManifest::ActivationType GetCSPActivationType(const bool value) {
if (value)
return blink::OriginManifest::ActivationType::kBaseline;
return blink::OriginManifest::ActivationType::kFallback;
}
} // namespace origin_manifest_parser
} // namespace content