[tracker/wip/carlosg/portal: 44/61] libtracker-sparql: Add private filtering methods to TrackerEndpointDBus



commit 3f9794f7e9b5e397eff35c2eb83c51d7b78c6916
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Jan 23 12:17:02 2020 +0100

    libtracker-sparql: Add private filtering methods to TrackerEndpointDBus
    
    These methods don't kick in unless they are implemented in a subclass.
    This is preparation in advance for portal filtering, letting endpoints
    filter down 1) operations at the bus level, 2) events in GraphUpdated
    and 3) through query prologues.

 src/libtracker-sparql/tracker-endpoint-dbus.c | 116 +++++++++++++++++++++++++-
 src/libtracker-sparql/tracker-private.h       |  12 +++
 2 files changed, 125 insertions(+), 3 deletions(-)
---
diff --git a/src/libtracker-sparql/tracker-endpoint-dbus.c b/src/libtracker-sparql/tracker-endpoint-dbus.c
index 89de4f1e2..8b67dd791 100644
--- a/src/libtracker-sparql/tracker-endpoint-dbus.c
+++ b/src/libtracker-sparql/tracker-endpoint-dbus.c
@@ -76,6 +76,7 @@ typedef struct {
        gboolean array_update;
        gint num_queries;
        gint cur_query;
+       gchar *prologue;
 } UpdateRequest;
 
 GParamSpec *props[N_PROPS] = { 0 };
@@ -92,6 +93,68 @@ static void read_update_blank_cb (GObject      *object,
 G_DEFINE_TYPE_WITH_CODE (TrackerEndpointDBus, tracker_endpoint_dbus, TRACKER_TYPE_ENDPOINT,
                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, tracker_endpoint_dbus_initable_iface_init))
 
