From 98e9311669908d4332496f4f02dbb0c0a52936fe Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Sat, 11 Nov 2017 14:27:30 +1100 Subject: [PATCH] Give user access to the URL that is attempting to be openExternal'ed --- atom/browser/atom_permission_manager.cc | 37 ++++++++++++++++++- atom/browser/atom_permission_manager.h | 19 +++++++++- .../atom_resource_dispatcher_host_delegate.cc | 2 +- .../browser/web_contents_permission_helper.cc | 25 ++++++++++--- atom/browser/web_contents_permission_helper.h | 8 +++- docs/api/session.md | 3 ++ 6 files changed, 83 insertions(+), 11 deletions(-) diff --git a/atom/browser/atom_permission_manager.cc b/atom/browser/atom_permission_manager.cc index e890618be73..ce544d338be 100644 --- a/atom/browser/atom_permission_manager.cc +++ b/atom/browser/atom_permission_manager.cc @@ -97,11 +97,28 @@ int AtomPermissionManager::RequestPermission( const GURL& requesting_origin, bool user_gesture, const StatusCallback& response_callback) { - return RequestPermissions( + return RequestPermissionWithDetails( + permission, + render_frame_host, + requesting_origin, + user_gesture, + nullptr, + response_callback); +} + +int AtomPermissionManager::RequestPermissionWithDetails( + content::PermissionType permission, + content::RenderFrameHost* render_frame_host, + const GURL& requesting_origin, + bool user_gesture, + const base::DictionaryValue* details, + const StatusCallback& response_callback) { + return RequestPermissionsWithDetails( std::vector(1, permission), render_frame_host, requesting_origin, user_gesture, + details, base::Bind(&PermissionRequestResponseCallbackWrapper, response_callback)); } @@ -111,6 +128,18 @@ int AtomPermissionManager::RequestPermissions( const GURL& requesting_origin, bool user_gesture, const StatusesCallback& response_callback) { + return RequestPermissionsWithDetails( + permissions, render_frame_host, requesting_origin, + user_gesture, nullptr, response_callback); +} + +int AtomPermissionManager::RequestPermissionsWithDetails( + const std::vector& permissions, + content::RenderFrameHost* render_frame_host, + const GURL& requesting_origin, + bool user_gesture, + const base::DictionaryValue* details, + const StatusesCallback& response_callback) { if (permissions.empty()) { response_callback.Run(std::vector()); return kNoPendingOperation; @@ -143,7 +172,11 @@ int AtomPermissionManager::RequestPermissions( const auto callback = base::Bind(&AtomPermissionManager::OnPermissionResponse, base::Unretained(this), request_id, i); - request_handler_.Run(web_contents, permission, callback); + if (details == nullptr) { + request_handler_.Run(web_contents, permission, callback, base::DictionaryValue()); + } else { + request_handler_.Run(web_contents, permission, callback, *details); + } } return request_id; diff --git a/atom/browser/atom_permission_manager.h b/atom/browser/atom_permission_manager.h index b8a768a0794..e4acb6f4323 100644 --- a/atom/browser/atom_permission_manager.h +++ b/atom/browser/atom_permission_manager.h @@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/id_map.h" +#include "base/values.h" #include "content/public/browser/permission_manager.h" namespace content { @@ -30,7 +31,8 @@ class AtomPermissionManager : public content::PermissionManager { using RequestHandler = base::Callback; + const StatusCallback&, + const base::DictionaryValue&)>; // Handler to dispatch permission requests in JS. void SetPermissionRequestHandler(const RequestHandler& handler); @@ -43,6 +45,13 @@ class AtomPermissionManager : public content::PermissionManager { bool user_gesture, const base::Callback& callback) override; + int RequestPermissionWithDetails( + content::PermissionType permission, + content::RenderFrameHost* render_frame_host, + const GURL& requesting_origin, + bool user_gesture, + const base::DictionaryValue* details, + const base::Callback& callback); int RequestPermissions( const std::vector& permissions, content::RenderFrameHost* render_frame_host, @@ -51,6 +60,14 @@ class AtomPermissionManager : public content::PermissionManager { const base::Callback&)>& callback) override; + int RequestPermissionsWithDetails( + const std::vector& permissions, + content::RenderFrameHost* render_frame_host, + const GURL& requesting_origin, + bool user_gesture, + const base::DictionaryValue* details, + const base::Callback&)>& callback); protected: void OnPermissionResponse(int request_id, diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.cc b/atom/browser/atom_resource_dispatcher_host_delegate.cc index 7cb8f718112..896167cd1f6 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.cc +++ b/atom/browser/atom_resource_dispatcher_host_delegate.cc @@ -61,7 +61,7 @@ void HandleExternalProtocolInUI( GURL escaped_url(net::EscapeExternalHandlerValue(url.spec())); auto callback = base::Bind(&OnOpenExternal, escaped_url); - permission_helper->RequestOpenExternalPermission(callback, has_user_gesture); + permission_helper->RequestOpenExternalPermission(callback, has_user_gesture, url); } void OnPdfResourceIntercepted( diff --git a/atom/browser/web_contents_permission_helper.cc b/atom/browser/web_contents_permission_helper.cc index ec9e4ad6e94..94464b6176f 100644 --- a/atom/browser/web_contents_permission_helper.cc +++ b/atom/browser/web_contents_permission_helper.cc @@ -7,6 +7,7 @@ #include #include "atom/browser/atom_permission_manager.h" +#include "atom/common/native_mate_converters/gurl_converter.h" #include "brightray/browser/media/media_stream_devices_controller.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/render_process_host.h" @@ -55,13 +56,21 @@ void WebContentsPermissionHelper::RequestPermission( content::PermissionType permission, const base::Callback& callback, bool user_gesture) { + RequestPermissionWithDetails(permission, callback, user_gesture, nullptr); +} + +void WebContentsPermissionHelper::RequestPermissionWithDetails( + content::PermissionType permission, + const base::Callback& callback, + bool user_gesture, + const base::DictionaryValue* details) { auto rfh = web_contents_->GetMainFrame(); auto permission_manager = static_cast( web_contents_->GetBrowserContext()->GetPermissionManager()); auto origin = web_contents_->GetLastCommittedURL(); - permission_manager->RequestPermission( - permission, rfh, origin, false, - base::Bind(&OnPermissionResponse, callback)); + permission_manager->RequestPermissionWithDetails( + permission, rfh, origin, false, details, + base::Bind(&OnPermissionResponse, callback)); } void WebContentsPermissionHelper::RequestFullscreenPermission( @@ -94,10 +103,14 @@ void WebContentsPermissionHelper::RequestPointerLockPermission( void WebContentsPermissionHelper::RequestOpenExternalPermission( const base::Callback& callback, - bool user_gesture) { - RequestPermission( + bool user_gesture, + const GURL& url) { + base::DictionaryValue details; + details.SetString("scheme", url.scheme()); + details.SetString("url", url.spec()); + RequestPermissionWithDetails( static_cast(PermissionType::OPEN_EXTERNAL), - callback, user_gesture); + callback, user_gesture, &details); } } // namespace atom diff --git a/atom/browser/web_contents_permission_helper.h b/atom/browser/web_contents_permission_helper.h index 89da64b7583..e0ce3a2bd14 100644 --- a/atom/browser/web_contents_permission_helper.h +++ b/atom/browser/web_contents_permission_helper.h @@ -33,7 +33,8 @@ class WebContentsPermissionHelper void RequestPointerLockPermission(bool user_gesture); void RequestOpenExternalPermission( const base::Callback& callback, - bool user_gesture); + bool user_gesture, + const GURL& url); private: explicit WebContentsPermissionHelper(content::WebContents* web_contents); @@ -43,6 +44,11 @@ class WebContentsPermissionHelper content::PermissionType permission, const base::Callback& callback, bool user_gesture = false); + void RequestPermissionWithDetails( + content::PermissionType permission, + const base::Callback& callback, + bool user_gesture, + const base::DictionaryValue* details); content::WebContents* web_contents_; diff --git a/docs/api/session.md b/docs/api/session.md index aa975fddd54..1eb478533c4 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -293,6 +293,9 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => { 'pointerLock', 'fullscreen', 'openExternal'. * `callback` Function * `permissionGranted` Boolean - Allow or deny the permission. + * `details` Object - Some properties are only available on certain permission types. + * `url` String - The url of the `openExternal` request. + * `scheme` String - The protocol scheme of the `openExternal` request. Sets the handler which can be used to respond to permission requests for the `session`. Calling `callback(true)` will allow the permission and `callback(false)` will reject it.