[tracker/wip/carlosg/portal: 2/36] libtracker-data: Add support for graph/service control over SPARQL queries



commit 5d23e24b8762cded6f36bff614d7cae310c67e1f
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Jan 20 14:53:29 2020 +0100

    libtracker-data: Add support for graph/service control over SPARQL queries
    
    This is unused ATM, but will be made so in future commits.

 src/libtracker-data/tracker-sparql.c | 72 ++++++++++++++++++++++++++++++++++--
 1 file changed, 68 insertions(+), 4 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index 8e87d9fb5..0db0a503d 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -139,6 +139,12 @@ struct _TrackerSparql
 
        GMutex mutex;
 
+       struct {
+               GPtrArray *graphs;
+               GPtrArray *services;
+               GHashTable *filtered_graphs;
+       } policy;
+
        struct {
                TrackerContext *context;
                TrackerContext *select_context;
@@ -186,6 +192,7 @@ tracker_sparql_finalize (GObject *object)
        g_hash_table_destroy (sparql->parameters);
        g_hash_table_destroy (sparql->cached_bindings);
 
+
        if (sparql->sql)
                tracker_string_builder_free (sparql->sql);
        if (sparql->tree)
@@ -211,6 +218,10 @@ tracker_sparql_finalize (GObject *object)
        g_array_unref (sparql->var_types);
        g_free (sparql->base);
 
+       g_clear_pointer (&sparql->policy.graphs, g_ptr_array_unref);
+       g_clear_pointer (&sparql->policy.services, g_ptr_array_unref);
+       g_clear_pointer (&sparql->policy.filtered_graphs, g_hash_table_unref);
+
        if (sparql->blank_nodes)
                g_variant_builder_unref (sparql->blank_nodes);
 
@@ -633,6 +644,41 @@ build_properties_string (TrackerSparql   *sparql,
        }
 }
 
+static GHashTable *
+tracker_sparql_get_effective_graphs (TrackerSparql *sparql)
+{
+       GHashTable *graphs;
+
+       graphs = tracker_data_manager_get_graphs (sparql->data_manager);
+
+       if (graphs && sparql->policy.graphs) {
+               if (!sparql->policy.filtered_graphs) {
+                       gint i;
+
+                       sparql->policy.filtered_graphs =
+                               g_hash_table_new_full (g_str_hash,
+                                                      g_str_equal,
+                                                      g_free,
+                                                      NULL);
+
+                       for (i = 0; i < sparql->policy.graphs->len; i++) {
+                               gpointer key, value;
+
+                               if (g_hash_table_lookup_extended (graphs,
+                                                                 g_ptr_array_index (sparql->policy.graphs, 
i),
+                                                                 &key, &value)) {
+                                       g_hash_table_insert (sparql->policy.filtered_graphs,
+                                                            g_strdup (key), value);
+                               }
+                       }
+               }
+
+               return sparql->policy.filtered_graphs;
+       } else {
+               return graphs;
+       }
+}
+
 static void
 _append_union_graph_with_clause (TrackerSparql *sparql,
                                  const gchar   *table_name,
@@ -642,7 +688,7 @@ _append_union_graph_with_clause (TrackerSparql *sparql,
        GHashTable *graphs;
        GHashTableIter iter;
 
-       graphs = tracker_data_manager_get_graphs (sparql->data_manager);
+       graphs = tracker_sparql_get_effective_graphs (sparql);
 
        _append_string_printf (sparql, "\"unionGraph_%s\"(ID, %s graph) AS (",
                               table_name, properties);
@@ -1351,7 +1397,7 @@ tracker_sparql_add_fts_subquery (TrackerSparql         *sparql,
                                       select_items->str);
                _append_literal_sql (sparql, binding);
 
-               graphs = tracker_data_manager_get_graphs (sparql->data_manager);
+               graphs = tracker_sparql_get_effective_graphs (sparql);
                g_hash_table_iter_init (&iter, graphs);
 
                while (g_hash_table_iter_next (&iter, &graph_name, &graph_id)) {
@@ -3562,7 +3608,7 @@ translate_Clear (TrackerSparql  *sparql,
                        GHashTable *ht;
                        GHashTableIter iter;
 
-                       ht = tracker_data_manager_get_graphs (sparql->data_manager);
+                       ht = tracker_sparql_get_effective_graphs (sparql);
                        g_hash_table_iter_init (&iter, ht);
 
                        while (g_hash_table_iter_next (&iter, (gpointer *) &graph, NULL))
@@ -3617,7 +3663,7 @@ translate_Drop (TrackerSparql  *sparql,
                        GHashTable *ht;
                        GHashTableIter iter;
 
-                       ht = tracker_data_manager_get_graphs (sparql->data_manager);
+                       ht = tracker_sparql_get_effective_graphs (sparql);
                        g_hash_table_iter_init (&iter, ht);
 
                        while (g_hash_table_iter_next (&iter, (gpointer *) &graph, NULL))
@@ -4723,6 +4769,24 @@ translate_ServiceGraphPattern (TrackerSparql  *sparql,
        _call_rule (sparql, NAMED_RULE_VarOrIri, error);
        _init_token (&service, sparql->current_state.prev_node, sparql);
 
+       if (sparql->policy.services &&
+           tracker_token_get_literal (&service)) {
+               gboolean found = FALSE;
+               gint i;
+
+               for (i = 0; i < sparql->policy.services->len; i++) {
+                       if (g_strcmp0 (g_ptr_array_index (sparql->policy.services, i),
+                                      tracker_token_get_idstring (&service)) == 0) {
+                               found = TRUE;
+                               break;
+                       }
+               }
+
+               if (!found) {
+                       _raise (PARSE, "Access to service is disallowed", "SERVICE");
+               }
+       }
+
        pattern = _skip_rule (sparql, NAMED_RULE_GroupGraphPattern);
        _append_string (sparql, "SELECT ");
        service_sparql = g_string_new ("SELECT ");


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