1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/extensions/api/messaging/native_messaging_policy_handler.h"
6
7#include "base/logging.h"
8#include "base/prefs/pref_value_map.h"
9#include "chrome/browser/extensions/api/messaging/native_messaging_host_manifest.h"
10#include "chrome/browser/extensions/external_policy_loader.h"
11#include "chrome/common/pref_names.h"
12#include "components/policy/core/browser/policy_error_map.h"
13#include "components/policy/core/common/policy_map.h"
14#include "grit/components_strings.h"
15#include "policy/policy_constants.h"
16
17namespace extensions {
18
19NativeMessagingHostListPolicyHandler::NativeMessagingHostListPolicyHandler(
20    const char* policy_name,
21    const char* pref_path,
22    bool allow_wildcards)
23    : policy::TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST),
24      pref_path_(pref_path),
25      allow_wildcards_(allow_wildcards) {}
26
27NativeMessagingHostListPolicyHandler::~NativeMessagingHostListPolicyHandler() {}
28
29bool NativeMessagingHostListPolicyHandler::CheckPolicySettings(
30    const policy::PolicyMap& policies,
31    policy::PolicyErrorMap* errors) {
32  return CheckAndGetList(policies, errors, NULL);
33}
34
35void NativeMessagingHostListPolicyHandler::ApplyPolicySettings(
36    const policy::PolicyMap& policies,
37    PrefValueMap* prefs) {
38  scoped_ptr<base::ListValue> list;
39  policy::PolicyErrorMap errors;
40  if (CheckAndGetList(policies, &errors, &list) && list)
41    prefs->SetValue(pref_path(), list.release());
42}
43
44const char* NativeMessagingHostListPolicyHandler::pref_path() const {
45  return pref_path_;
46}
47
48bool NativeMessagingHostListPolicyHandler::CheckAndGetList(
49    const policy::PolicyMap& policies,
50    policy::PolicyErrorMap* errors,
51    scoped_ptr<base::ListValue>* names) {
52  const base::Value* value = NULL;
53  if (!CheckAndGetValue(policies, errors, &value))
54    return false;
55
56  if (!value)
57    return true;
58
59  const base::ListValue* list_value = NULL;
60  if (!value->GetAsList(&list_value)) {
61    NOTREACHED();
62    return false;
63  }
64
65  // Filter the list, rejecting any invalid native messaging host names.
66  scoped_ptr<base::ListValue> filtered_list(new base::ListValue());
67  for (base::ListValue::const_iterator entry(list_value->begin());
68       entry != list_value->end(); ++entry) {
69    std::string name;
70    if (!(*entry)->GetAsString(&name)) {
71      errors->AddError(policy_name(),
72                       entry - list_value->begin(),
73                       IDS_POLICY_TYPE_ERROR,
74                       ValueTypeToString(base::Value::TYPE_STRING));
75      continue;
76    }
77    if (!(allow_wildcards_ && name == "*") &&
78        !NativeMessagingHostManifest::IsValidName(name)) {
79      errors->AddError(policy_name(),
80                       entry - list_value->begin(),
81                       IDS_POLICY_VALUE_FORMAT_ERROR);
82      continue;
83    }
84    filtered_list->Append(new base::StringValue(name));
85  }
86
87  if (names)
88    *names = filtered_list.Pass();
89
90  return true;
91}
92
93}  // namespace extensions
94