blob: e03ec89e4f2965af1b0f9d4c40d4cb703e88c6d2 [file] [log] [blame]
// 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_