1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef COMPONENTS_PERMISSIONS_OBJECT_PERMISSION_CONTEXT_BASE_H_
6 #define COMPONENTS_PERMISSIONS_OBJECT_PERMISSION_CONTEXT_BASE_H_
14 #include "base/containers/flat_set.h"
15 #include "base/memory/raw_ptr.h"
16 #include "base/observer_list.h"
17 #include "base/observer_list_types.h"
18 #include "base/values.h"
19 #include "components/content_settings/core/common/content_settings.h"
20 #include "components/content_settings/core/common/content_settings_types.h"
21 #include "components/keyed_service/core/keyed_service.h"
22 #include "third_party/abseil-cpp/absl/types/optional.h"
25 class HostContentSettingsMap;
31 namespace permissions {
33 // This is the base class for services that manage any type of permission that
34 // is associated with a more complicated grant than simple allow/deny. This is
35 // typically granted through a chooser-style UI.
36 // Subclasses must define the structure of the objects that are stored.
37 class ObjectPermissionContextBase : public KeyedService {
40 Object(const url::Origin& origin,
41 base::Value::Dict value,
42 content_settings::SettingSource source,
45 // TODO(https://crbug.com/1187001): Migrate value to base::Value::Dict.
46 Object(const url::Origin& origin,
48 content_settings::SettingSource source,
51 std::unique_ptr<Object> Clone();
54 base::Value::Dict value;
55 content_settings::SettingSource source;
60 std::map<url::Origin, std::map<std::string, std::unique_ptr<Object>>>;
62 // This observer can be used to be notified of changes to the permission of
64 class PermissionObserver : public base::CheckedObserver {
66 // Notify observer that an object permission changed for the permission
67 // context represented by |guard_content_settings_type|, if applicable, and
68 // |data_content_settings_type|.
69 virtual void OnObjectPermissionChanged(
70 absl::optional<ContentSettingsType> guard_content_settings_type,
71 ContentSettingsType data_content_settings_type);
72 // Notify observer that an object permission was revoked for |origin|.
73 virtual void OnPermissionRevoked(const url::Origin& origin);
76 void AddObserver(PermissionObserver* observer);
77 void RemoveObserver(PermissionObserver* observer);
79 ObjectPermissionContextBase(
80 ContentSettingsType guard_content_settings_type,
81 ContentSettingsType data_content_settings_type,
82 HostContentSettingsMap* host_content_settings_map);
83 ObjectPermissionContextBase(
84 ContentSettingsType data_content_settings_type,
85 HostContentSettingsMap* host_content_settings_map);
86 ~ObjectPermissionContextBase() override;
88 // Checks whether |origin| can request permission to access objects. This is
89 // done by checking |guard_content_settings_type_| is in the "ask" state.
90 bool CanRequestObjectPermission(const url::Origin& origin);
92 // Returns the object corresponding to |key| that |origin| has been granted
93 // permission to access. This method should only be called if
94 // |GetKeyForObject()| is overridden to return sensible keys.
96 // This method may be extended by a subclass to return
97 // objects not stored in |host_content_settings_map_|.
98 virtual std::unique_ptr<Object> GetGrantedObject(const url::Origin& origin,
99 const base::StringPiece key);
101 // Returns the list of objects that |origin| has been granted permission to
102 // access. This method may be extended by a subclass to return objects not
103 // stored in |host_content_settings_map_|.
104 virtual std::vector<std::unique_ptr<Object>> GetGrantedObjects(
105 const url::Origin& origin);
107 // Returns a set of all origins that have granted permission(s).
108 // This method may be extended by a subclass to return origins with objects
109 // not stored in |host_content_settings_map_|.
110 virtual std::set<url::Origin> GetOriginsWithGrants();
112 // Returns the set of all objects that any origin has been granted permission
115 // This method may be extended by a subclass to return objects not stored in
116 // |host_content_settings_map_|.
117 virtual std::vector<std::unique_ptr<Object>> GetAllGrantedObjects();
119 // Grants |origin| access to |object| by writing it into
120 // |host_content_settings_map_|.
121 // TODO(https://crbug.com/1189682): Combine GrantObjectPermission and
122 // UpdateObjectPermission methods into key-based GrantOrUpdateObjectPermission
123 // once backend is updated to make key-based methods more efficient.
124 void GrantObjectPermission(const url::Origin& origin,
125 base::Value::Dict object);
127 // Updates |old_object| with |new_object| for |origin|, and writes the value
128 // into |host_content_settings_map_|.
129 void UpdateObjectPermission(const url::Origin& origin,
130 const base::Value::Dict& old_object,
131 base::Value::Dict new_object);
133 // Revokes |origin|'s permission to access |object|.
135 // This method may be extended by a subclass to revoke permission to access
136 // objects returned by GetGrantedObjects but not stored in
137 // |host_content_settings_map_|.
138 // TODO(https://crbug.com/1189682): Remove this method once backend is updated
139 // to make key-based methods more efficient.
140 virtual void RevokeObjectPermission(const url::Origin& origin,
141 const base::Value::Dict& object);
143 // Revokes |origin|'s permission to access the object corresponding to |key|.
144 // This method should only be called if |GetKeyForObject()| is overridden to
145 // return sensible keys.
147 // This method may be extended by a subclass to revoke permission to access
148 // objects returned by GetGrantedObjects but not stored in
149 // |host_content_settings_map_|.
150 virtual void RevokeObjectPermission(const url::Origin& origin,
151 const base::StringPiece key);
153 // Revokes a given `origin`'s permissions for access to all of its
154 // corresponding objects.
156 // This method may be extended by a subclass to revoke permissions to access
157 // objects returned by `GetGrantedObjects` but not stored in the
158 // `host_content_settings_map`.
159 virtual bool RevokeObjectPermissions(const url::Origin& origin);
161 // Returns a string which is used to uniquely identify this object.
162 virtual std::string GetKeyForObject(const base::Value::Dict& object) = 0;
164 // Validates the structure of an object read from
165 // |host_content_settings_map_|.
166 virtual bool IsValidObject(const base::Value::Dict& object) = 0;
168 // Gets the human-readable name for a given object.
169 virtual std::u16string GetObjectDisplayName(
170 const base::Value::Dict& object) = 0;
172 // Triggers the immediate flushing of all scheduled save setting operations.
173 // To be called when the host_content_settings_map_ is about to become
174 // unusable (e.g. browser context shutting down).
175 void FlushScheduledSaveSettingsCalls();
178 // TODO(odejesush): Use this method in all derived classes instead of using a
179 // member variable to store this state.
180 bool IsOffTheRecord();
181 void NotifyPermissionChanged();
182 void NotifyPermissionRevoked(const url::Origin& origin);
184 const absl::optional<ContentSettingsType> guard_content_settings_type_;
185 const ContentSettingsType data_content_settings_type_;
186 base::ObserverList<PermissionObserver> permission_observer_list_;
189 base::Value::Dict GetWebsiteSetting(const url::Origin& origin,
190 content_settings::SettingInfo* info);
191 void SaveWebsiteSetting(const url::Origin& origin);
192 void ScheduleSaveWebsiteSetting(const url::Origin& origin);
193 virtual std::vector<std::unique_ptr<Object>> GetWebsiteSettingObjects();
194 void LoadWebsiteSettingsIntoObjects();
196 // Getter for `objects_` used to initialize the structure at first access.
197 // Never use the `objects_` member directly outside of this function.
198 ObjectMap& objects();
200 const raw_ptr<HostContentSettingsMap, DanglingUntriaged>
201 host_content_settings_map_;
203 // In-memory cache that holds the granted objects. Lazy-initialized by first
204 // call to `objects()`.
207 // Whether the `objects_` member was initialized;
208 bool objects_initialized_ = false;
210 // Origins that have a scheduled `SaveWebsiteSetting` call.
211 base::flat_set<url::Origin> origins_with_scheduled_save_settings_calls_;
213 base::WeakPtrFactory<ObjectPermissionContextBase> weak_factory_{this};
216 } // namespace permissions
218 #endif // COMPONENTS_PERMISSIONS_OBJECT_PERMISSION_CONTEXT_BASE_H_