File: supervised_user_extensions_manager.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (204 lines) | stat: -rw-r--r-- 8,962 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_EXTENSIONS_MANAGER_H_
#define CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_EXTENSIONS_MANAGER_H_

#include <set>
#include <string>

#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "components/prefs/pref_change_registrar.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/browser/management_policy.h"

namespace content {
class BrowserContext;
}  // namespace content

namespace extensions {
class Extension;
class ExtensionPrefs;
class ExtensionSystem;
class ExtensionRegistry;

// UMA metrics for auto-approved extensions.
inline constexpr char
    kInitialLocallyApprovedExtensionCountWinLinuxMacHistogramName[] =
        "SupervisedUsers.InitialLocallyApprovedExtensionsCountOnWinLinuxMac";
inline constexpr char kExtensionApprovalsCountOnExtensionToggleHistogramName[] =
    "SupervisedUsers.ExtensionApprovalsCountOnExtensionToggle";

// This class groups all the functionality to handle extensions
// for supervised users.
class SupervisedUserExtensionsManager : public ExtensionRegistryObserver,
                                        public ManagementPolicy::Provider {
 public:
  explicit SupervisedUserExtensionsManager(content::BrowserContext* context);
  SupervisedUserExtensionsManager(const SupervisedUserExtensionsManager&) =
      delete;
  SupervisedUserExtensionsManager& operator=(
      const SupervisedUserExtensionsManager&) = delete;
  ~SupervisedUserExtensionsManager() override;

  // Updates registration of this class as a management policy provider
  // for supervised users. It needs to be called after
  // extension::ManagementPolicy has been set.
  void UpdateManagementPolicyRegistration();

  // Updates the set of approved extensions to add approval for `extension`.
  void AddExtensionApproval(const Extension& extension);

  // Checks if the extension escalated permissions during an upgrade
  // and records the corresponding metrics.
  void MaybeRecordPermissionsIncreaseMetrics(const extensions::Extension& extension);

  // Updates the set of approved extensions to remove approval for `extension`.
  void RemoveExtensionApproval(const Extension& extension);

  // Returns whether the extension is allowed by the parent.
  bool IsExtensionAllowed(const Extension& extension) const;

  // Returns whether the supervised user can install extensions.
  // If the feature that allows skipping parent approval is enabled, supervised
  // user are always allowed to install extensions.
  // If the feature is disabled, the permission to install is based on existing
  // Family Link parental controls ("Permissions" switch).
  bool CanInstallExtensions() const;

  // Records the state of extension approvals.
  void RecordExtensionEnablementUmaMetrics(bool enabled) const;

  // extensions::ManagementPolicy::Provider implementation:
  std::string GetDebugPolicyProviderName() const override;
  bool UserMayLoad(const Extension* extension,
                   std::u16string* error) const override;
  bool MustRemainDisabled(const Extension* extension,
                          disable_reason::DisableReason* reason) const override;

  // extensions::ExtensionRegistryObserver overrides:
  void OnExtensionInstalled(content::BrowserContext* browser_context,
                            const Extension* extension,
                            bool is_update) override;
  void OnExtensionUninstalled(content::BrowserContext* browser_context,
                              const Extension* extension,
                              UninstallReason reason) override;

 private:
  // These enum values represent operations to manage the
  // kSupervisedUserApprovedExtensions user pref, which stores parent approved
  // extension ids.
  enum class ApprovedExtensionChange {
    // Adds a new approved extension to the pref.
    kAdd,
    // Removes extension approval.
    kRemove
  };

  // An extension can be in one of the following states:
  //
  // BLOCKED: if kSupervisedUserExtensionsMayRequestPermissions is false and the
  // child user is attempting to install a new extension or an existing
  // extension is asking for additional permissions.
  // ALLOWED: Components, Themes, Default extensions ..etc
  //    are generally allowed.  Extensions that have been approved by the
  //    custodian are also allowed.
  // REQUIRE_APPROVAL: if it is installed by the child user and
  //    hasn't been approved by the custodian yet.
  enum class ExtensionState { BLOCKED, ALLOWED, REQUIRE_APPROVAL };

  // Returns the state of an extension whether being BLOCKED, ALLOWED or
  // REQUIRE_APPROVAL from the Supervised User service's point of view.
  ExtensionState GetExtensionState(const Extension& extension) const;

  // Updates the set of approved extensions when the preference is changed.
  void RefreshApprovedExtensionsFromPrefs();

  // Activates the extension manager for supervised users.
  void SetActiveForSupervisedUsers();

  // Marks the class as active manegment policy provider for supervised users
  // and updates management policy registration.
  void ActivateManagementPolicyAndUpdateRegistration();

  // Updates the synced set of approved extension ids.
  // Use AddExtensionApproval() or RemoveExtensionApproval() for public access.
  // If `type` is kAdd, then add approval.
  // If `type` is kRemove, then remove approval.
  // Triggers a call to RefreshApprovedExtensionsFromPrefs() via a listener.
  // TODO(crbug.com/40685974): We don't need the extension version information.
  // It's only included for backwards compatibility with previous versions of
  // Chrome. Remove the version information once a sufficient number of users
  // have migrated away from M83.
  void UpdateApprovedExtension(const std::string& extension_id,
                               const std::string& version,
                               ApprovedExtensionChange type);

  // Returns a message saying that extensions can only be modified by the
  // custodian.
  std::u16string GetExtensionsLockedMessage() const;

  // Enables/Disables extensions upon change in approvals. This function is
  // idempotent.
  void ChangeExtensionStateIfNecessary(const std::string& extension_id);

  // Returns whether we should block an extension.
  // If the toggle "Permissions for sites, apps and extensions" toggle
  // is used to manage supervised user extensions, the result depends on the
  // value of the toggle.
  // If the new toggle "Extensions" is used to manage supervised user
  // extensions, this method return always false.
  // TODO(b/321239324): De-release when the "Extensions" toggle-management is
  // launched.
  bool ShouldBlockExtension(const std::string& extension_id) const;

#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
  // Triggers an one-time migration of the present extensions as parent-approved
  // when the feature
  // `kEnableSupervisedUserSkipParentApprovalToInstallExtensions` becomes
  // enabled.
  void MaybeMarkExtensionsLocallyParentApproved();

  // Marks the extensions available to the child user as locally parent-approved
  // on a preference on this device.
  void DoExtensionsMigrationToParentApproved();
#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)

  // Returns true if the given `extension_id` has been marked locally parent
  // approved.
  bool IsLocallyParentApprovedExtension(const std::string& extension_id) const;

  // Removes from the locally approved extension preference the given
  // `extension_ids`. The input `extension_ids` doesn't have to be a subset of
  // the locally approved extensions: the method will remove those that are
  // locally approved and ignore the rest.
  void RemoveLocalParentalApproval(const std::set<std::string>& extension_ids);

  // Handles the parent-approval state of the present extensions,
  // whenever the parent changes the value of the FL "Extension" switch.
  void OnSkipParentApprovalToInstallExtensionsChanged();

  // The current state of registration of this class as a management policy.
  bool is_active_policy_for_supervised_users_ = false;

  const raw_ptr<content::BrowserContext> context_;
  raw_ptr<ExtensionPrefs> extension_prefs_;
  raw_ptr<ExtensionSystem> extension_system_;
  raw_ptr<ExtensionRegistry> extension_registry_;
  raw_ptr<PrefService> user_prefs_;

  PrefChangeRegistrar pref_change_registrar_;

  // Store a set of extension ids approved by the custodian.
  // It is only relevant for SU-initiated installs.
  std::set<std::string> approved_extensions_set_;

  base::ScopedObservation<ExtensionRegistry, ExtensionRegistryObserver>
      registry_observation_{this};
};

}  // namespace extensions

#endif  // CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_EXTENSIONS_MANAGER_H_