Make policy load on startup without an async delay (#35337)

* Block brave://wallet WebUI on desktop when disabled by policy

Previously, the wallet WebUI on desktop relied solely on
WalletPageUIConfig::IsWebUIEnabled() to prevent loading when wallet is
disabled by policy (e.g. via Brave Origin). Unlike brave://rewards which
has a second check in GetWebUIType(), wallet lacked this, allowing the
page to load and fail with "Mojo is not defined".

Add an IsAllowedForContext check in GetWebUIType() for wallet page and
panel hosts on desktop, matching the rewards blocking pattern.

* Format: fix line wrapping in wallet WebUI block

* Block wallet WebUI when BraveOrigin feature is enabled

The previous IsAllowedForContext check only blocked wallet when the
managed pref was set by admin policy. BraveOrigin policies are only
loaded after purchase verification, so enabling BraveOrigin via feature
flag without purchase left wallet accessible.

Add IsBraveOriginFeatureEnabled() check to GetWebUIType(),
WalletPageUIConfig::IsWebUIEnabled, and
WalletPanelUIConfig::IsWebUIEnabled to block wallet WebUI in all
BraveOrigin configurations.

* Use persisted purchase pref for IsPurchased check

BraveOriginPolicyManager::IsPurchased() only returned true after the
async SKU credential check completed. On startup, this meant policies
weren't applied yet when wallet WebUI tried to load.

Fall back to the kOriginPurchaseValidated local state pref so policies
are applied immediately on startup. Remove BraveOrigin-specific checks
from wallet code — the admin policy pref check is sufficient.
This commit is contained in:
Brian R. Bondy
2026-04-08 14:36:56 -04:00
committed by GitHub
parent 3660b3622a
commit 2d66ca65bc
6 changed files with 42 additions and 4 deletions
@@ -71,8 +71,8 @@
#endif
#if BUILDFLAG(ENABLE_BRAVE_WALLET)
#if !BUILDFLAG(IS_ANDROID)
#include "brave/browser/brave_wallet/brave_wallet_context_utils.h"
#if !BUILDFLAG(IS_ANDROID)
#include "brave/browser/ui/webui/brave_wallet/wallet_page_ui.h"
#include "brave/components/brave_wallet/browser/brave_wallet_utils.h"
#include "brave/components/brave_wallet/common/brave_wallet.mojom.h"
@@ -268,11 +268,18 @@ WebUI::TypeID BraveWebUIControllerFactory::GetWebUIType(
return WebUI::kNoWebUI;
}
#endif // BUILDFLAG(ENABLE_BRAVE_REWARDS)
#if BUILDFLAG(IS_ANDROID) && BUILDFLAG(ENABLE_BRAVE_WALLET)
#if BUILDFLAG(ENABLE_BRAVE_WALLET)
#if BUILDFLAG(IS_ANDROID)
if (ShouldBlockWalletWebUI(browser_context, url)) {
return WebUI::kNoWebUI;
}
#endif // BUILDFLAG(IS_ANDROID) && BUILDFLAG(ENABLE_BRAVE_WALLET)
#else
if ((url.host() == kWalletPageHost || url.host() == kWalletPanelHost) &&
!brave_wallet::IsAllowedForContext(browser_context)) {
return WebUI::kNoWebUI;
}
#endif // BUILDFLAG(IS_ANDROID)
#endif // BUILDFLAG(ENABLE_BRAVE_WALLET)
#if BUILDFLAG(ENABLE_PLAYLIST_WEBUI)
if (base::FeatureList::IsEnabled(playlist::features::kPlaylist)) {
if (playlist::PlaylistUI::ShouldBlockPlaylistWebUI(browser_context, url)) {
@@ -172,13 +172,26 @@ void BraveOriginPolicyManager::SetPurchased(bool purchased) {
return;
}
is_purchased_ = purchased;
// Persist purchase state so policies can be applied immediately on next
// startup, before the async SKU credential check completes.
if (local_state_) {
local_state_->SetBoolean(kOriginPurchaseValidated, purchased);
}
if (initialized_) {
observers_.Notify(&brave_policy::BravePolicyObserver::OnBravePoliciesReady);
}
}
bool BraveOriginPolicyManager::IsPurchased() const {
return is_purchased_;
if (is_purchased_) {
return true;
}
// Fall back to persisted pref so policies are applied immediately on startup,
// before the async purchase verification completes.
if (local_state_) {
return local_state_->GetBoolean(kOriginPurchaseValidated);
}
return false;
}
void BraveOriginPolicyManager::Shutdown() {
@@ -35,6 +35,8 @@ class BraveOriginPolicyManagerTest : public testing::Test {
void SetUp() override {
pref_service_.registry()->RegisterDictionaryPref(kBraveOriginPolicies);
pref_service_.registry()->RegisterBooleanPref(kOriginPurchaseValidated,
false);
}
void TearDown() override {
@@ -53,6 +53,8 @@ class BraveOriginServiceTest : public testing::Test {
// Register the BraveOrigin policies dictionary pref in local_state
local_state_.registry()->RegisterDictionaryPref(kBraveOriginPolicies);
local_state_.registry()->RegisterBooleanPref(kOriginPurchaseValidated,
false);
// Register test browser preferences in local_state
// These are needed because BraveOriginService::SetBrowserPolicyValue()
@@ -512,6 +514,8 @@ class BraveOriginServiceWithSkusTest : public testing::Test {
feature_list_.InitAndEnableFeature(features::kBraveOrigin);
local_state_.registry()->RegisterDictionaryPref(kBraveOriginPolicies);
local_state_.registry()->RegisterBooleanPref(kOriginPurchaseValidated,
false);
local_state_.registry()->RegisterBooleanPref(kTestBrowserPref, false);
profile_prefs_.registry()->RegisterBooleanPref(kTestProfilePref, true);
@@ -692,6 +696,8 @@ class BraveOriginServiceDisabledTest : public testing::Test {
// Register the BraveOrigin policies dictionary pref in local_state
local_state_.registry()->RegisterDictionaryPref(kBraveOriginPolicies);
local_state_.registry()->RegisterBooleanPref(kOriginPurchaseValidated,
false);
// Register test preferences (needed for pref service not to crash)
local_state_.registry()->RegisterBooleanPref(kTestBrowserPref, false);
@@ -51,6 +51,8 @@ class BraveOriginHandlerTest : public testing::Test {
// Register the BraveOrigin policies dictionary pref in local_state
local_state_.registry()->RegisterDictionaryPref(kBraveOriginPolicies);
local_state_.registry()->RegisterBooleanPref(kOriginPurchaseValidated,
false);
// Register test browser preferences in local_state
local_state_.registry()->RegisterBooleanPref(kTestBrowserPrefName, false);
@@ -324,6 +326,8 @@ class BraveOriginHandlerWithSkusTest : public testing::Test {
feature_list_.InitAndEnableFeature(features::kBraveOrigin);
local_state_.registry()->RegisterDictionaryPref(kBraveOriginPolicies);
local_state_.registry()->RegisterBooleanPref(kOriginPurchaseValidated,
false);
local_state_.registry()->RegisterBooleanPref(kTestBrowserPrefName, false);
profile_prefs_.registry()->RegisterBooleanPref(kTestProfilePrefName, true);
@@ -441,6 +445,8 @@ class BraveOriginHandlerDisabledTest : public testing::Test {
// Register the BraveOrigin policies dictionary pref in local_state
local_state_.registry()->RegisterDictionaryPref(kBraveOriginPolicies);
local_state_.registry()->RegisterBooleanPref(kOriginPurchaseValidated,
false);
// Register test preferences (needed for pref service not to crash)
local_state_.registry()->RegisterBooleanPref(kTestBrowserPrefName, false);
@@ -48,6 +48,8 @@ TEST_F(BraveOriginUtilsTest,
scoped_feature_list_.InitAndEnableFeature(features::kBraveOrigin);
pref_service_.registry()->RegisterDictionaryPref(kBraveOriginPolicies);
pref_service_.registry()->RegisterBooleanPref(kOriginPurchaseValidated,
false);
auto* manager = BraveOriginPolicyManager::GetInstance();
manager->Init(BraveOriginPolicyMap(), BraveOriginPolicyMap(), &pref_service_);
@@ -59,6 +61,8 @@ TEST_F(BraveOriginUtilsTest, IsBraveOriginPurchased_FeatureEnabled_Purchased) {
scoped_feature_list_.InitAndEnableFeature(features::kBraveOrigin);
pref_service_.registry()->RegisterDictionaryPref(kBraveOriginPolicies);
pref_service_.registry()->RegisterBooleanPref(kOriginPurchaseValidated,
false);
auto* manager = BraveOriginPolicyManager::GetInstance();
manager->Init(BraveOriginPolicyMap(), BraveOriginPolicyMap(), &pref_service_);
manager->SetPurchased(true);