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/policy/managed_bookmarks_policy_handler.h"
6
7#include "base/prefs/pref_value_map.h"
8#include "base/values.h"
9#include "components/bookmarks/common/bookmark_pref_names.h"
10#include "components/policy/core/browser/managed_bookmarks_tracker.h"
11#include "components/policy/core/browser/policy_error_map.h"
12#include "components/policy/core/common/policy_map.h"
13#include "components/url_fixer/url_fixer.h"
14#include "policy/policy_constants.h"
15#include "url/gurl.h"
16
17namespace policy {
18
19ManagedBookmarksPolicyHandler::ManagedBookmarksPolicyHandler(
20    Schema chrome_schema)
21    : SchemaValidatingPolicyHandler(
22          key::kManagedBookmarks,
23          chrome_schema.GetKnownProperty(key::kManagedBookmarks),
24          SCHEMA_ALLOW_INVALID) {}
25
26ManagedBookmarksPolicyHandler::~ManagedBookmarksPolicyHandler() {}
27
28void ManagedBookmarksPolicyHandler::ApplyPolicySettings(
29    const PolicyMap& policies,
30    PrefValueMap* prefs) {
31  scoped_ptr<base::Value> value;
32  if (!CheckAndGetValue(policies, NULL, &value))
33    return;
34
35  base::ListValue* list = NULL;
36  if (!value || !value->GetAsList(&list))
37    return;
38
39  FilterBookmarks(list);
40  prefs->SetValue(bookmarks::prefs::kManagedBookmarks, value.release());
41}
42
43void ManagedBookmarksPolicyHandler::FilterBookmarks(base::ListValue* list) {
44  // Remove any non-conforming values found.
45  base::ListValue::iterator it = list->begin();
46  while (it != list->end()) {
47    base::DictionaryValue* dict = NULL;
48    if (!*it || !(*it)->GetAsDictionary(&dict)) {
49      it = list->Erase(it, NULL);
50      continue;
51    }
52
53    std::string name;
54    std::string url;
55    base::ListValue* children = NULL;
56    // Every bookmark must have a name, and then either a URL of a list of
57    // child bookmarks.
58    if (!dict->GetString(ManagedBookmarksTracker::kName, &name) ||
59        (!dict->GetList(ManagedBookmarksTracker::kChildren, &children) &&
60         !dict->GetString(ManagedBookmarksTracker::kUrl, &url))) {
61      it = list->Erase(it, NULL);
62      continue;
63    }
64
65    if (children) {
66      // Ignore the URL if this bookmark has child nodes.
67      dict->Remove(ManagedBookmarksTracker::kUrl, NULL);
68      FilterBookmarks(children);
69    } else {
70      // Make sure the URL is valid before passing a bookmark to the pref.
71      dict->Remove(ManagedBookmarksTracker::kChildren, NULL);
72      GURL gurl = url_fixer::FixupURL(url, "");
73      if (!gurl.is_valid()) {
74        it = list->Erase(it, NULL);
75        continue;
76      }
77      dict->SetString(ManagedBookmarksTracker::kUrl, gurl.spec());
78    }
79
80    ++it;
81  }
82}
83
84}  // namespace policy
85