1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 * Permission delegate handler provides a policy of how top-level can
9 * delegate permission to embedded iframes.
11 * This class includes a mechanism to delegate permission using feature
12 * policy. Feature policy will assure that only cross-origin iframes which
13 * have been explicitly granted access will have the opportunity to request
16 * For example if an iframe has not been granted access to geolocation by
17 * Feature Policy, geolocation request from the iframe will be automatically
18 * denied. if the top-level origin already has access to geolocation and the
19 * iframe has been granted access to geolocation by Feature Policy, the iframe
20 * will also have access to geolocation. If the top-level frame did not have
21 * access to geolocation, and the iframe has been granted access to geolocation
22 * by Feature Policy, a request from the cross-origin iframe would trigger a
23 * prompt using of the top-level origin.
26 #ifndef mozilla_PermissionDelegateHandler_h
27 #define mozilla_PermissionDelegateHandler_h
29 #include "mozilla/Array.h"
30 #include "nsCycleCollectionParticipant.h"
31 #include "nsISupports.h"
32 #include "nsIPermissionDelegateHandler.h"
33 #include "nsIPermissionManager.h"
37 class nsIContentPermissionRequest
;
45 class PermissionDelegateHandler final
: public nsIPermissionDelegateHandler
{
47 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
48 NS_DECL_CYCLE_COLLECTION_CLASS(PermissionDelegateHandler
)
50 NS_DECL_NSIPERMISSIONDELEGATEHANDLER
52 explicit PermissionDelegateHandler() = default;
53 explicit PermissionDelegateHandler(mozilla::dom::Document
* aDocument
);
55 static constexpr size_t DELEGATED_PERMISSION_COUNT
= 13;
57 typedef struct DelegatedPermissionList
{
58 Array
<uint32_t, DELEGATED_PERMISSION_COUNT
> mPermissions
;
60 bool operator==(const DelegatedPermissionList
& aOther
) const {
61 return mPermissions
== aOther
.mPermissions
;
63 } DelegatedPermissionList
;
68 * Indicates if we has the right to make permission request with aType
70 bool HasPermissionDelegated(const nsACString
& aType
) const;
73 * Get permission state, which applied permission delegate policy.
75 * @param aType the permission type to get
76 * @param aPermission out argument which will be a permission type that we
77 * will return from this function.
78 * @param aExactHostMatch whether to look for the exact host name or also for
79 * subdomains that can have the same permission.
81 nsresult
GetPermission(const nsACString
& aType
, uint32_t* aPermission
,
82 bool aExactHostMatch
);
85 * Get permission state for permission api, which applied
86 * permission delegate policy.
88 * @param aType the permission type to get
89 * @param aExactHostMatch whether to look for the exact host name or also for
90 * subdomains that can have the same permission.
91 * @param aPermission out argument which will be a permission type that we
92 * will return from this function.
94 nsresult
GetPermissionForPermissionsAPI(const nsACString
& aType
,
95 uint32_t* aPermission
);
97 enum PermissionDelegatePolicy
{
98 /* Always delegate permission from top level to iframe and the iframe
99 * should use top level origin to get/set permission.*/
100 eDelegateUseTopOrigin
,
102 /* Permission is delegated using Feature Policy. Permission is denied by
103 * default in cross origin iframe and the iframe only could get/set
104 * permission if there's allow attribute set in iframe. e.g allow =
106 eDelegateUseFeaturePolicy
,
108 /* Persistent denied permissions in cross origin iframe */
109 ePersistDeniedCrossOrigin
,
111 /* This is the old behavior of cross origin iframe permission. The
112 * permission delegation should not have an effect on iframe. The cross
113 * origin iframe get/set permissions by its origin */
114 eDelegateUseIframeOrigin
,
118 * Indicates matching between Feature Policy and Permissions name defined in
119 * Permissions Manager, not DOM Permissions API. Permissions API exposed in
120 * DOM only supports "geo" at the moment but Permissions Manager also supports
121 * "camera", "microphone".
124 const char* mPermissionName
;
125 const char16_t
* mFeatureName
;
126 PermissionDelegatePolicy mPolicy
;
127 } PermissionDelegateInfo
;
130 * The loader maintains a weak reference to the document with
131 * which it is initialized. This call forces the reference to
134 void DropDocumentReference() { mDocument
= nullptr; }
137 * Helper function to return the delegate info value for aPermissionName.
138 * @param aPermissionName the permission name to get
140 static const PermissionDelegateInfo
* GetPermissionDelegateInfo(
141 const nsAString
& aPermissionName
);
144 * Helper function to return the delegate principal. This will return nullptr,
145 * or request's principal or top level principal based on the delegate policy
146 * will be applied for a given type.
147 * We use this function when prompting, no need to perform permission check
150 * @param aType the permission type to get
151 * @param aRequest The request which the principal is get from.
152 * @param aResult out argument which will be a principal that we
153 * will return from this function.
155 static nsresult
GetDelegatePrincipal(const nsACString
& aType
,
156 nsIContentPermissionRequest
* aRequest
,
157 nsIPrincipal
** aResult
);
160 * Populate all delegated permissions to the WindowContext of the associated
161 * document. We only populate the permissions for the top-level content.
163 void PopulateAllDelegatedPermissions();
166 * Update the given delegated permission to the WindowContext. We only
167 * update it for the top-level content.
169 void UpdateDelegatedPermission(const nsACString
& aType
);
172 ~PermissionDelegateHandler() = default;
175 * Check whether the permission is blocked by FeaturePolicy directive.
176 * Default allowlist for a featureName of permission used in permissions
177 * delegate should be set to eSelf, to ensure that permission is denied by
178 * default and only have the opportunity to request permission with allow
181 bool HasFeaturePolicyAllowed(const PermissionDelegateInfo
* info
) const;
184 * A helper function to test the permission and set the result to the given
185 * list. It will return true if the permission is changed, otherwise false.
187 bool UpdateDelegatePermissionInternal(
188 PermissionDelegateHandler::DelegatedPermissionList
& aList
,
189 const nsACString
& aType
, size_t aIdx
,
190 nsresult (NS_STDCALL
nsIPermissionManager::*aTestFunc
)(nsIPrincipal
*,
194 // A weak pointer to our document. Nulled out by DropDocumentReference.
195 mozilla::dom::Document
* mDocument
;
197 nsCOMPtr
<nsIPrincipal
> mPrincipal
;
198 RefPtr
<nsIPermissionManager
> mPermissionManager
;
201 } // namespace mozilla
203 #endif // mozilla_PermissionDelegateHandler_h