Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Process wallet permission requests in FIFO order instead of fixed order of Accepted->Denied->Cancelled (uplift to 1.53.x) #18932

Merged
merged 1 commit into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions browser/permissions/permission_manager_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/ranges/algorithm.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "brave/components/brave_wallet/browser/permission_utils.h"
#include "brave/components/brave_wallet/common/features.h"
Expand Down Expand Up @@ -38,6 +39,8 @@
#include "url/gurl.h"
#include "url/origin.h"

using testing::ElementsAreArray;

namespace permissions {

namespace {
Expand Down Expand Up @@ -169,9 +172,16 @@ IN_PROC_BROWSER_TEST_F(PermissionManagerBrowserTest, RequestPermissions) {
auto observer = std::make_unique<PermissionRequestManagerObserver>(
permission_request_manager);

base::MockCallback<base::OnceCallback<void(
const std::vector<blink::mojom::PermissionStatus>&)>>
callback;
EXPECT_CALL(callback,
Run(ElementsAreArray({blink::mojom::PermissionStatus::ASK,
blink::mojom::PermissionStatus::ASK})))
.Times(1);
permission_manager()->RequestPermissionsForOrigin(
permissions, web_contents()->GetPrimaryMainFrame(), origin.GetURL(),
true, base::DoNothing());
true, callback.Get());

content::RunAllTasksUntilIdle();

Expand All @@ -193,6 +203,7 @@ IN_PROC_BROWSER_TEST_F(PermissionManagerBrowserTest, RequestPermissions) {

// Test dismissing request.
permissions::BraveWalletPermissionContext::Cancel(web_contents());
testing::Mock::VerifyAndClearExpectations(&callback);
EXPECT_TRUE(observer->IsRequestsFinalized()) << "case: " << i;
EXPECT_TRUE(!observer->IsShowingBubble()) << "case: " << i;
EXPECT_TRUE(IsPendingGroupedRequestsEmpty(cases[i].type)) << "case: " << i;
Expand All @@ -206,9 +217,14 @@ IN_PROC_BROWSER_TEST_F(PermissionManagerBrowserTest, RequestPermissions) {
}

observer->Reset();
EXPECT_CALL(
callback,
Run(ElementsAreArray({blink::mojom::PermissionStatus::ASK,
blink::mojom::PermissionStatus::GRANTED})))
.Times(1);
permission_manager()->RequestPermissionsForOrigin(
permissions, web_contents()->GetPrimaryMainFrame(), origin.GetURL(),
true, base::DoNothing());
true, callback.Get());

content::RunAllTasksUntilIdle();
EXPECT_TRUE(permission_request_manager->IsRequestInProgress())
Expand All @@ -232,6 +248,7 @@ IN_PROC_BROWSER_TEST_F(PermissionManagerBrowserTest, RequestPermissions) {
std::vector<std::string>{addresses[1]},
brave_wallet::mojom::PermissionLifetimeOption::kForever,
web_contents());
testing::Mock::VerifyAndClearExpectations(&callback);
std::vector<ContentSetting> expected_settings(
{ContentSetting::CONTENT_SETTING_ASK,
ContentSetting::CONTENT_SETTING_ALLOW});
Expand Down
29 changes: 17 additions & 12 deletions chromium_src/components/permissions/permission_request_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <string>

#include "base/containers/contains.h"
#include "brave/components/brave_wallet/browser/permission_utils.h"
#include "src/components/permissions/permission_request_manager.cc"
#include "url/origin.h"
Expand Down Expand Up @@ -34,7 +35,8 @@ bool PermissionRequestManager::ShouldGroupRequests(PermissionRequest* a,

// Accept/Deny/Cancel each sub-request, total size of all passed in requests
// should be equal to current requests_size because we will finalizing all
// current requests in the end.
// current requests in the end. The request callbacks will be called in FIFO
// order.
void PermissionRequestManager::AcceptDenyCancel(
const std::vector<PermissionRequest*>& accepted_requests,
const std::vector<PermissionRequest*>& denied_requests,
Expand All @@ -46,17 +48,20 @@ void PermissionRequestManager::AcceptDenyCancel(
DCHECK((accepted_requests.size() + denied_requests.size() +
cancelled_requests.size()) == requests_.size());

for (PermissionRequest* request : accepted_requests) {
PermissionGrantedIncludingDuplicates(request,
/*is_one_time=*/false);
}

for (PermissionRequest* request : denied_requests) {
PermissionDeniedIncludingDuplicates(request);
}

for (PermissionRequest* request : cancelled_requests) {
CancelledIncludingDuplicates(request);
// We need to process requests in reverse order because
// PermissionRequestQueue impelementation of Push and Pop are paired with
// base::circular_dequeue's (push_back, pop_back) and (push_front, pop_front)
// Once pending_permission_requests_ is popped to the vector request_, the
// order is fixed because the reorder takes place in
// pending_permission_requests_.
for (auto it = requests_.crbegin(); it != requests_.crend(); ++it) {
if (base::Contains(accepted_requests, *it)) {
PermissionGrantedIncludingDuplicates(*it, /*is_one_time=*/false);
} else if (base::Contains(denied_requests, *it)) {
PermissionDeniedIncludingDuplicates(*it);
} else {
CancelledIncludingDuplicates(*it);
}
}

// Finalize permission with granted if some sub-requests are accepted. If
Expand Down