blob: 4f872838c0d70c00e26c24fe938a6ce1c6af104f [file] [log] [blame]
binjin5f405ef2014-09-03 21:23:161// Copyright 2014 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
5#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_MANAGEMENT_H_
6#define CHROME_BROWSER_EXTENSIONS_EXTENSION_MANAGEMENT_H_
7
dchengc963c7142016-04-08 03:55:228#include <memory>
binjin685ade82014-11-06 09:53:569#include <string>
avi3ec9c0d2016-12-27 22:38:0610#include <unordered_map>
binjine6b58b52014-10-31 01:55:5711#include <vector>
12
binjin5f405ef2014-09-03 21:23:1613#include "base/macros.h"
binjine6b58b52014-10-31 01:55:5714#include "base/memory/ref_counted.h"
binjin1569c9b2014-09-05 13:33:1815#include "base/memory/singleton.h"
16#include "base/observer_list.h"
binjin5f405ef2014-09-03 21:23:1617#include "base/values.h"
binjin1569c9b2014-09-05 13:33:1818#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
19#include "components/keyed_service/core/keyed_service.h"
brettwb1fc1b82016-02-02 00:19:0820#include "components/prefs/pref_change_registrar.h"
binjin1569c9b2014-09-05 13:33:1821#include "extensions/browser/management_policy.h"
rdevlin.cronin0670b562016-07-02 02:05:4322#include "extensions/common/extension_id.h"
binjin5f405ef2014-09-03 21:23:1623#include "extensions/common/manifest.h"
binjin5f405ef2014-09-03 21:23:1624
binjin311ecdf2014-09-12 22:56:5225class GURL;
binjin5f405ef2014-09-03 21:23:1626class PrefService;
Sergey Poromov741e70702018-10-11 20:11:5427class Profile;
binjin5f405ef2014-09-03 21:23:1628
binjin1569c9b2014-09-05 13:33:1829namespace content {
30class BrowserContext;
31} // namespace content
32
binjin5f405ef2014-09-03 21:23:1633namespace extensions {
34
binjin81d7c552014-10-02 11:47:1235namespace internal {
36
37struct IndividualSettings;
38struct GlobalSettings;
39
40} // namespace internal
41
binjine6b58b52014-10-31 01:55:5742class APIPermissionSet;
rdevlin.cronin0670b562016-07-02 02:05:4343class Extension;
binjine6b58b52014-10-31 01:55:5744class PermissionSet;
45
binjin5f405ef2014-09-03 21:23:1646// Tracks the management policies that affect extensions and provides interfaces
47// for observing and obtaining the global settings for all extensions, as well
48// as per-extension settings.
binjin1569c9b2014-09-05 13:33:1849class ExtensionManagement : public KeyedService {
binjin5f405ef2014-09-03 21:23:1650 public:
binjin1569c9b2014-09-05 13:33:1851 // Observer class for extension management settings changes.
52 class Observer {
53 public:
54 virtual ~Observer() {}
55
binjin81d7c552014-10-02 11:47:1256 // Called when the extension management settings change.
binjin1569c9b2014-09-05 13:33:1857 virtual void OnExtensionManagementSettingsChanged() = 0;
58 };
59
binjin5f405ef2014-09-03 21:23:1660 // Installation mode for extensions, default is INSTALLATION_ALLOWED.
61 // * INSTALLATION_ALLOWED: Extension can be installed.
62 // * INSTALLATION_BLOCKED: Extension cannot be installed.
63 // * INSTALLATION_FORCED: Extension will be installed automatically
64 // and cannot be disabled.
65 // * INSTALLATION_RECOMMENDED: Extension will be installed automatically but
66 // can be disabled.
67 enum InstallationMode {
68 INSTALLATION_ALLOWED = 0,
69 INSTALLATION_BLOCKED,
70 INSTALLATION_FORCED,
71 INSTALLATION_RECOMMENDED,
72 };
73
Sergey Poromov741e70702018-10-11 20:11:5474 explicit ExtensionManagement(Profile* profile);
dchengae36a4a2014-10-21 12:36:3675 ~ExtensionManagement() override;
binjin5f405ef2014-09-03 21:23:1676
binjine6b58b52014-10-31 01:55:5777 // KeyedService implementations:
78 void Shutdown() override;
79
binjin1569c9b2014-09-05 13:33:1880 void AddObserver(Observer* observer);
81 void RemoveObserver(Observer* observer);
82
binjine6b58b52014-10-31 01:55:5783 // Get the list of ManagementPolicy::Provider controlled by extension
84 // management policy settings.
lazyboy4aeef202016-09-07 21:28:5985 const std::vector<std::unique_ptr<ManagementPolicy::Provider>>& GetProviders()
86 const;
binjin1569c9b2014-09-05 13:33:1887
88 // Checks if extensions are blacklisted by default, by policy. When true,
89 // this means that even extensions without an ID should be blacklisted (e.g.
90 // from the command line, or when loaded as an unpacked extension).
binjin81d7c552014-10-02 11:47:1291 bool BlacklistedByDefault() const;
92
93 // Returns installation mode for an extension.
binjin685ade82014-11-06 09:53:5694 InstallationMode GetInstallationMode(const Extension* extension) const;
binjin5f405ef2014-09-03 21:23:1695
binjin30301062014-09-08 20:27:3496 // Returns the force install list, in format specified by
97 // ExternalPolicyLoader::AddExtension().
dchengc963c7142016-04-08 03:55:2298 std::unique_ptr<base::DictionaryValue> GetForceInstallList() const;
binjin30301062014-09-08 20:27:3499
binjincccacef2014-10-13 19:00:20100 // Like GetForceInstallList(), but returns recommended install list instead.
dchengc963c7142016-04-08 03:55:22101 std::unique_ptr<base::DictionaryValue> GetRecommendedInstallList() const;
binjincccacef2014-10-13 19:00:20102
Yann Dago726278c62019-03-18 14:59:55103 // Returns |true| if there is at least one extension with
104 // |INSTALLATION_ALLOWED| as installation mode. This excludes force installed
105 // extensions.
106 bool HasWhitelistedExtension() const;
107
binjinc641add2014-10-15 16:20:45108 // Returns if an extension with id |id| is explicitly allowed by enterprise
109 // policy or not.
110 bool IsInstallationExplicitlyAllowed(const ExtensionId& id) const;
binjin30301062014-09-08 20:27:34111
binjin311ecdf2014-09-12 22:56:52112 // Returns true if an extension download should be allowed to proceed.
binjin81d7c552014-10-02 11:47:12113 bool IsOffstoreInstallAllowed(const GURL& url,
114 const GURL& referrer_url) const;
binjin311ecdf2014-09-12 22:56:52115
Owen Mina9a13e12018-11-01 20:43:52116 // Returns true if an extension with manifest type |manifest_type| and
117 // id |extension_id| is allowed to be installed.
118 bool IsAllowedManifestType(Manifest::Type manifest_type,
119 const std::string& extension_id) const;
binjin5f405ef2014-09-03 21:23:16120
binjin685ade82014-11-06 09:53:56121 // Returns the list of blocked API permissions for |extension|.
122 APIPermissionSet GetBlockedAPIPermissions(const Extension* extension) const;
binjine6b58b52014-10-31 01:55:57123
nrpeter40e16382017-04-13 17:34:58124 // Returns the list of hosts blocked by policy for |extension|.
Devlin Cronin7e0f41ff2018-05-16 17:19:36125 const URLPatternSet& GetPolicyBlockedHosts(const Extension* extension) const;
nrpeter40e16382017-04-13 17:34:58126
Devlin Cronin7e0f41ff2018-05-16 17:19:36127 // Returns the hosts exempted by policy from the PolicyBlockedHosts for
nrpetere33d2a5b2017-04-25 00:12:31128 // |extension|.
Devlin Cronin7e0f41ff2018-05-16 17:19:36129 const URLPatternSet& GetPolicyAllowedHosts(const Extension* extension) const;
nrpeter40e16382017-04-13 17:34:58130
nrpetere33d2a5b2017-04-25 00:12:31131 // Returns the list of hosts blocked by policy for Default scope. This can be
Devlin Cronin7e0f41ff2018-05-16 17:19:36132 // overridden by an individual scope which is queried via
133 // GetPolicyBlockedHosts.
134 const URLPatternSet& GetDefaultPolicyBlockedHosts() const;
nrpetere33d2a5b2017-04-25 00:12:31135
Devlin Cronin7e0f41ff2018-05-16 17:19:36136 // Returns the hosts exempted by policy from PolicyBlockedHosts for
nrpetere33d2a5b2017-04-25 00:12:31137 // the default scope. This can be overridden by an individual scope which is
Devlin Cronin7e0f41ff2018-05-16 17:19:36138 // queries via GetPolicyAllowedHosts. This should only be used to
nrpetere33d2a5b2017-04-25 00:12:31139 // initialize a new renderer.
Devlin Cronin7e0f41ff2018-05-16 17:19:36140 const URLPatternSet& GetDefaultPolicyAllowedHosts() const;
nrpetere33d2a5b2017-04-25 00:12:31141
142 // Checks if an |extension| has its own runtime_blocked_hosts or
143 // runtime_allowed_hosts defined in the individual scope of the
144 // ExtensionSettings policy.
145 // Returns false if an individual scoped setting isn't defined.
Devlin Cronin7e0f41ff2018-05-16 17:19:36146 bool UsesDefaultPolicyHostRestrictions(const Extension* extension) const;
nrpetere33d2a5b2017-04-25 00:12:31147
nrpeter40e16382017-04-13 17:34:58148 // Checks if a URL is on the blocked host permissions list for a specific
149 // extension.
Devlin Cronin7e0f41ff2018-05-16 17:19:36150 bool IsPolicyBlockedHost(const Extension* extension, const GURL& url) const;
nrpeter40e16382017-04-13 17:34:58151
binjin685ade82014-11-06 09:53:56152 // Returns blocked permission set for |extension|.
dchengc963c7142016-04-08 03:55:22153 std::unique_ptr<const PermissionSet> GetBlockedPermissions(
binjin685ade82014-11-06 09:53:56154 const Extension* extension) const;
binjine6b58b52014-10-31 01:55:57155
nrpeter2362e7e2017-05-10 17:21:26156 // If the extension is blocked from install and a custom error message
157 // was defined returns it. Otherwise returns an empty string. The maximum
158 // string length is 1000 characters.
159 const std::string BlockedInstallMessage(const ExtensionId& id) const;
160
binjin685ade82014-11-06 09:53:56161 // Returns true if every permission in |perms| is allowed for |extension|.
162 bool IsPermissionSetAllowed(const Extension* extension,
rdevlin.cronine2d0fd02015-09-24 22:35:49163 const PermissionSet& perms) const;
binjine6b58b52014-10-31 01:55:57164
binjin8e3d0182014-12-04 16:44:28165 // Returns true if |extension| meets the minimum required version set for it.
166 // If there is no such requirement set for it, returns true as well.
167 // If false is returned and |required_version| is not null, the minimum
168 // required version is returned.
169 bool CheckMinimumVersion(const Extension* extension,
170 std::string* required_version) const;
171
binjin5f405ef2014-09-03 21:23:16172 private:
avi3ec9c0d2016-12-27 22:38:06173 using SettingsIdMap =
174 std::unordered_map<ExtensionId,
175 std::unique_ptr<internal::IndividualSettings>>;
176 using SettingsUpdateUrlMap =
177 std::unordered_map<std::string,
178 std::unique_ptr<internal::IndividualSettings>>;
binjin81d7c552014-10-02 11:47:12179 friend class ExtensionManagementServiceTest;
180
binjin1569c9b2014-09-05 13:33:18181 // Load all extension management preferences from |pref_service|, and
182 // refresh the settings.
183 void Refresh();
184
binjin5f405ef2014-09-03 21:23:16185 // Load preference with name |pref_name| and expected type |expected_type|.
186 // If |force_managed| is true, only loading from the managed preference store
187 // is allowed. Returns NULL if the preference is not present, not allowed to
188 // be loaded from or has the wrong type.
189 const base::Value* LoadPreference(const char* pref_name,
190 bool force_managed,
Owen Mina9a13e12018-11-01 20:43:52191 base::Value::Type expected_type) const;
binjin5f405ef2014-09-03 21:23:16192
binjin1569c9b2014-09-05 13:33:18193 void OnExtensionPrefChanged();
194 void NotifyExtensionManagementPrefChanged();
195
achuith4607f072017-03-08 11:49:13196 // Helper to return an extension install list, in format specified by
197 // ExternalPolicyLoader::AddExtension().
198 std::unique_ptr<base::DictionaryValue> GetInstallListByMode(
199 InstallationMode installation_mode) const;
200
201 // Helper to update |extension_dict| for forced installs.
202 void UpdateForcedExtensions(const base::DictionaryValue* extension_dict);
203
Owen Mina9a13e12018-11-01 20:43:52204 // Helper to update |settings_by_id_| for forced cloud reporting extension.
205 void UpdateForcedCloudReportingExtension();
206
207 // Returns true if cloud reporting policy is enabled.
208 bool IsCloudReportingPolicyEnabled() const;
209
binjin5f405ef2014-09-03 21:23:16210 // Helper function to access |settings_by_id_| with |id| as key.
211 // Adds a new IndividualSettings entry to |settings_by_id_| if none exists for
212 // |id| yet.
binjin81d7c552014-10-02 11:47:12213 internal::IndividualSettings* AccessById(const ExtensionId& id);
binjin5f405ef2014-09-03 21:23:16214
binjin685ade82014-11-06 09:53:56215 // Similar to AccessById(), but access |settings_by_update_url_| instead.
216 internal::IndividualSettings* AccessByUpdateUrl(
217 const std::string& update_url);
218
binjin5f405ef2014-09-03 21:23:16219 // A map containing all IndividualSettings applied to an individual extension
220 // identified by extension ID. The extension ID is used as index key of the
221 // map.
binjin5f405ef2014-09-03 21:23:16222 SettingsIdMap settings_by_id_;
223
binjin685ade82014-11-06 09:53:56224 // Similar to |settings_by_id_|, but contains the settings for a group of
225 // extensions with same update URL. The update url itself is used as index
226 // key for the map.
227 SettingsUpdateUrlMap settings_by_update_url_;
228
binjin5f405ef2014-09-03 21:23:16229 // The default IndividualSettings.
230 // For extension settings applied to an individual extension (identified by
231 // extension ID) or a group of extension (with specified extension update
232 // URL), all unspecified part will take value from |default_settings_|.
233 // For all other extensions, all settings from |default_settings_| will be
234 // enforced.
dchengc963c7142016-04-08 03:55:22235 std::unique_ptr<internal::IndividualSettings> default_settings_;
binjin5f405ef2014-09-03 21:23:16236
237 // Extension settings applicable to all extensions.
dchengc963c7142016-04-08 03:55:22238 std::unique_ptr<internal::GlobalSettings> global_settings_;
binjin5f405ef2014-09-03 21:23:16239
Sergey Poromov741e70702018-10-11 20:11:54240 Profile* const profile_ = nullptr;
achuith4607f072017-03-08 11:49:13241 PrefService* pref_service_ = nullptr;
242 bool is_signin_profile_ = false;
binjin5f405ef2014-09-03 21:23:16243
Trent Apteda250ec3ab2018-08-19 08:52:19244 base::ObserverList<Observer, true>::Unchecked observer_list_;
binjin1569c9b2014-09-05 13:33:18245 PrefChangeRegistrar pref_change_registrar_;
lazyboy4aeef202016-09-07 21:28:59246 std::vector<std::unique_ptr<ManagementPolicy::Provider>> providers_;
binjin1569c9b2014-09-05 13:33:18247
binjin5f405ef2014-09-03 21:23:16248 DISALLOW_COPY_AND_ASSIGN(ExtensionManagement);
249};
250
binjin1569c9b2014-09-05 13:33:18251class ExtensionManagementFactory : public BrowserContextKeyedServiceFactory {
252 public:
253 static ExtensionManagement* GetForBrowserContext(
254 content::BrowserContext* context);
255 static ExtensionManagementFactory* GetInstance();
256
257 private:
olli.raula36aa8be2015-09-10 11:14:22258 friend struct base::DefaultSingletonTraits<ExtensionManagementFactory>;
binjin1569c9b2014-09-05 13:33:18259
260 ExtensionManagementFactory();
dchengae36a4a2014-10-21 12:36:36261 ~ExtensionManagementFactory() override;
binjin1569c9b2014-09-05 13:33:18262
263 // BrowserContextKeyedServiceExtensionManagementFactory:
dchengae36a4a2014-10-21 12:36:36264 KeyedService* BuildServiceInstanceFor(
mostynba15bee12014-10-04 00:40:32265 content::BrowserContext* context) const override;
dchengae36a4a2014-10-21 12:36:36266 content::BrowserContext* GetBrowserContextToUse(
mostynba15bee12014-10-04 00:40:32267 content::BrowserContext* context) const override;
dchengae36a4a2014-10-21 12:36:36268 void RegisterProfilePrefs(
mostynba15bee12014-10-04 00:40:32269 user_prefs::PrefRegistrySyncable* registry) override;
binjin1569c9b2014-09-05 13:33:18270
271 DISALLOW_COPY_AND_ASSIGN(ExtensionManagementFactory);
272};
273
binjin5f405ef2014-09-03 21:23:16274} // namespace extensions
275
276#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_MANAGEMENT_H_