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
|
// Copyright 2025 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_UI_SAFETY_HUB_UNUSED_SITE_PERMISSIONS_MANAGER_H_
#define CHROME_BROWSER_UI_SAFETY_HUB_UNUSED_SITE_PERMISSIONS_MANAGER_H_
#include <memory>
#include <optional>
#include <set>
#include <string>
#include "base/memory/scoped_refptr.h"
#include "base/time/clock.h"
#include "base/values.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/ui/safety_hub/revoked_permissions_result.h"
#include "chrome/browser/ui/safety_hub/safety_hub_result.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings_constraints.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
class PrefChangeRegistrar;
class PrefService;
namespace url {
class Origin;
}
// This class keeps track of unused site permissions by updating
// their last_visit date on navigations and clearing them periodically.
class UnusedSitePermissionsManager {
public:
explicit UnusedSitePermissionsManager(
content::BrowserContext* browser_context,
PrefService* prefs);
UnusedSitePermissionsManager(const UnusedSitePermissionsManager&) = delete;
UnusedSitePermissionsManager& operator=(const UnusedSitePermissionsManager&) =
delete;
~UnusedSitePermissionsManager();
// Does most of the heavy lifting of the update process: for each permission,
// it determines whether it should be considered as recently unused (i.e. one
// week). This list will be further filtered in the UI task to determine which
// permissions should be revoked.
static std::unique_ptr<SafetyHubResult> UpdateOnBackgroundThread(
base::Clock* clock,
const scoped_refptr<HostContentSettingsMap> hcsm);
// Helper to convert content settings type into its string representation.
static std::string ConvertContentSettingsTypeToKey(ContentSettingsType type);
// Helper to get content settings type from its string representation.
static ContentSettingsType ConvertKeyToContentSettingsType(
const std::string& key);
// Helper to convert single origin primary pattern to an origin.
// Converting a primary pattern to an origin is normally an anti-pattern, and
// this method should only be used for single origin primary patterns.
// They have fully defined URL+scheme+port which makes converting
// a primary pattern to an origin successful.
static url::Origin ConvertPrimaryPatternToOrigin(
const ContentSettingsPattern& primary_pattern);
// Revokes permissions from sites whose last visit is older than a defined
// threshold (e.g. currently 60 days).
void RevokeUnusedPermissions(std::unique_ptr<SafetyHubResult> result);
// Returns true if settings are being changed due to auto revocation of
// unused site permissions.
bool IsRevocationRunning();
// Called by TabHelper when a URL was visited.
void OnPageVisited(const url::Origin& origin);
// Re-grants permissions that are auto-revoked ones and removes the origin
// from revoked permissions list.
void RegrantPermissionsForOrigin(const url::Origin& origin);
// Reverse changes made by |RegrantPermissionsForOrigin|. Adds this origin to
// the removed permissions list and resets its permissions.
void UndoRegrantPermissionsForOrigin(const PermissionsData& permission);
// Removes a pattern from the list of revoked permissions so that the entry is
// no longer shown to the user. Does not affect permissions themselves.
void DeletePatternFromRevokedUnusedSitePermissionList(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern);
// Stores revoked permissions data on HCSM.
void StorePermissionInUnusedSitePermissionSetting(
const std::set<ContentSettingsType>& permissions,
const base::Value::Dict& chooser_permissions_data,
const std::optional<content_settings::ContentSettingConstraints>
constraint,
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern);
// Test support:
void SetClockForTesting(base::Clock* clock);
std::vector<ContentSettingEntry> GetTrackedUnusedPermissionsForTesting();
using UnusedPermissionMap = RevokedPermissionsResult::UnusedPermissionMap;
private:
FRIEND_TEST_ALL_PREFIXES(UnusedSitePermissionsManagerTest,
UpdateIntegerValuesToGroupName_AllContentSettings);
FRIEND_TEST_ALL_PREFIXES(
UnusedSitePermissionsManagerTest,
UpdateIntegerValuesToGroupName_SubsetOfContentSettings);
FRIEND_TEST_ALL_PREFIXES(
UnusedSitePermissionsManagerTest,
UpdateIntegerValuesToGroupName_UnknownContentSettings);
// If the user clicked "Allow again" for an auto-revoked origin, the
// permissions for that site should not be auto-revoked again by the service.
void IgnoreOriginForAutoRevocation(const url::Origin& origin);
// Convert all integer permission values to string, if there is any
// permission represented by integer.
void UpdateIntegerValuesToGroupName();
// Pointer to an object that allows us to manage site permissions.
HostContentSettingsMap* hcsm() {
return HostContentSettingsMapFactory::GetForProfile(browser_context_.get());
}
// Pointer to a browser context whose permissions are being updated.
raw_ptr<content::BrowserContext> browser_context_;
// Observes user profile prefs.
std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
// Set of permissions that haven't been used for at least a week.
UnusedPermissionMap recently_unused_permissions_;
// Returns true if automatic check and revocation of unused site permissions
// is occurring. This value is used in `OnContentSettingChanged` to help
// decide whether to clean up revoked permission data.
bool is_unused_site_revocation_running_ = false;
// Clock to implement revocation based on last visited time.
raw_ptr<base::Clock> clock_;
};
#endif // CHROME_BROWSER_UI_SAFETY_HUB_UNUSED_SITE_PERMISSIONS_MANAGER_H_
|