Skip to content

Commit

Permalink
[GTK] Add WebKitClipboardPermissionRequest to handle DOM paste access…
Browse files Browse the repository at this point in the history
… requests

https://bugs.webkit.org/show_bug.cgi?id=254510

Reviewed by Michael Catanzaro and Adrian Perez de Castro.

* Source/WebKit/PlatformGTK.cmake:
* Source/WebKit/SourcesGTK.txt:
* Source/WebKit/UIProcess/API/glib/WebKitClipboardPermissionRequest.cpp: Added.
(webkitClipboardPermissionRequestAllow):
(webkitClipboardPermissionRequestDeny):
(webkit_permission_request_interface_init):
(webkitClipboardPermissionRequestDispose):
(webkit_clipboard_permission_request_class_init):
(webkitClipboardPermissionRequestCreate):
* Source/WebKit/UIProcess/API/glib/WebKitClipboardPermissionRequest.h.in: Added.
* Source/WebKit/UIProcess/API/glib/WebKitClipboardPermissionRequestPrivate.h: Added.
* Source/WebKit/UIProcess/API/glib/webkit.h.in:
* Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp:
(WebKit::PageClientImpl::requestDOMPasteAccess):
* Tools/MiniBrowser/gtk/BrowserTab.c:
(permissionRequestDialogResponse):
(decidePermissionRequest):
(browser_tab_class_init):
* Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebViewEditor.cpp:
(Clipboard::writeText):
(testWebViewClipboardPermissionRequest):
(beforeAll):

Canonical link: https://commits.webkit.org/262202@main
  • Loading branch information