+static gboolean
+tracker_endpoint_dbus_forbid_operation (TrackerEndpointDBus   *endpoint_dbus,
+                                        GDBusMethodInvocation *invocation,
+                                        TrackerOperationType   operation_type)
+{
+       TrackerEndpointDBusClass *endpoint_dbus_class;
+
+       endpoint_dbus_class = TRACKER_ENDPOINT_DBUS_GET_CLASS (endpoint_dbus);
+
+       if (!endpoint_dbus_class->forbid_operation)
+               return FALSE;
+
+       return endpoint_dbus_class->forbid_operation (endpoint_dbus,
+                                                     invocation,
+                                                     operation_type);
+}
+
+static gboolean
+tracker_endpoint_dbus_filter_graph (TrackerEndpointDBus *endpoint_dbus,
+                                    const gchar         *graph_name)
+{
+       TrackerEndpointDBusClass *endpoint_dbus_class;
+
+       endpoint_dbus_class = TRACKER_ENDPOINT_DBUS_GET_CLASS (endpoint_dbus);
+
+       if (!endpoint_dbus_class->filter_graph)
+               return FALSE;
+
+       return endpoint_dbus_class->filter_graph (endpoint_dbus, graph_name);
+}
+
+static gchar *
+tracker_endpoint_dbus_add_prologue (TrackerEndpointDBus *endpoint_dbus,
+                                    gchar               *query)
+{
+       TrackerEndpointDBusClass *endpoint_dbus_class;
+       gchar *prologue = NULL;
+
+       endpoint_dbus_class = TRACKER_ENDPOINT_DBUS_GET_CLASS (endpoint_dbus);
+
+       if (endpoint_dbus_class->add_prologue)
+               prologue = endpoint_dbus_class->add_prologue (endpoint_dbus);
+
+       if (prologue) {
+               if (query) {
+                       gchar *result;
+
+                       result = g_strdup_printf ("%s %s",
+                                                 prologue,
+                                                 query);
+                       g_free (query);
+                       g_free (prologue);
+
+                       return result;
+               } else {
+                       return prologue;
+               }
+       } else {
+               return query;
+       }
+}
+
 static QueryRequest *
 query_request_new (TrackerEndpointDBus   *endpoint,
                    GDBusMethodInvocation *invocation,
@@ -144,6 +207,7 @@ update_request_new (TrackerEndpointDBus   *endpoint,
        request->cur_query = 0;
        request->array_update = array_update;
        request->queries = g_ptr_array_new_with_free_func (g_free);
+       request->prologue = tracker_endpoint_dbus_add_prologue (endpoint, NULL);
 
        stream = g_unix_input_stream_new (input, TRUE);
        request->input_stream = g_data_input_stream_new (stream);
@@ -166,18 +230,27 @@ update_request_read_next (UpdateRequest       *request,
                           GAsyncReadyCallback  cb)
 {
        gchar *buffer;
-       gint buffer_size;
+       gint buffer_size, prologue_size = 0;
 
        if (request->cur_query >= request->num_queries)
                return FALSE;
 
+       if (request->prologue)
+               prologue_size = strlen (request->prologue) + 1;
+
        request->cur_query++;
        buffer_size = g_data_input_stream_read_int32 (request->input_stream, NULL, NULL);
-       buffer = g_new0 (char, buffer_size + 1);
+       buffer = g_new0 (char, prologue_size + 1 + buffer_size + 1);
+
+       if (request->prologue) {
+               strncpy (buffer, request->prologue, prologue_size - 1);
+               buffer[prologue_size - 1] = ' ';
+       }
+
        g_ptr_array_add (request->queries, buffer);
 
        g_input_stream_read_all_async (G_INPUT_STREAM (request->input_stream),
-                                      buffer,
+                                      &buffer[prologue_size],
                                       buffer_size,
                                       G_PRIORITY_DEFAULT,
                                       request->endpoint->cancellable,
@@ -194,6 +267,7 @@ update_request_free (UpdateRequest *request)
        g_ptr_array_unref (request->queries);
        g_object_unref (request->invocation);
        g_object_unref (request->input_stream);
+       g_free (request->prologue);
        g_free (request);
 }
 
@@ -518,6 +592,16 @@ endpoint_dbus_iface_method_call (GDBusConnection       *connection,
        fd_list = g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation));
 
        if (g_strcmp0 (method_name, "Query") == 0) {
+               if (tracker_endpoint_dbus_forbid_operation (endpoint_dbus,
+                                                           invocation,
+                                                           TRACKER_OPERATION_TYPE_SELECT)) {
+                       g_dbus_method_invocation_return_error (invocation,
+                                                              G_DBUS_ERROR,
+                                                              G_DBUS_ERROR_ACCESS_DENIED,
+                                                              "Operation not allowed");
+                       return;
+               }
+
                g_variant_get (parameters, "(sha{sv})", &query, &handle, &arguments);
 
                if (fd_list)
@@ -531,6 +615,9 @@ endpoint_dbus_iface_method_call (GDBusConnection       *connection,
                } else {
                        QueryRequest *request;
 
+                       query = tracker_endpoint_dbus_add_prologue (endpoint_dbus,
+                                                                   query);
+
                        request = query_request_new (endpoint_dbus, invocation, fd);
 
                        if (arguments) {
@@ -563,6 +650,16 @@ endpoint_dbus_iface_method_call (GDBusConnection       *connection,
                g_free (query);
        } else if (g_strcmp0 (method_name, "Update") == 0 ||
                   g_strcmp0 (method_name, "UpdateArray") == 0) {
+               if (tracker_endpoint_dbus_forbid_operation (endpoint_dbus,
+                                                           invocation,
+                                                           TRACKER_OPERATION_TYPE_UPDATE)) {
+                       g_dbus_method_invocation_return_error (invocation,
+                                                              G_DBUS_ERROR,
+                                                              G_DBUS_ERROR_ACCESS_DENIED,
+                                                              "Operation not allowed");
+                       return;
+               }
+
                g_variant_get (parameters, "(h)", &handle);
 
                if (fd_list)
@@ -582,6 +679,16 @@ endpoint_dbus_iface_method_call (GDBusConnection       *connection,
                        update_request_read_next (request, read_update_cb);
                }
        } else if (g_strcmp0 (method_name, "UpdateBlank") == 0) {
+               if (tracker_endpoint_dbus_forbid_operation (endpoint_dbus,
+                                                           invocation,
+                                                           TRACKER_OPERATION_TYPE_UPDATE)) {
+                       g_dbus_method_invocation_return_error (invocation,
+                                                              G_DBUS_ERROR,
+                                                              G_DBUS_ERROR_ACCESS_DENIED,
+                                                              "Operation not allowed");
+                       return;
+               }
+
                g_variant_get (parameters, "(h)", &handle);
 
                if (fd_list)
@@ -618,6 +725,9 @@ notifier_events_cb (TrackerNotifier *notifier,
        GError *error = NULL;
        gint i;
 
+       if (tracker_endpoint_dbus_filter_graph (endpoint_dbus, graph))
+               return;
+
        g_variant_builder_init (&builder, G_VARIANT_TYPE ("(sa{ii})"));
        g_variant_builder_add (&builder, "s", graph ? graph : "");
        g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{ii}"));
diff --git a/src/libtracker-sparql/tracker-private.h b/src/libtracker-sparql/tracker-private.h
index 5f81bb192..e80ca0ae6 100644
--- a/src/libtracker-sparql/tracker-private.h
+++ b/src/libtracker-sparql/tracker-private.h
@@ -147,8 +147,20 @@ struct _TrackerEndpointDBus {
 
 typedef struct _TrackerEndpointDBusClass TrackerEndpointDBusClass;
 
+typedef enum {
+       TRACKER_OPERATION_TYPE_SELECT,
+       TRACKER_OPERATION_TYPE_UPDATE,
+} TrackerOperationType;
+
 struct _TrackerEndpointDBusClass {
        struct _TrackerEndpointClass parent_class;
+
+       gboolean (* forbid_operation) (TrackerEndpointDBus   *endpoint_dbus,
+                                      GDBusMethodInvocation *invocation,
+                                      TrackerOperationType   operation_type);
+       gboolean (* filter_graph) (TrackerEndpointDBus *endpoint_dbus,
+                                  const gchar         *graph_name);
+       gchar * (* add_prologue) (TrackerEndpointDBus *endpoint_dbus);
 };
 
 typedef struct _TrackerResourceClass TrackerResourceClass;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]