blob: 7b8e602529f750bb0dc8b71efeae8a2349203e9e [file] [log] [blame]
// Copyright 2013 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.
#ifndef COMPONENTS_POLICY_CORE_COMMON_POLICY_MAP_H_
#define COMPONENTS_POLICY_CORE_COMMON_POLICY_MAP_H_
#include <stddef.h>
#include <map>
#include <memory>
#include <set>
#include <string>
#include "base/callback.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/values.h"
#include "components/policy/core/common/external_data_fetcher.h"
#include "components/policy/core/common/policy_types.h"
#include "components/policy/policy_export.h"
namespace policy {
class PolicyMerger;
class PolicyMapTest;
FORWARD_DECLARE_TEST(PolicyMapTest, BlockedEntry);
FORWARD_DECLARE_TEST(PolicyMapTest, MergeFrom);
// A mapping of policy names to policy values for a given policy namespace.
class POLICY_EXPORT PolicyMap {
public:
// Each policy maps to an Entry which keeps the policy value as well as other
// relevant data about the policy.
class POLICY_EXPORT Entry {
public:
PolicyLevel level = POLICY_LEVEL_RECOMMENDED;
PolicyScope scope = POLICY_SCOPE_USER;
// For debugging and displaying only. Set by provider delivering the policy.
PolicySource source = POLICY_SOURCE_ENTERPRISE_DEFAULT;
std::unique_ptr<base::Value> value;
std::unique_ptr<ExternalDataFetcher> external_data_fetcher;
std::vector<Entry> conflicts;
Entry();
Entry(PolicyLevel level,
PolicyScope scope,
PolicySource source,
std::unique_ptr<base::Value> value,
std::unique_ptr<ExternalDataFetcher> external_data_fetcher);
~Entry();
Entry(Entry&&) noexcept;
Entry& operator=(Entry&&) noexcept;
// Returns a copy of |this|.
Entry DeepCopy() const;
// Returns true if |this| has higher priority than |other|. The priority of
// the fields are |level| > |scope| > |source|.
bool has_higher_priority_than(const Entry& other) const;
// Returns true if |this| equals |other|.
bool Equals(const Entry& other) const;
// Add a non-localized error given its UTF-8 string contents.
void AddError(base::StringPiece error);
// Add a localized error given its l10n message ID.
void AddError(int message_id);
// Add a localized error given its l10n message ID.
void AddWarning(int message_id);
// Adds a conflicting policy.
void AddConflictingPolicy(Entry&& conflict);
// Removes all the conflicts.
void ClearConflicts();
// Returns true if the policy is either blocked or ignored.
bool IsBlockedOrIgnored() const;
// Marks the policy as blocked because it is not supported in the current
// environment.
void SetBlocked();
// Marks the policy as ignored because it does not share the priority of
// its policy atomic group.
void SetIgnoredByPolicyAtomicGroup();
bool IsIgnoredByAtomicGroup() const;
// Callback used to look up a localized string given its l10n message ID. It
// should return a UTF-16 string.
typedef base::RepeatingCallback<base::string16(int message_id)>
L10nLookupFunction;
// Returns localized errors added through AddError(), as UTF-16, and
// separated with LF characters.
base::string16 GetLocalizedErrors(L10nLookupFunction lookup) const;
// Returns localized warnings added through AddWarning(), as UTF-16, and
// separated with LF characters.
base::string16 GetLocalizedWarnings(L10nLookupFunction lookup) const;
private:
std::string error_strings_;
std::set<int> error_message_ids_;
std::set<int> warning_message_ids_;
};
typedef std::map<std::string, Entry> PolicyMapType;
typedef PolicyMapType::const_iterator const_iterator;
PolicyMap();
virtual ~PolicyMap();
// Returns a weak reference to the entry currently stored for key |policy|,
// or NULL if untrusted or not found. Ownership is retained by the PolicyMap.
const Entry* Get(const std::string& policy) const;
Entry* GetMutable(const std::string& policy);
// Returns a weak reference to the value currently stored for key
// |policy|, or NULL if not found. Ownership is retained by the PolicyMap.
// This is equivalent to Get(policy)->value, when it doesn't return NULL.
const base::Value* GetValue(const std::string& policy) const;
base::Value* GetMutableValue(const std::string& policy);
// Overwrites any existing information stored in the map for the key |policy|.
// Resets the error for that policy to the empty string.
void Set(const std::string& policy,
PolicyLevel level,
PolicyScope scope,
PolicySource source,
std::unique_ptr<base::Value> value,
std::unique_ptr<ExternalDataFetcher> external_data_fetcher);
void Set(const std::string& policy, Entry entry);
// Adds non-localized |error| to the map for the key |policy| that should be
// shown to the user alongside the value in the policy UI. This should only be
// called for policies that are already stored in this map.
void AddError(const std::string& policy, const std::string& error);
// Adds a localized error with |message_id| to the map for the key |policy|
// that should be shown to the user alongisde the value in the policy UI. This
// should only be called for policies that are already stored in the map.
void AddError(const std::string& policy, int message_id);
// Return True if the policy is set but its value is ignored because it does
// not share the highest priority from its atomic group. Returns False if the
// policy is active or not set.
bool IsPolicyIgnoredByAtomicGroup(const std::string& policy) const;
// For all policies, overwrite the PolicySource with |source|.
void SetSourceForAll(PolicySource source);
// Erase the given |policy|, if it exists in this map.
void Erase(const std::string& policy);
// Erase all entries for which |filter| returns true.
void EraseMatching(const base::Callback<bool(const const_iterator)>& filter);
// Erase all entries for which |filter| returns false.
void EraseNonmatching(
const base::Callback<bool(const const_iterator)>& filter);
// Swaps the internal representation of |this| with |other|.
void Swap(PolicyMap* other);
// |this| becomes a copy of |other|. Any existing policies are dropped.
void CopyFrom(const PolicyMap& other);
// Returns a copy of |this|.
std::unique_ptr<PolicyMap> DeepCopy() const;
// Merges policies from |other| into |this|. Existing policies are only
// overridden by those in |other| if they have a higher priority, as defined
// by Entry::has_higher_priority_than(). If a policy is contained in both
// maps with the same priority, the current value in |this| is preserved.
void MergeFrom(const PolicyMap& other);
// Merge the policy values that are coming from different sources.
void MergeValues(const std::vector<PolicyMerger*>& mergers);
// Loads the values in |policies| into this PolicyMap. All policies loaded
// will have |level|, |scope| and |source| in their entries. Existing entries
// are replaced.
void LoadFrom(const base::DictionaryValue* policies,
PolicyLevel level,
PolicyScope scope,
PolicySource source);
// Compares this value map against |other| and stores all key names that have
// different values or reference different external data in |differing_keys|.
// This includes keys that are present only in one of the maps.
// |differing_keys| is not cleared before the keys are added.
void GetDifferingKeys(const PolicyMap& other,
std::set<std::string>* differing_keys) const;
bool Equals(const PolicyMap& other) const;
bool empty() const;
size_t size() const;
const_iterator begin() const;
const_iterator end() const;
void Clear();
private:
FRIEND_TEST_ALL_PREFIXES(PolicyMapTest, BlockedEntry);
FRIEND_TEST_ALL_PREFIXES(PolicyMapTest, MergeFrom);
// Returns a weak reference to the entry currently stored for key |policy|,
// or NULL if not found. Ownership is retained by the PolicyMap.
const Entry* GetUntrusted(const std::string& policy) const;
Entry* GetMutableUntrusted(const std::string& policy);
// Helper function for Equals().
static bool MapEntryEquals(const PolicyMapType::value_type& a,
const PolicyMapType::value_type& b);
// Erase all entries for which |filter| returns |deletion_value|.
void FilterErase(const base::Callback<bool(const const_iterator)>& filter,
bool deletion_value);
PolicyMapType map_;
DISALLOW_COPY_AND_ASSIGN(PolicyMap);
};
} // namespace policy
#endif // COMPONENTS_POLICY_CORE_COMMON_POLICY_MAP_H_