blob: 398cfe916edd6736a8069a3ac0e0f19648ad2a87 [file] [log] [blame]
mlamouri4e372022015-03-29 14:51:061// Copyright 2015 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
Clark DuVall6b73c742020-03-11 19:00:155#ifndef COMPONENTS_PERMISSIONS_PERMISSION_MANAGER_H_
6#define COMPONENTS_PERMISSIONS_PERMISSION_MANAGER_H_
mlamouri4e372022015-03-29 14:51:067
raymese3afee6b2016-04-18 02:00:508#include <unordered_map>
9
mlamouri4e372022015-03-29 14:51:0610#include "base/callback_forward.h"
James Hollyerd281a7312021-04-29 21:07:5911#include "base/containers/flat_map.h"
Brett Wilsonf976d3f2017-08-18 17:23:3912#include "base/containers/id_map.h"
mlamouri4e372022015-03-29 14:51:0613#include "base/macros.h"
mlamouri23957a22015-04-01 10:37:5614#include "components/content_settings/core/browser/content_settings_observer.h"
lalitm27583e92015-10-02 11:34:1715#include "components/content_settings/core/common/content_settings.h"
mlamouri4e372022015-03-29 14:51:0616#include "components/keyed_service/core/keyed_service.h"
James Hollyerd281a7312021-04-29 21:07:5917#include "components/permissions/permission_context_base.h"
Balazs Engedye15473b2021-04-14 09:09:2118#include "components/permissions/permission_request_id.h"
Clark DuVall732778e2020-01-27 18:13:5819#include "components/permissions/permission_util.h"
Andrey Lushnikovf3500102018-07-16 19:55:2220#include "content/public/browser/permission_controller_delegate.h"
Pavel Feldman73b22022018-11-02 02:55:3021#include "content/public/browser/permission_type.h"
Rohan Pavonefaf64572019-07-30 17:50:2022#include "url/origin.h"
mlamouri4e372022015-03-29 14:51:0623
Clark DuVall6b73c742020-03-11 19:00:1524namespace content {
25class BrowserContext;
26}
27
Clark DuVall484c2562020-01-23 22:05:0928namespace permissions {
Clark DuValla11361ad32020-02-20 22:14:2729class PermissionContextBase;
timlohc6911802017-03-01 05:37:0330struct PermissionResult;
mlamouri4e372022015-03-29 14:51:0631
mlamouri4e372022015-03-29 14:51:0632class PermissionManager : public KeyedService,
Andrey Lushnikovf3500102018-07-16 19:55:2233 public content::PermissionControllerDelegate,
James Hollyerd281a7312021-04-29 21:07:5934 public permissions::Observer {
mlamouri4e372022015-03-29 14:51:0635 public:
Clark DuVall6b73c742020-03-11 19:00:1536 using PermissionContextMap =
37 std::unordered_map<ContentSettingsType,
38 std::unique_ptr<PermissionContextBase>,
39 ContentSettingsTypeHash>;
40 PermissionManager(content::BrowserContext* browser_context,
41 PermissionContextMap permission_contexts);
mlamouri4e372022015-03-29 14:51:0642 ~PermissionManager() override;
43
Marc Treib9e4bd922017-09-25 08:32:1344 // Converts from |url|'s actual origin to the "canonical origin" that should
45 // be used for the purpose of requesting/storing permissions. For example, the
Raymes Khouryb474c642018-02-28 06:16:2846 // origin of the local NTP gets mapped to the Google base URL instead. With
47 // Permission Delegation it will transform the requesting origin into
48 // the embedding origin because all permission checks happen on the top level
49 // origin.
50 //
51 // All the public methods below, such as RequestPermission or
52 // GetPermissionStatus, take the actual origin and do the canonicalization
53 // internally. You only need to call this directly if you do something else
54 // with the origin, such as display it in the UI.
Balazs Engedyf39e22b2019-07-30 11:16:2455 GURL GetCanonicalOrigin(ContentSettingsType permission,
56 const GURL& requesting_origin,
Raymes Khouryb474c642018-02-28 06:16:2857 const GURL& embedding_origin) const;
Marc Treib9e4bd922017-09-25 08:32:1358
timloh9a180ad2017-02-20 07:15:2359 // Callers from within chrome/ should use the methods which take the
60 // ContentSettingsType enum. The methods which take PermissionType values
Andrey Lushnikovf3500102018-07-16 19:55:2261 // are for the content::PermissionControllerDelegate overrides and shouldn't
62 // be used from chrome/.
timloh592d7322017-02-23 07:23:5463
Balazs Engedye30e9612021-04-02 10:37:2964 void RequestPermission(ContentSettingsType permission,
65 content::RenderFrameHost* render_frame_host,
66 const GURL& requesting_origin,
67 bool user_gesture,
68 base::OnceCallback<void(ContentSetting)> callback);
69 void RequestPermissions(
timloh592d7322017-02-23 07:23:5470 const std::vector<ContentSettingsType>& permissions,
71 content::RenderFrameHost* render_frame_host,
72 const GURL& requesting_origin,
73 bool user_gesture,
danakj47c8fb52019-05-02 16:34:3674 base::OnceCallback<void(const std::vector<ContentSetting>&)> callback);
timloh592d7322017-02-23 07:23:5475
Clark DuVall6b73c742020-03-11 19:00:1576 PermissionResult GetPermissionStatus(ContentSettingsType permission,
77 const GURL& requesting_origin,
78 const GURL& embedding_origin);
timloh9a180ad2017-02-20 07:15:2379
raymesf6104d492017-03-09 01:20:1880 // Returns the permission status for a given frame. This should be preferred
81 // over GetPermissionStatus as additional checks can be performed when we know
82 // the exact context the request is coming from.
raymes79f22a612017-03-13 05:28:1083 // TODO(raymes): Currently we still pass the |requesting_origin| as a separate
84 // parameter because we can't yet guarantee that it matches the last committed
85 // origin of the RenderFrameHost. See crbug.com/698985.
Clark DuVall6b73c742020-03-11 19:00:1586 PermissionResult GetPermissionStatusForFrame(
raymesf6104d492017-03-09 01:20:1887 ContentSettingsType permission,
raymes79f22a612017-03-13 05:28:1088 content::RenderFrameHost* render_frame_host,
89 const GURL& requesting_origin);
raymesf6104d492017-03-09 01:20:1890
Andrey Lushnikovf3500102018-07-16 19:55:2291 // content::PermissionControllerDelegate implementation.
Balazs Engedye30e9612021-04-02 10:37:2992 void RequestPermission(
93 content::PermissionType permission,
94 content::RenderFrameHost* render_frame_host,
95 const GURL& requesting_origin,
96 bool user_gesture,
97 base::OnceCallback<void(blink::mojom::PermissionStatus)> callback)
98 override;
99 void RequestPermissions(
mlamouri8b5ec902015-10-24 00:52:03100 const std::vector<content::PermissionType>& permissions,
101 content::RenderFrameHost* render_frame_host,
102 const GURL& requesting_origin,
benwellsfd2b1552016-07-05 04:26:53103 bool user_gesture,
danakj47c8fb52019-05-02 16:34:36104 base::OnceCallback<
105 void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
leon.han06e55662016-03-26 17:19:42106 override;
mlamouri4e372022015-03-29 14:51:06107 void ResetPermission(content::PermissionType permission,
108 const GURL& requesting_origin,
109 const GURL& embedding_origin) override;
mathpcc29ae52016-05-04 15:22:17110 blink::mojom::PermissionStatus GetPermissionStatus(
mlamouri4e372022015-03-29 14:51:06111 content::PermissionType permission,
112 const GURL& requesting_origin,
113 const GURL& embedding_origin) override;
Raymes Khoury4ead6c32018-03-07 04:43:48114 blink::mojom::PermissionStatus GetPermissionStatusForFrame(
115 content::PermissionType permission,
116 content::RenderFrameHost* render_frame_host,
117 const GURL& requesting_origin) override;
Pavel Feldman446a91b2020-03-13 17:39:55118 bool IsPermissionOverridableByDevTools(
119 content::PermissionType permission,
120 const base::Optional<url::Origin>& origin) override;
Balazs Engedyad1489b2021-03-31 07:47:19121 SubscriptionId SubscribePermissionStatusChange(
mlamouri23957a22015-04-01 10:37:56122 content::PermissionType permission,
Raymes Khoury3ef4f6e2018-08-09 09:34:48123 content::RenderFrameHost* render_frame_host,
mlamouri23957a22015-04-01 10:37:56124 const GURL& requesting_origin,
danakj47c8fb52019-05-02 16:34:36125 base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
mathpcc29ae52016-05-04 15:22:17126 override;
Balazs Engedyad1489b2021-03-31 07:47:19127 void UnsubscribePermissionStatusChange(
128 SubscriptionId subscription_id) override;
mlamouri4e372022015-03-29 14:51:06129
timlohc6911802017-03-01 05:37:03130 // TODO(raymes): Rather than exposing this, use the denial reason from
131 // GetPermissionStatus in callers to determine whether a permission is
raymes893dbdd602016-12-19 22:49:29132 // denied due to the kill switch.
timloh9a180ad2017-02-20 07:15:23133 bool IsPermissionKillSwitchOn(ContentSettingsType);
raymes893dbdd602016-12-19 22:49:29134
Rohan Pavonefaf64572019-07-30 17:50:20135 // For the given |origin|, overrides permissions that belong to |overrides|.
136 // These permissions are in-sync with the PermissionController.
137 void SetPermissionOverridesForDevTools(
Pavel Feldman446a91b2020-03-13 17:39:55138 const base::Optional<url::Origin>& origin,
Rohan Pavonefaf64572019-07-30 17:50:20139 const PermissionOverrides& overrides) override;
140 void ResetPermissionOverridesForDevTools() override;
Pavel Feldman73b22022018-11-02 02:55:30141
Alexey Baskakov386f1742019-09-03 04:08:47142 // KeyedService implementation
143 void Shutdown() override;
144
Clark DuVall2c6c8672020-03-18 18:41:20145 // Helper method to convert PermissionType to ContentSettingType.
146 static ContentSettingsType PermissionTypeToContentSetting(
147 content::PermissionType permission);
148
Clark DuVall6b73c742020-03-11 19:00:15149 PermissionContextBase* GetPermissionContextForTesting(
150 ContentSettingsType type);
151
mlamouri4e372022015-03-29 14:51:06152 private:
raymes158a8c12017-07-06 02:52:59153 friend class PermissionManagerTest;
raymese3afee6b2016-04-18 02:00:50154
Balazs Engedye15473b2021-04-14 09:09:21155 // The `PendingRequestLocalId` will be unique within the `PermissionManager`
156 // instance, thus within a `BrowserContext`, which overachieves the
157 // requirement from `PermissionRequestID` that the `RequestLocalId` be unique
158 // within each frame.
mlamouri8b5ec902015-10-24 00:52:03159 class PendingRequest;
Balazs Engedye15473b2021-04-14 09:09:21160 using PendingRequestLocalId = PermissionRequestID::RequestLocalId;
161 using PendingRequestsMap =
162 base::IDMap<std::unique_ptr<PendingRequest>, PendingRequestLocalId>;
lalitm27583e92015-10-02 11:34:17163
raymes158a8c12017-07-06 02:52:59164 class PermissionResponseCallback;
165
mlamouri23957a22015-04-01 10:37:56166 struct Subscription;
Balazs Engedyad1489b2021-03-31 07:47:19167 using SubscriptionsMap =
168 base::IDMap<std::unique_ptr<Subscription>, SubscriptionId>;
James Hollyerd281a7312021-04-29 21:07:59169 using SubscriptionTypeCounts = base::flat_map<ContentSettingsType, size_t>;
mlamouri23957a22015-04-01 10:37:56170
Clark DuVall6b73c742020-03-11 19:00:15171 PermissionContextBase* GetPermissionContext(ContentSettingsType type);
raymese3afee6b2016-04-18 02:00:50172
mlamouri8b5ec902015-10-24 00:52:03173 // Called when a permission was decided for a given PendingRequest. The
Balazs Engedye15473b2021-04-14 09:09:21174 // PendingRequest is identified by its |request_local_id| and the permission
175 // is identified by its |permission_id|. If the PendingRequest contains more
176 // than one permission, it will wait for the remaining permissions to be
177 // resolved. When all the permissions have been resolved, the PendingRequest's
178 // callback is run.
179 void OnPermissionsRequestResponseStatus(
180 PendingRequestLocalId request_local_id,
181 int permission_id,
182 ContentSetting status);
lalitm27583e92015-10-02 11:34:17183
James Hollyerd281a7312021-04-29 21:07:59184 // permissions::Observer:
185 void OnPermissionChanged(const ContentSettingsPattern& primary_pattern,
186 const ContentSettingsPattern& secondary_pattern,
187 ContentSettingsType content_type) override;
mlamouri23957a22015-04-01 10:37:56188
Clark DuVall6b73c742020-03-11 19:00:15189 PermissionResult GetPermissionStatusHelper(
raymesf6104d492017-03-09 01:20:18190 ContentSettingsType permission,
191 content::RenderFrameHost* render_frame_host,
192 const GURL& requesting_origin,
193 const GURL& embedding_origin);
194
Pavel Feldman73b22022018-11-02 02:55:30195 ContentSetting GetPermissionOverrideForDevTools(
Rohan Pavone8180cba62019-08-26 20:55:09196 const url::Origin& origin,
Pavel Feldman73b22022018-11-02 02:55:30197 ContentSettingsType permission);
198
Clark DuVall6b73c742020-03-11 19:00:15199 content::BrowserContext* browser_context_;
Balazs Engedye15473b2021-04-14 09:09:21200
lalitm27583e92015-10-02 11:34:17201 PendingRequestsMap pending_requests_;
Balazs Engedye15473b2021-04-14 09:09:21202 PendingRequestLocalId::Generator request_local_id_generator_;
203
mlamouri23957a22015-04-01 10:37:56204 SubscriptionsMap subscriptions_;
Balazs Engedyad1489b2021-03-31 07:47:19205 SubscriptionId::Generator subscription_id_generator_;
mlamouri4e372022015-03-29 14:51:06206
James Hollyerd281a7312021-04-29 21:07:59207 // Tracks the number of Subscriptions in |subscriptions_| which have a
208 // certain ContentSettingsType. An entry for a given ContentSettingsType key
209 // is added on first use and never removed. This is done to utilize the
210 // flat_map's efficiency in accessing/editing items and minimize the use of
211 // the unefficient addition/removal of items.
212 SubscriptionTypeCounts subscription_type_counts_;
213
Clark DuVall6b73c742020-03-11 19:00:15214 PermissionContextMap permission_contexts_;
Rohan Pavonefaf64572019-07-30 17:50:20215 using ContentSettingsTypeOverrides =
216 base::flat_map<ContentSettingsType, ContentSetting>;
217 std::map<url::Origin, ContentSettingsTypeOverrides>
218 devtools_permission_overrides_;
Pavel Feldman446a91b2020-03-13 17:39:55219 url::Origin devtools_global_overrides_origin_;
raymese3afee6b2016-04-18 02:00:50220
Alexey Baskakov386f1742019-09-03 04:08:47221 bool is_shutting_down_ = false;
222
mlamouri4e372022015-03-29 14:51:06223 DISALLOW_COPY_AND_ASSIGN(PermissionManager);
224};
225
Clark DuVall6b73c742020-03-11 19:00:15226} // namespace permissions
227
228#endif // COMPONENTS_PERMISSIONS_PERMISSION_MANAGER_H_