Chromium Code Reviews| Index: chrome/browser/permissions/permission_context_base.cc |
| diff --git a/chrome/browser/permissions/permission_context_base.cc b/chrome/browser/permissions/permission_context_base.cc |
| index 5c99fbd3668796176b5a1b073fa2f16d013f9c3b..cb28f3587d944a5304b40999111b483c4e320da3 100644 |
| --- a/chrome/browser/permissions/permission_context_base.cc |
| +++ b/chrome/browser/permissions/permission_context_base.cc |
| @@ -5,6 +5,9 @@ |
| #include "chrome/browser/permissions/permission_context_base.h" |
| #include <stddef.h> |
| + |
| +#include <set> |
| +#include <string> |
| #include <utility> |
| #include "base/callback.h" |
| @@ -12,6 +15,7 @@ |
| #include "base/memory/ptr_util.h" |
| #include "base/strings/stringprintf.h" |
| #include "build/build_config.h" |
| +#include "chrome/browser/browser_process.h" |
| #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| #include "chrome/browser/permissions/permission_decision_auto_blocker.h" |
| #include "chrome/browser/permissions/permission_request.h" |
| @@ -21,10 +25,13 @@ |
| #include "chrome/browser/permissions/permission_uma_util.h" |
| #include "chrome/browser/permissions/permission_util.h" |
| #include "chrome/browser/profiles/profile.h" |
| +#include "chrome/browser/safe_browsing/safe_browsing_service.h" |
| +#include "chrome/common/chrome_features.h" |
| #include "chrome/common/pref_names.h" |
| #include "components/content_settings/core/browser/host_content_settings_map.h" |
| #include "components/content_settings/core/browser/website_settings_registry.h" |
| #include "components/prefs/pref_service.h" |
| +#include "components/safe_browsing_db/database_manager.h" |
| #include "components/variations/variations_associated_data.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/render_frame_host.h" |
| @@ -43,6 +50,49 @@ const char PermissionContextBase::kPermissionsKillSwitchFieldStudy[] = |
| const char PermissionContextBase::kPermissionsKillSwitchBlockedValue[] = |
| "blocked"; |
| +class PermissionsBlacklistSBClientImpl |
|
dominickn
2016/12/07 04:34:29
Add a comment above this class:
"The client used
meredithl
2016/12/07 06:37:10
Done.
|
| + : public safe_browsing::SafeBrowsingDatabaseManager::Client { |
| + public: |
| + PermissionsBlacklistSBClientImpl( |
| + content::PermissionType permission_type, |
| + const GURL& request_origin, |
| + scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager, |
| + base::Callback<void(bool)> callback) |
| + : permission_type_(permission_type), callback_(callback) { |
| + content::BrowserThread::PostTask( |
| + content::BrowserThread::IO, FROM_HERE, |
| + base::Bind(&PermissionsBlacklistSBClientImpl::StartCheck, |
| + base::Unretained(this), db_manager, request_origin)); |
| + } |
| + |
| + private: |
| + void StartCheck( |
| + scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager, |
| + const GURL& request_origin) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| + db_manager->CheckApiBlacklistUrl(request_origin, this); |
| + } |
| + |
| + void OnCheckApiBlacklistUrlResult( |
| + const GURL& url, |
| + const safe_browsing::ThreatMetadata& metadata) override { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| + bool permission_blocked = |
| + metadata.api_permissions.find(PermissionUtil::GetPermissionString( |
|
dominickn
2016/12/07 04:34:29
We need to verify that PermissionUtil::GetPermissi
|
| + permission_type_)) != metadata.api_permissions.end(); |
| + // return to the callback with the result |
|
dominickn
2016/12/07 04:34:29
Nit: you can probably remove this comment.
meredithl
2016/12/07 06:37:10
Done.
|
| + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, |
| + base::Bind(callback_, permission_blocked)); |
| + // result has been received and posted, the client can now free itself |
|
dominickn
2016/12/07 04:34:29
Nit: "The result has been received, so this object
meredithl
2016/12/07 06:37:10
Done.
|
| + delete this; |
| + } |
| + |
| + ~PermissionsBlacklistSBClientImpl() override {} |
| + |
| + content::PermissionType permission_type_; |
| + base::Callback<void(bool)> callback_; |
| +}; |
| + |
| PermissionContextBase::PermissionContextBase( |
| Profile* profile, |
| const content::PermissionType permission_type, |
| @@ -69,7 +119,6 @@ void PermissionContextBase::RequestPermission( |
| bool user_gesture, |
| const BrowserPermissionCallback& callback) { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
|
dominickn
2016/12/07 04:34:29
Nit: put these newlines back in. :)
|
| - |
| // First check if this permission has been disabled. |
| if (IsPermissionKillSwitchOn()) { |
| // Log to the developer console. |
| @@ -85,7 +134,6 @@ void PermissionContextBase::RequestPermission( |
| GURL requesting_origin = requesting_frame.GetOrigin(); |
| GURL embedding_origin = web_contents->GetLastCommittedURL().GetOrigin(); |
| - |
| if (!requesting_origin.is_valid() || !embedding_origin.is_valid()) { |
| std::string type_name = |
| content_settings::WebsiteSettingsRegistry::GetInstance() |
| @@ -101,12 +149,55 @@ void PermissionContextBase::RequestPermission( |
| return; |
| } |
| + scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager = |
| + GetSafeBrowsingDatabaseManager(); |
| + if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist) && |
| + database_manager) { |
| + // The client will contact safe browsing, and invoke the callback with the |
|
dominickn
2016/12/07 04:34:29
Nit: "Safe Browsing"
meredithl
2016/12/07 06:37:11
Done.
|
| + // result. This object will be freed once Safe Browsing has returned the |
| + // results. |
| + // TODO(meredithl): Check if Safe Browsing Service has timed out |
| + new PermissionsBlacklistSBClientImpl( |
| + permission_type_, requesting_origin, database_manager, |
| + base::Bind(&PermissionContextBase::CheckPermissionsBlacklistResult, |
| + base::Unretained(this), web_contents, id, requesting_origin, |
| + embedding_origin, user_gesture, callback)); |
| + } else { |
| + CheckPermissionsBlacklistResult(web_contents, id, requesting_origin, |
| + embedding_origin, user_gesture, callback, |
| + false); |
| + } |
| +} |
| + |
| +void PermissionContextBase::CheckPermissionsBlacklistResult( |
| + content::WebContents* web_contents, |
| + const PermissionRequestID& id, |
| + const GURL& requesting_origin, |
| + const GURL& embedding_origin, |
| + bool user_gesture, |
| + const BrowserPermissionCallback& callback, |
| + bool result) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + if (result) { |
| + // Log to the developer console that this permission is auto blocked. |
|
dominickn
2016/12/07 04:34:28
Nit: the comment here is probably unnecessary.
meredithl
2016/12/07 06:37:10
Done.
|
| + web_contents->GetMainFrame()->AddMessageToConsole( |
| + content::CONSOLE_MESSAGE_LEVEL_LOG, |
| + base::StringPrintf( |
| + "%s permission has been auto-blocked.", |
| + PermissionUtil::GetPermissionString(permission_type_).c_str())); |
| + // Permission has been blacklisted, block the request. |
| + callback.Run(CONTENT_SETTING_BLOCK); |
| + return; |
| + } |
| + |
| + // Site is not blacklisted by Safe Browsing for the requested permission. |
| ContentSetting content_setting = |
| GetPermissionStatus(requesting_origin, embedding_origin); |
| if (content_setting == CONTENT_SETTING_ALLOW) { |
| HostContentSettingsMapFactory::GetForProfile(profile_)->UpdateLastUsage( |
| requesting_origin, embedding_origin, content_settings_type_); |
| } |
| + |
| if (content_setting == CONTENT_SETTING_ALLOW || |
| content_setting == CONTENT_SETTING_BLOCK) { |
| NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, |
| @@ -318,3 +409,10 @@ bool PermissionContextBase::IsPermissionKillSwitchOn() const { |
| return param == kPermissionsKillSwitchBlockedValue; |
| } |
| + |
| +scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> |
| +PermissionContextBase::GetSafeBrowsingDatabaseManager() { |
| + safe_browsing::SafeBrowsingService* sb_service = |
| + g_browser_process->safe_browsing_service(); |
| + return sb_service ? sb_service->database_manager() : nullptr; |
| +} |