nsContentPermissionHelper.h (7751B)
1 /* -*- Mode: C++; tab-width: 8; 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/. */ 6 7 #ifndef nsContentPermissionHelper_h 8 #define nsContentPermissionHelper_h 9 10 #include "mozilla/PermissionDelegateHandler.h" 11 #include "mozilla/dom/PContentPermissionRequestChild.h" 12 #include "mozilla/dom/ipc/IdType.h" 13 #include "nsIContentPermissionPrompt.h" 14 #include "nsIMutableArray.h" 15 #include "nsTArray.h" 16 17 // Microsoft's API Name hackery sucks 18 // XXXbz Doing this in a header is a gigantic footgun. See 19 // https://bugzilla.mozilla.org/show_bug.cgi?id=932421#c3 for why. 20 #undef LoadImage 21 22 class nsPIDOMWindowInner; 23 class nsContentPermissionRequestProxy; 24 25 namespace mozilla::dom { 26 27 class Element; 28 class PermissionRequest; 29 class ContentPermissionRequestParent; 30 class PContentPermissionRequestParent; 31 32 class ContentPermissionType : public nsIContentPermissionType { 33 public: 34 NS_DECL_ISUPPORTS 35 NS_DECL_NSICONTENTPERMISSIONTYPE 36 37 ContentPermissionType(const nsACString& aType, 38 const nsTArray<nsString>& aOptions); 39 40 protected: 41 virtual ~ContentPermissionType(); 42 43 nsCString mType; 44 nsTArray<nsString> mOptions; 45 }; 46 47 class nsContentPermissionUtils { 48 public: 49 static uint32_t ConvertPermissionRequestToArray( 50 nsTArray<PermissionRequest>& aSrcArray, nsIMutableArray* aDesArray); 51 52 // Converts blindly, that is, strings are not matched against any list. 53 // 54 // @param aSrcArray needs to contain elements of type 55 // `nsIContentPermissionType`. 56 static void ConvertArrayToPermissionRequest( 57 nsIArray* aSrcArray, nsTArray<PermissionRequest>& aDesArray); 58 59 static nsresult CreatePermissionArray(const nsACString& aType, 60 const nsTArray<nsString>& aOptions, 61 nsIArray** aTypesArray); 62 63 // @param aIsRequestDelegatedToUnsafeThirdParty see 64 // ContentPermissionRequestParent. 65 static PContentPermissionRequestParent* CreateContentPermissionRequestParent( 66 const nsTArray<PermissionRequest>& aRequests, Element* aElement, 67 nsIPrincipal* aPrincipal, nsIPrincipal* aTopLevelPrincipal, 68 const bool aHasValidTransientUserGestureActivation, 69 const bool aIsRequestDelegatedToUnsafeThirdParty, const TabId& aTabId); 70 71 static nsresult AskPermission(nsIContentPermissionRequest* aRequest, 72 nsPIDOMWindowInner* aWindow); 73 74 static nsTArray<PContentPermissionRequestParent*> 75 GetContentPermissionRequestParentById(const TabId& aTabId); 76 77 static void NotifyRemoveContentPermissionRequestParent( 78 PContentPermissionRequestParent* aParent); 79 80 static nsTArray<PContentPermissionRequestChild*> 81 GetContentPermissionRequestChildById(const TabId& aTabId); 82 83 static void NotifyRemoveContentPermissionRequestChild( 84 PContentPermissionRequestChild* aChild); 85 }; 86 87 nsresult TranslateChoices( 88 JS::Handle<JS::Value> aChoices, 89 const nsTArray<PermissionRequest>& aPermissionRequests, 90 nsTArray<PermissionChoice>& aTranslatedChoices); 91 92 class ContentPermissionRequestBase : public nsIContentPermissionRequest { 93 public: 94 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 95 NS_DECL_CYCLE_COLLECTION_CLASS(ContentPermissionRequestBase) 96 97 NS_IMETHOD GetTypes(nsIArray** aTypes) override; 98 NS_IMETHOD GetPrincipal(nsIPrincipal** aPrincipal) override; 99 NS_IMETHOD GetDelegatePrincipal(const nsACString& aType, 100 nsIPrincipal** aPrincipal) override; 101 NS_IMETHOD GetTopLevelPrincipal(nsIPrincipal** aTopLevelPrincipal) override; 102 NS_IMETHOD GetWindow(mozIDOMWindow** aWindow) override; 103 NS_IMETHOD GetElement(mozilla::dom::Element** aElement) override; 104 NS_IMETHOD GetHasValidTransientUserGestureActivation( 105 bool* aHasValidTransientUserGestureActivation) override; 106 NS_IMETHOD GetIsRequestDelegatedToUnsafeThirdParty( 107 bool* aIsRequestDelegatedToUnsafeThirdParty) override; 108 NS_IMETHOD NotifyShown(void) override; 109 // Overrides for Allow() and Cancel() aren't provided by this class. 110 // That is the responsibility of the subclasses. 111 112 enum class PromptResult { 113 Granted, 114 Denied, 115 Pending, 116 }; 117 nsresult ShowPrompt(PromptResult& aResult); 118 119 PromptResult CheckPromptPrefs() const; 120 121 // Check if the permission has an opportunity to request. 122 bool CheckPermissionDelegate() const; 123 124 enum class DelayedTaskType { 125 Allow, 126 Deny, 127 Request, 128 }; 129 void RequestDelayedTask(nsIEventTarget* aTarget, DelayedTaskType aType); 130 131 protected: 132 // @param aPrefName see `mPrefName`. 133 // @param aType see `mType`. 134 ContentPermissionRequestBase(nsIPrincipal* aPrincipal, 135 nsPIDOMWindowInner* aWindow, 136 const nsACString& aPrefName, 137 const nsACString& aType); 138 virtual ~ContentPermissionRequestBase() = default; 139 140 nsCOMPtr<nsIPrincipal> mPrincipal; 141 nsCOMPtr<nsIPrincipal> mTopLevelPrincipal; 142 nsCOMPtr<nsPIDOMWindowInner> mWindow; 143 RefPtr<PermissionDelegateHandler> mPermissionHandler; 144 145 // The prefix of a pref which allows tests to bypass showing the prompt. 146 // Tests will have to set both of 147 // ${mPrefName}.prompt.testing and 148 // ${mPrefName}.prompt.testing.allow 149 // to either true or false. If no such testing is required, mPrefName may be 150 // empty. 151 const nsCString mPrefName; 152 153 // The type of the request, such as "autoplay-media-audible". 154 const nsCString mType; 155 156 bool mHasValidTransientUserGestureActivation; 157 158 // See nsIPermissionDelegateHandler.maybeUnsafePermissionDelegate`. 159 bool mIsRequestDelegatedToUnsafeThirdParty; 160 }; 161 162 } // namespace mozilla::dom 163 164 using mozilla::dom::ContentPermissionRequestParent; 165 166 class nsContentPermissionRequestProxy : public nsIContentPermissionRequest { 167 public: 168 NS_DECL_ISUPPORTS 169 NS_DECL_NSICONTENTPERMISSIONREQUEST 170 171 explicit nsContentPermissionRequestProxy( 172 ContentPermissionRequestParent* parent); 173 174 nsresult Init(const nsTArray<mozilla::dom::PermissionRequest>& requests); 175 176 void OnParentDestroyed(); 177 178 private: 179 virtual ~nsContentPermissionRequestProxy(); 180 181 // Non-owning pointer to the ContentPermissionRequestParent object which owns 182 // this proxy. 183 ContentPermissionRequestParent* mParent; 184 nsTArray<mozilla::dom::PermissionRequest> mPermissionRequests; 185 }; 186 187 /** 188 * RemotePermissionRequest will send a prompt ipdl request to the chrome process 189 * (https://wiki.mozilla.org/Security/Sandbox/Process_model#Chrome_process_.28Parent.29). 190 */ 191 class RemotePermissionRequest final 192 : public mozilla::dom::PContentPermissionRequestChild { 193 public: 194 NS_INLINE_DECL_REFCOUNTING(RemotePermissionRequest) 195 196 RemotePermissionRequest(nsIContentPermissionRequest* aRequest, 197 nsPIDOMWindowInner* aWindow); 198 199 // It will be called when prompt dismissed. MOZ_CAN_RUN_SCRIPT_BOUNDARY 200 // because we don't have MOZ_CAN_RUN_SCRIPT bits in IPC code yet. 201 MOZ_CAN_RUN_SCRIPT_BOUNDARY 202 mozilla::ipc::IPCResult RecvNotifyResult( 203 const bool& aAllow, nsTArray<PermissionChoice>&& aChoices); 204 205 void IPDLAddRef() { 206 mIPCOpen = true; 207 AddRef(); 208 } 209 210 void IPDLRelease() { 211 mIPCOpen = false; 212 Release(); 213 } 214 215 void Destroy(); 216 217 bool IPCOpen() const { return mIPCOpen && !mDestroyed; } 218 219 private: 220 virtual ~RemotePermissionRequest(); 221 222 MOZ_CAN_RUN_SCRIPT 223 void DoAllow(JS::Handle<JS::Value> aChoices); 224 MOZ_CAN_RUN_SCRIPT 225 void DoCancel(); 226 227 nsCOMPtr<nsIContentPermissionRequest> mRequest; 228 nsCOMPtr<nsPIDOMWindowInner> mWindow; 229 bool mIPCOpen; 230 bool mDestroyed; 231 }; 232 233 #endif // nsContentPermissionHelper_h