tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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