Commit 893ce4b5 authored by Balazs Engedy's avatar Balazs Engedy Committed by Commit Bot

Implement CrowdDenySafeBrowsingRequest.

CrowdDenySafeBrowsingRequest interfaces with Safe Browsing to fetch
whether a certain origin is known to show unsolicited notification
permission requests to users.

Bug: 1028642
Change-Id: I9942350500e88115b0d2f42954222423d0eddd63
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1940253
Commit-Queue: Balazs Engedy <engedy@chromium.org>
Reviewed-by: default avatarVarun Khaneja <vakh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#719913}
parent a85a1b28
...@@ -1170,6 +1170,8 @@ jumbo_static_library("browser") { ...@@ -1170,6 +1170,8 @@ jumbo_static_library("browser") {
"permissions/adaptive_notification_permission_ui_selector.h", "permissions/adaptive_notification_permission_ui_selector.h",
"permissions/chooser_context_base.cc", "permissions/chooser_context_base.cc",
"permissions/chooser_context_base.h", "permissions/chooser_context_base.h",
"permissions/crowd_deny_safe_browsing_request.cc",
"permissions/crowd_deny_safe_browsing_request.h",
"permissions/permission_context_base.cc", "permissions/permission_context_base.cc",
"permissions/permission_context_base.h", "permissions/permission_context_base.h",
"permissions/permission_decision_auto_blocker.cc", "permissions/permission_decision_auto_blocker.cc",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/permissions/crowd_deny_safe_browsing_request.h"
#include <utility>
#include "base/bind.h"
#include "base/location.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/task_runner.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/timer/timer.h"
#include "components/safe_browsing/db/database_manager.h"
#include "content/public/browser/browser_task_traits.h"
#include "url/origin.h"
namespace {
// The permission identifier string used by Safe Browsing for notifications.
constexpr char kSafeBrowsingNotificationPermissionName[] = "NOTIFICATIONS";
// The maximum amount of time to wait for the Safe Browsing response.
constexpr base::TimeDelta kSafeBrowsingCheckTimeout =
base::TimeDelta::FromSeconds(2);
} // namespace
// CrowdDenySafeBrowsingRequest::SafeBrowsingClient --------------------------
class CrowdDenySafeBrowsingRequest::SafeBrowsingClient
: public safe_browsing::SafeBrowsingDatabaseManager::Client {
public:
SafeBrowsingClient(scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
database_manager,
base::WeakPtr<CrowdDenySafeBrowsingRequest> handler,
scoped_refptr<base::TaskRunner> handler_task_runner)
: database_manager_(database_manager),
handler_(handler),
handler_task_runner_(handler_task_runner) {}
~SafeBrowsingClient() override {
if (timeout_.IsRunning())
database_manager_->CancelApiCheck(this);
}
void CheckOrigin(const url::Origin& origin) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
if (!database_manager_->IsSupported() ||
database_manager_->CheckApiBlacklistUrl(origin.GetURL(), this)) {
SendResultToHandler(Verdict::kAcceptable);
} else {
timeout_.Start(FROM_HERE, kSafeBrowsingCheckTimeout, this,
&SafeBrowsingClient::OnTimeout);
}
}
private:
SafeBrowsingClient(const SafeBrowsingClient&) = delete;
SafeBrowsingClient& operator=(const SafeBrowsingClient&) = delete;
static Verdict ExtractVerdictFromMetadata(
const safe_browsing::ThreatMetadata& metadata) {
return metadata.api_permissions.count(
kSafeBrowsingNotificationPermissionName)
? Verdict::kKnownToShowUnsolicitedNotificationPermissionRequests
: Verdict::kAcceptable;
}
void OnTimeout() {
database_manager_->CancelApiCheck(this);
SendResultToHandler(Verdict::kAcceptable);
}
void SendResultToHandler(Verdict verdict) {
handler_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&CrowdDenySafeBrowsingRequest::OnReceivedResult,
handler_, verdict));
}
// SafeBrowsingDatabaseManager::Client:
void OnCheckApiBlacklistUrlResult(
const GURL& url,
const safe_browsing::ThreatMetadata& metadata) override {
timeout_.AbandonAndStop();
SendResultToHandler(ExtractVerdictFromMetadata(metadata));
}
base::OneShotTimer timeout_;
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_;
base::WeakPtr<CrowdDenySafeBrowsingRequest> handler_;
scoped_refptr<base::TaskRunner> handler_task_runner_;
};
// CrowdDenySafeBrowsingRequest ----------------------------------------------
CrowdDenySafeBrowsingRequest::CrowdDenySafeBrowsingRequest(
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager,
const url::Origin& origin,
VerdictCallback callback)
: callback_(std::move(callback)) {
client_.reset(new SafeBrowsingClient(database_manager,
weak_factory_.GetWeakPtr(),
base::SequencedTaskRunnerHandle::Get()));
base::PostTask(FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&SafeBrowsingClient::CheckOrigin,
base::Unretained(client_.get()), origin));
}
CrowdDenySafeBrowsingRequest::~CrowdDenySafeBrowsingRequest() = default;
void CrowdDenySafeBrowsingRequest::OnReceivedResult(Verdict verdict) {
DCHECK(callback_);
std::move(callback_).Run(verdict);
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_PERMISSIONS_CROWD_DENY_SAFE_BROWSING_REQUEST_H_
#define CHROME_BROWSER_PERMISSIONS_CROWD_DENY_SAFE_BROWSING_REQUEST_H_
#include <memory>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "content/public/browser/browser_thread.h"
namespace url {
class Origin;
}
namespace safe_browsing {
class SafeBrowsingDatabaseManager;
}
// Represents a single request to the Safe Browsing service to fetch the crowd
// deny verdict for a given origin. Can be created and used on any one thread.
class CrowdDenySafeBrowsingRequest {
public:
// The crowd deny verdict for a given origin.
enum class Verdict {
kAcceptable,
kKnownToShowUnsolicitedNotificationPermissionRequests
};
using VerdictCallback = base::OnceCallback<void(Verdict)>;
// Constructs a request that fetches the verdict for |origin| by consulting
// the |database_manager|, and invokes |callback| when done.
//
// It is guaranteed that |callback| will never be invoked synchronously, and
// it will not be invoked after |this| goes out of scope.
CrowdDenySafeBrowsingRequest(
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
database_manager,
const url::Origin& origin,
VerdictCallback callback);
~CrowdDenySafeBrowsingRequest();
private:
class SafeBrowsingClient;
CrowdDenySafeBrowsingRequest(const CrowdDenySafeBrowsingRequest&) = delete;
CrowdDenySafeBrowsingRequest& operator=(const CrowdDenySafeBrowsingRequest&) =
delete;
// Posted by the |client_| from the IO thread when it gets a response.
void OnReceivedResult(Verdict verdict);
// The client interfacing with Safe Browsing. Created on |this| thread, but
// used on the IO thread for the rest of its life.
std::unique_ptr<SafeBrowsingClient, content::BrowserThread::DeleteOnIOThread>
client_;
VerdictCallback callback_;
base::WeakPtrFactory<CrowdDenySafeBrowsingRequest> weak_factory_{this};
};
#endif // CHROME_BROWSER_PERMISSIONS_CROWD_DENY_SAFE_BROWSING_REQUEST_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment