1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef mozilla_extensions_WebExtensionPolicy_h
7 #define mozilla_extensions_WebExtensionPolicy_h
8 
9 #include "mozilla/dom/BindingDeclarations.h"
10 #include "mozilla/dom/Nullable.h"
11 #include "mozilla/dom/WebExtensionPolicyBinding.h"
12 #include "mozilla/dom/WindowProxyHolder.h"
13 #include "mozilla/extensions/MatchPattern.h"
14 
15 #include "jspubtd.h"
16 
17 #include "mozilla/Result.h"
18 #include "mozilla/WeakPtr.h"
19 #include "nsCOMPtr.h"
20 #include "nsCycleCollectionParticipant.h"
21 #include "nsISupports.h"
22 #include "nsWrapperCache.h"
23 
24 namespace mozilla {
25 namespace dom {
26 class Promise;
27 }  // namespace dom
28 
29 namespace extensions {
30 
31 using dom::WebExtensionInit;
32 using dom::WebExtensionLocalizeCallback;
33 
34 class DocInfo;
35 class WebExtensionContentScript;
36 
37 class WebExtensionPolicy final : public nsISupports,
38                                  public nsWrapperCache,
39                                  public SupportsWeakPtr<WebExtensionPolicy> {
40  public:
41   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
42   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebExtensionPolicy)
43   MOZ_DECLARE_WEAKREFERENCE_TYPENAME(WebExtensionPolicy)
44 
45   using ScriptArray = nsTArray<RefPtr<WebExtensionContentScript>>;
46 
47   static already_AddRefed<WebExtensionPolicy> Constructor(
48       dom::GlobalObject& aGlobal, const WebExtensionInit& aInit,
49       ErrorResult& aRv);
50 
Id()51   nsAtom* Id() const { return mId; }
GetId(nsAString & aId)52   void GetId(nsAString& aId) const { aId = nsDependentAtomString(mId); };
53 
MozExtensionHostname()54   const nsCString& MozExtensionHostname() const { return mHostname; }
GetMozExtensionHostname(nsACString & aHostname)55   void GetMozExtensionHostname(nsACString& aHostname) const {
56     aHostname = MozExtensionHostname();
57   }
58 
GetBaseURL(nsACString & aBaseURL)59   void GetBaseURL(nsACString& aBaseURL) const {
60     MOZ_ALWAYS_SUCCEEDS(mBaseURI->GetSpec(aBaseURL));
61   }
62 
IsPrivileged()63   bool IsPrivileged() { return mIsPrivileged; }
64 
65   void GetURL(const nsAString& aPath, nsAString& aURL, ErrorResult& aRv) const;
66 
67   Result<nsString, nsresult> GetURL(const nsAString& aPath) const;
68 
69   void RegisterContentScript(WebExtensionContentScript& script,
70                              ErrorResult& aRv);
71 
72   void UnregisterContentScript(const WebExtensionContentScript& script,
73                                ErrorResult& aRv);
74 
75   void InjectContentScripts(ErrorResult& aRv);
76 
77   bool CanAccessURI(const URLInfo& aURI, bool aExplicit = false,
78                     bool aCheckRestricted = true,
79                     bool aAllowFilePermission = false) const {
80     return (!aCheckRestricted || !IsRestrictedURI(aURI)) && mHostPermissions &&
81            mHostPermissions->Matches(aURI, aExplicit) &&
82            (aURI.Scheme() != nsGkAtoms::file || aAllowFilePermission);
83   }
84 
IsPathWebAccessible(const nsAString & aPath)85   bool IsPathWebAccessible(const nsAString& aPath) const {
86     return mWebAccessiblePaths.Matches(aPath);
87   }
88 
HasPermission(const nsAtom * aPermission)89   bool HasPermission(const nsAtom* aPermission) const {
90     return mPermissions->Contains(aPermission);
91   }
HasPermission(const nsAString & aPermission)92   bool HasPermission(const nsAString& aPermission) const {
93     return mPermissions->Contains(aPermission);
94   }
95 
96   static bool IsRestrictedDoc(const DocInfo& aDoc);
97   static bool IsRestrictedURI(const URLInfo& aURI);
98 
99   nsCString BackgroundPageHTML() const;
100 
101   MOZ_CAN_RUN_SCRIPT
102   void Localize(const nsAString& aInput, nsString& aResult) const;
103 
Name()104   const nsString& Name() const { return mName; }
GetName(nsAString & aName)105   void GetName(nsAString& aName) const { aName = mName; }
106 
ExtensionPageCSP()107   const nsString& ExtensionPageCSP() const { return mExtensionPageCSP; }
GetExtensionPageCSP(nsAString & aCSP)108   void GetExtensionPageCSP(nsAString& aCSP) const { aCSP = mExtensionPageCSP; }
109 
ContentScriptCSP()110   const nsString& ContentScriptCSP() const { return mContentScriptCSP; }
GetContentScriptCSP(nsAString & aCSP)111   void GetContentScriptCSP(nsAString& aCSP) const { aCSP = mContentScriptCSP; }
112 
AllowedOrigins()113   already_AddRefed<MatchPatternSet> AllowedOrigins() {
114     return do_AddRef(mHostPermissions);
115   }
SetAllowedOrigins(MatchPatternSet & aAllowedOrigins)116   void SetAllowedOrigins(MatchPatternSet& aAllowedOrigins) {
117     mHostPermissions = &aAllowedOrigins;
118   }
119 
GetPermissions(nsTArray<nsString> & aResult)120   void GetPermissions(nsTArray<nsString>& aResult) const {
121     mPermissions->Get(aResult);
122   }
SetPermissions(const nsTArray<nsString> & aPermissions)123   void SetPermissions(const nsTArray<nsString>& aPermissions) {
124     mPermissions = new AtomSet(aPermissions);
125   }
126 
127   void GetContentScripts(ScriptArray& aScripts) const;
ContentScripts()128   const ScriptArray& ContentScripts() const { return mContentScripts; }
129 
Active()130   bool Active() const { return mActive; }
131   void SetActive(bool aActive, ErrorResult& aRv);
132 
PrivateBrowsingAllowed()133   bool PrivateBrowsingAllowed() const {
134     return mAllowPrivateBrowsingByDefault ||
135            HasPermission(nsGkAtoms::privateBrowsingAllowedPermission);
136   }
137 
138   bool CanAccessContext(nsILoadContext* aContext) const;
139 
140   bool CanAccessWindow(const dom::WindowProxyHolder& aWindow) const;
141 
142   void GetReadyPromise(JSContext* aCx, JS::MutableHandleObject aResult) const;
ReadyPromise()143   dom::Promise* ReadyPromise() const { return mReadyPromise; }
144 
145   static void GetActiveExtensions(
146       dom::GlobalObject& aGlobal,
147       nsTArray<RefPtr<WebExtensionPolicy>>& aResults);
148 
149   static already_AddRefed<WebExtensionPolicy> GetByID(
150       dom::GlobalObject& aGlobal, const nsAString& aID);
151 
152   static already_AddRefed<WebExtensionPolicy> GetByHostname(
153       dom::GlobalObject& aGlobal, const nsACString& aHostname);
154 
155   static already_AddRefed<WebExtensionPolicy> GetByURI(
156       dom::GlobalObject& aGlobal, nsIURI* aURI);
157 
IsRestrictedURI(dom::GlobalObject & aGlobal,const URLInfo & aURI)158   static bool IsRestrictedURI(dom::GlobalObject& aGlobal, const URLInfo& aURI) {
159     return IsRestrictedURI(aURI);
160   }
161 
162   static bool UseRemoteWebExtensions(dom::GlobalObject& aGlobal);
163   static bool IsExtensionProcess(dom::GlobalObject& aGlobal);
164 
GetParentObject()165   nsISupports* GetParentObject() const { return mParent; }
166 
167   virtual JSObject* WrapObject(JSContext* aCx,
168                                JS::HandleObject aGivenProto) override;
169 
170  protected:
171   virtual ~WebExtensionPolicy() = default;
172 
173  private:
174   WebExtensionPolicy(dom::GlobalObject& aGlobal, const WebExtensionInit& aInit,
175                      ErrorResult& aRv);
176 
177   bool Enable();
178   bool Disable();
179 
180   nsCOMPtr<nsISupports> mParent;
181 
182   RefPtr<nsAtom> mId;
183   nsCString mHostname;
184   nsCOMPtr<nsIURI> mBaseURI;
185 
186   nsString mName;
187   nsString mExtensionPageCSP;
188   nsString mContentScriptCSP;
189 
190   bool mActive = false;
191   bool mAllowPrivateBrowsingByDefault = true;
192 
193   RefPtr<WebExtensionLocalizeCallback> mLocalizeCallback;
194 
195   bool mIsPrivileged;
196   RefPtr<AtomSet> mPermissions;
197   RefPtr<MatchPatternSet> mHostPermissions;
198   MatchGlobSet mWebAccessiblePaths;
199 
200   dom::Nullable<nsTArray<nsString>> mBackgroundScripts;
201 
202   nsTArray<RefPtr<WebExtensionContentScript>> mContentScripts;
203 
204   RefPtr<dom::Promise> mReadyPromise;
205 };
206 
207 }  // namespace extensions
208 }  // namespace mozilla
209 
210 #endif  // mozilla_extensions_WebExtensionPolicy_h
211