carlosgcampos committed Mar 28, 2023
1 parent 3823da2 commit 2ec3bfd
Show file tree
Hide file tree
Showing 9 changed files with 299 additions and 2 deletions.
1 change: 1 addition & 0 deletions Source/WebKit/PlatformGTK.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ set(WebKitGTK_HEADER_TEMPLATES
${WEBKIT_DIR}/UIProcess/API/glib/WebKitAutomationSession.h.in
${WEBKIT_DIR}/UIProcess/API/glib/WebKitBackForwardList.h.in
${WEBKIT_DIR}/UIProcess/API/glib/WebKitBackForwardListItem.h.in
${WEBKIT_DIR}/UIProcess/API/glib/WebKitClipboardPermissionRequest.h.in
${WEBKIT_DIR}/UIProcess/API/glib/WebKitCredential.h.in
${WEBKIT_DIR}/UIProcess/API/glib/WebKitContextMenu.h.in
${WEBKIT_DIR}/UIProcess/API/glib/WebKitContextMenuActions.h.in
Expand Down
1 change: 1 addition & 0 deletions Source/WebKit/SourcesGTK.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ UIProcess/API/glib/WebKitAuthenticationRequest.cpp @no-unify
UIProcess/API/glib/WebKitAutomationSession.cpp @no-unify
UIProcess/API/glib/WebKitBackForwardList.cpp @no-unify
UIProcess/API/glib/WebKitBackForwardListItem.cpp @no-unify
UIProcess/API/glib/WebKitClipboardPermissionRequest.cpp @no-unify
UIProcess/API/glib/WebKitContextMenuClient.cpp @no-unify
UIProcess/API/glib/WebKitCookieManager.cpp @no-unify
UIProcess/API/glib/WebKitCredential.cpp @no-unify
Expand Down
101 changes: 101 additions & 0 deletions Source/WebKit/UIProcess/API/glib/WebKitClipboardPermissionRequest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright (C) 2023 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

#include "config.h"
#include "WebKitClipboardPermissionRequest.h"

#include "WebKitClipboardPermissionRequestPrivate.h"
#include "WebKitPermissionRequest.h"
#include <wtf/glib/WTFGType.h>

#if !ENABLE(2022_GLIB_API)
typedef WebKitPermissionRequestIface WebKitPermissionRequestInterface;
#endif

/**
* WebKitClipboardPermissionRequest:
* @See_also: #WebKitPermissionRequest, #WebKitWebView
*
* A permission request for reading clipboard contents.
*
* WebKitClipboardPermissionRequest represents a request for
* permission to decide whether WebKit can access the clibpard to read
* its contents through the Async Clipboard API.
*
* When a WebKitClipboardPermissionRequest is not handled by the user,
* it is denied by default.
*
* Since: 2.42
*/

static void webkit_permission_request_interface_init(WebKitPermissionRequestInterface*);

struct _WebKitClipboardPermissionRequestPrivate {
CompletionHandler<void(WebCore::DOMPasteAccessResponse)> completionHandler;
};

WEBKIT_DEFINE_FINAL_TYPE_WITH_CODE(
WebKitClipboardPermissionRequest, webkit_clipboard_permission_request, G_TYPE_OBJECT, GObject,
G_IMPLEMENT_INTERFACE(WEBKIT_TYPE_PERMISSION_REQUEST, webkit_permission_request_interface_init))

static void webkitClipboardPermissionRequestAllow(WebKitPermissionRequest* request)
{
ASSERT(WEBKIT_IS_CLIPBOARD_PERMISSION_REQUEST(request));

WebKitClipboardPermissionRequestPrivate* priv = WEBKIT_CLIPBOARD_PERMISSION_REQUEST(request)->priv;

if (priv->completionHandler)
priv->completionHandler(WebCore::DOMPasteAccessResponse::GrantedForGesture);
}

static void webkitClipboardPermissionRequestDeny(WebKitPermissionRequest* request)
{
ASSERT(WEBKIT_IS_CLIPBOARD_PERMISSION_REQUEST(request));

WebKitClipboardPermissionRequestPrivate* priv = WEBKIT_CLIPBOARD_PERMISSION_REQUEST(request)->priv;

if (priv->completionHandler)
priv->completionHandler(WebCore::DOMPasteAccessResponse::DeniedForGesture);
}

static void webkit_permission_request_interface_init(WebKitPermissionRequestInterface* iface)
{
iface->allow = webkitClipboardPermissionRequestAllow;
iface->deny = webkitClipboardPermissionRequestDeny;
}

static void webkitClipboardPermissionRequestDispose(GObject* object)
{
// Default behaviour when no decision has been made is denying the request.
webkitClipboardPermissionRequestDeny(WEBKIT_PERMISSION_REQUEST(object));
G_OBJECT_CLASS(webkit_clipboard_permission_request_parent_class)->dispose(object);
}

static void webkit_clipboard_permission_request_class_init(WebKitClipboardPermissionRequestClass* klass)
{
GObjectClass* objectClass = G_OBJECT_CLASS(klass);
objectClass->dispose = webkitClipboardPermissionRequestDispose;
}

WebKitClipboardPermissionRequest* webkitClipboardPermissionRequestCreate(CompletionHandler<void(WebCore::DOMPasteAccessResponse)>&& completionHandler)
{
WebKitClipboardPermissionRequest* clipboardPermissionRequest = WEBKIT_CLIPBOARD_PERMISSION_REQUEST(g_object_new(WEBKIT_TYPE_CLIPBOARD_PERMISSION_REQUEST, nullptr));
clipboardPermissionRequest->priv->completionHandler = WTFMove(completionHandler);
return clipboardPermissionRequest;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (C) 2023 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

@API_SINGLE_HEADER_CHECK@

#ifndef WebKitClipboardPermissionRequest_h
#define WebKitClipboardPermissionRequest_h

#include <glib-object.h>
#include <@API_INCLUDE_PREFIX@/WebKitDefines.h>

G_BEGIN_DECLS

#define WEBKIT_TYPE_CLIPBOARD_PERMISSION_REQUEST (webkit_clipboard_permission_request_get_type())
#if !ENABLE(2022_GLIB_API)
#define WEBKIT_CLIPBOARD_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_CLIPBOARD_PERMISSION_REQUEST, WebKitClipboardPermissionRequest))
#define WEBKIT_CLIPBOARD_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_CLIPBOARD_PERMISSION_REQUEST, WebKitClipboardPermissionRequestClass))
#define WEBKIT_IS_CLIPBOARD_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_CLIPBOARD_PERMISSION_REQUEST))
#define WEBKIT_IS_CLIPBOARD_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_CLIPBOARD_PERMISSION_REQUEST))
#define WEBKIT_CLIPBOARD_PERMISSION_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_CLIPBOARD_PERMISSION_REQUEST, WebKitClipboardPermissionRequestClass))

struct _WebKitClipboardPermissionRequestClass {
GObjectClass parent_class;
};
#endif

WEBKIT_DECLARE_FINAL_TYPE (WebKitClipboardPermissionRequest, webkit_clipboard_permission_request, WEBKIT, CLIPBOARD_PERMISSION_REQUEST, GObject)

G_END_DECLS

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (C) 2023 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

#pragma once

#include "WebKitClipboardPermissionRequest.h"
#include <WebCore/DOMPasteAccess.h>
#include <wtf/CompletionHandler.h>

WebKitClipboardPermissionRequest* webkitClipboardPermissionRequestCreate(CompletionHandler<void(WebCore::DOMPasteAccessResponse)>&&);
1 change: 1 addition & 0 deletions Source/WebKit/UIProcess/API/glib/webkit.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include <@API_INCLUDE_PREFIX@/WebKitBackForwardList.h>
#include <@API_INCLUDE_PREFIX@/WebKitBackForwardListItem.h>
#if PLATFORM(GTK)
#include <@API_INCLUDE_PREFIX@/WebKitClipboardPermissionRequest.h>
#include <@API_INCLUDE_PREFIX@/WebKitColorChooserRequest.h>
#endif
#include <@API_INCLUDE_PREFIX@/WebKitContextMenu.h>
Expand Down
12 changes: 10 additions & 2 deletions Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "WebContextMenuProxyGtk.h"
#include "WebDataListSuggestionsDropdownGtk.h"
#include "WebEventFactory.h"
#include "WebKitClipboardPermissionRequestPrivate.h"
#include "WebKitColorChooser.h"
#include "WebKitPopupMenu.h"
#include "WebKitWebViewBaseInternal.h"
Expand All @@ -56,6 +57,7 @@
#include <WebCore/SharedBuffer.h>
#include <WebCore/ValidationBubble.h>
#include <wtf/Compiler.h>
#include <wtf/glib/GWeakPtr.h>
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
#include <wtf/unix/UnixFileDescriptor.h>
Expand Down Expand Up @@ -552,13 +554,19 @@ void PageClientImpl::derefView()
void PageClientImpl::requestDOMPasteAccess(WebCore::DOMPasteAccessCategory, const IntRect&, const String& originIdentifier, CompletionHandler<void(WebCore::DOMPasteAccessResponse)>&& completionHandler)
{
auto& clipboard = Clipboard::get("CLIPBOARD"_s);
clipboard.readBuffer(PasteboardCustomData::gtkType().characters(), [originIdentifier, completionHandler = WTFMove(completionHandler)](Ref<SharedBuffer>&& buffer) mutable {
clipboard.readBuffer(PasteboardCustomData::gtkType().characters(), [weakWebView = GWeakPtr<GtkWidget>(m_viewWidget), originIdentifier, completionHandler = WTFMove(completionHandler)](Ref<SharedBuffer>&& buffer) mutable {
if (PasteboardCustomData::fromSharedBuffer(buffer.get()).origin() == originIdentifier) {
completionHandler(DOMPasteAccessResponse::GrantedForGesture);
return;
}

completionHandler(DOMPasteAccessResponse::DeniedForGesture);
if (!WEBKIT_IS_WEB_VIEW(weakWebView.get())) {
completionHandler(DOMPasteAccessResponse::DeniedForGesture);
return;
}

GRefPtr<WebKitClipboardPermissionRequest> request = adoptGRef(webkitClipboardPermissionRequestCreate(WTFMove(completionHandler)));
webkitWebViewMakePermissionRequest(WEBKIT_WEB_VIEW(weakWebView.get()), WEBKIT_PERMISSION_REQUEST(request.get()));
});
}

Expand Down
18 changes: 18 additions & 0 deletions Tools/MiniBrowser/gtk/BrowserTab.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ struct _BrowserTab {

static GHashTable *userMediaPermissionGrantedOrigins;
static GHashTable *mediaKeySystemPermissionGrantedOrigins;
static GHashTable *clipboardPermissionGrantedOrigins;
struct _BrowserTabClass {
GtkBoxClass parent;
};
Expand Down Expand Up @@ -274,6 +275,8 @@ static void permissionRequestDialogResponse(GtkWidget *dialog, gint response, Pe
g_hash_table_add(userMediaPermissionGrantedOrigins, g_strdup(requestData->origin));
if (WEBKIT_IS_MEDIA_KEY_SYSTEM_PERMISSION_REQUEST(requestData->request))
g_hash_table_add(mediaKeySystemPermissionGrantedOrigins, g_strdup(requestData->origin));
if (WEBKIT_IS_CLIPBOARD_PERMISSION_REQUEST(requestData->request))
g_hash_table_add(clipboardPermissionGrantedOrigins, g_strdup(requestData->origin));

webkit_permission_request_allow(requestData->request);
break;
Expand All @@ -282,6 +285,8 @@ static void permissionRequestDialogResponse(GtkWidget *dialog, gint response, Pe
g_hash_table_remove(userMediaPermissionGrantedOrigins, requestData->origin);
if (WEBKIT_IS_MEDIA_KEY_SYSTEM_PERMISSION_REQUEST(requestData->request))
g_hash_table_remove(mediaKeySystemPermissionGrantedOrigins, requestData->origin);
if (WEBKIT_IS_CLIPBOARD_PERMISSION_REQUEST(requestData->request))
g_hash_table_remove(clipboardPermissionGrantedOrigins, requestData->origin);

webkit_permission_request_deny(requestData->request);
break;
Expand Down Expand Up @@ -362,6 +367,16 @@ static gboolean decidePermissionRequest(WebKitWebView *webView, WebKitPermission
g_free(origin);
title = "DRM system access request";
text = g_strdup_printf("Allow to use a CDM providing access to %s?", webkit_media_key_system_permission_get_name(WEBKIT_MEDIA_KEY_SYSTEM_PERMISSION_REQUEST(request)));
} else if (WEBKIT_IS_CLIPBOARD_PERMISSION_REQUEST(request)) {
char *origin = getWebViewOrigin(webView);
if (g_hash_table_contains(clipboardPermissionGrantedOrigins, origin)) {
webkit_permission_request_allow(request);
g_free(origin);
return TRUE;
}
title = "Clipboard access request";
text = g_strdup_printf("Do you want to allow \"%s\" to read the contents of the clipboard?", origin);
g_free(origin);
} else {
g_print("%s request not handled\n", G_OBJECT_TYPE_NAME(request));
return FALSE;
Expand Down Expand Up @@ -735,6 +750,9 @@ static void browser_tab_class_init(BrowserTabClass *klass)
if (!mediaKeySystemPermissionGrantedOrigins)
mediaKeySystemPermissionGrantedOrigins = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);

if (!clipboardPermissionGrantedOrigins)
clipboardPermissionGrantedOrigins = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);

g_object_class_install_property(
gobjectClass,
PROP_VIEW,
Expand Down
Loading

0 comments on commit 2ec3bfd

Please sign in to comment.