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
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_ASH_COMPONENTS_SPECIALIZED_FEATURES_FEATURE_ACCESS_CHECKER_H_
#define CHROMEOS_ASH_COMPONENTS_SPECIALIZED_FEATURES_FEATURE_ACCESS_CHECKER_H_
#include <vector>
#include "base/component_export.h"
#include "base/containers/enum_set.h"
#include "base/feature_list.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "components/prefs/pref_service.h"
#include "components/signin/public/identity_manager/account_capabilities.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/variations/service/variations_service.h"
namespace specialized_features {
// FeatureAccessFailures are the types of failures returned by a
// FeatureAccessChecker. They indicate which configured checks failed.
enum class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_SPECIALIZED_FEATURES)
FeatureAccessFailure {
kMinValue = 0,
kConsentNotAccepted = kMinValue, // User consent not given
kDisabledInSettings, // Settings toggle is off
kFeatureFlagDisabled, // The feature flag disabled.
kFeatureManagementCheckFailed, // FeatureManagement flag was not enabled.
kSecretKeyCheckFailed, // Secret key required and was not valid.
kAccountCapabilitiesCheckFailed, // Does not have required account
// capabilities, which is a proxy to
// check user requirements such as the
// user inferred not to be a minor.
kCountryCheckFailed, // Device's country is not authorised
// to use this feature.
kDisabledInKioskModeCheckFailed, // In Kiosk mode.
kMaxValue = kDisabledInKioskModeCheckFailed,
};
// EnumSet containing FeatureAccessFailures.
using FeatureAccessFailureSet = base::EnumSet<FeatureAccessFailure,
FeatureAccessFailure::kMinValue,
FeatureAccessFailure::kMaxValue>;
// Represents a secret key used to allow users to access a feature.
struct COMPONENT_EXPORT(
CHROMEOS_ASH_COMPONENTS_SPECIALIZED_FEATURES) SecretKey {
// Name of the flag.
std::string flag;
// The hashed value of the key.
std::string sha1_hashed_key_value;
};
// This configures the FeatureAccessChecker for different types of common
// specialized feature checks.
struct COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_SPECIALIZED_FEATURES)
FeatureAccessConfig {
FeatureAccessConfig();
~FeatureAccessConfig();
FeatureAccessConfig(const FeatureAccessConfig&);
FeatureAccessConfig& operator=(const FeatureAccessConfig&);
FeatureAccessConfig& operator=(FeatureAccessConfig&&);
// Disable for kiosk mode.
bool disabled_in_kiosk_mode = false;
// The preference that determines whether the feature is enabled via settings.
// The FeatureAccessChecker::Check() verifies if its value is true in the
// given prefs, and returns kDisabledInSettings if not.
std::optional<std::string> settings_toggle_pref;
// The preference that deterimines whether the features legal consent
// disclaimer has been accepted. The FeatureAccessChecker::Check() verifies
// if its value is true in the given prefs, and returns kConsentNotAccepted if
// not.
std::optional<std::string> consent_accepted_pref;
// The main feature flag that is used to enable/disable the feature itself.
// The FeatureAccessChecker::Check() verifies if its value is true and returns
// kFeatureFlagDisabled if not.
// Since feature flags are not copyable, we have to use a pointer.
// This is safe for feature flags declared by `BASE_FEATURE` and
// `BASE_DECLARE_FEATURE` since they are created-module level and never
// destroyed.
raw_ptr<const base::Feature> feature_flag = nullptr;
// This is for the feature flag that is related to the ChromeOS feature
// management system. The FeatureAccessChecker::Check() verifies if its value
// is true and returns kFeatureManagementCheckFailed if not.
// Since feature flags are not copyable, we have to use a pointer.
// This is safe for feature flags declared by `BASE_FEATURE` and
// `BASE_DECLARE_FEATURE` since they are created-module level and never
// destroyed.
raw_ptr<const base::Feature> feature_management_flag = nullptr;
// Only these country codes are allowed. If empty, allows all country codes.
std::vector<std::string> country_codes;
// Special key used to guard users from accessing the feature.
// FeatureAccessChecker::Check() only checks this special key if the optional
// value is set since secret keys could be removed.
// FeatureAccessChecker::Check() will return kSecretKeyCheckFailed if this
// value is set and the secret key check fails.
std::optional<SecretKey> secret_key;
// Allow googlers to override the secret_key check.
bool allow_google_accounts_skip_secret_key = false;
// If not null, it will check if the account has the required account
// capabilities. This is used as a proxy to check user capability requirements
// such as whether the user is NOT inferred to be a minor.
// FeatureAccessChecker::Check() will return
// kAccountCapabilitiesCheckFailed if the return value is not
// signin::Tribool::kTrue.
// Example usage:
// config.capability_callback =
// base::BindRepeating([](AccountCapabilities capabilities) {
// return capabilities.can_use_manta_service();
// });
base::RepeatingCallback<signin::Tribool(AccountCapabilities capabilities)>
capability_callback;
};
// Creates a class to check different dependencies for specialized features.
class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_SPECIALIZED_FEATURES)
FeatureAccessChecker {
public:
using VariationsServiceCallback =
base::RepeatingCallback<variations::VariationsService*()>;
// The config determines which dependencies to check.
// The following objects should not be destroyed before this class is
// destroyed:
// - prefs
// - identity_manager
// If any checks require the above dependency and it is destroy, the check
// will return a failure.
FeatureAccessChecker(FeatureAccessConfig config,
PrefService* prefs,
signin::IdentityManager* identity_manager,
VariationsServiceCallback variations_service_callback);
FeatureAccessChecker(const FeatureAccessChecker&) = delete;
FeatureAccessChecker& operator=(const FeatureAccessChecker&) = delete;
virtual ~FeatureAccessChecker();
// Uses the set config and dependencies to check. Returns a list of errors.
// For details of errors, please refer the comments of FeatureAccessConfig.
virtual FeatureAccessFailureSet Check() const;
protected:
// Constructor for mock subclass.
FeatureAccessChecker();
private:
FeatureAccessConfig config_;
// The following raw_ptrs are not owned by this class.
raw_ptr<const PrefService> prefs_;
raw_ptr<const signin::IdentityManager> identity_manager_;
VariationsServiceCallback variations_service_callback_;
};
} // namespace specialized_features
#endif // CHROMEOS_ASH_COMPONENTS_SPECIALIZED_FEATURES_FEATURE_ACCESS_CHECKER_H_
|