Matej Habrnal fa1950
From 96a53a3d949142e1a401a0eaac1d09b30476e78c Mon Sep 17 00:00:00 2001
Matej Habrnal fa1950
From: Jakub Filak <jfilak@redhat.com>
Matej Habrnal fa1950
Date: Mon, 16 Mar 2015 08:58:58 +0100
Matej Habrnal fa1950
Subject: [PATCH] dbus: add a new method GetProblemData
Matej Habrnal fa1950
Matej Habrnal fa1950
The method returns serialized problem_data_t for a given problem id.
Matej Habrnal fa1950
Matej Habrnal fa1950
The method is needed by cockpit-abrt which is supposed to have a page
Matej Habrnal fa1950
showing comprehensive problem details.
Matej Habrnal fa1950
Matej Habrnal fa1950
Signed-off-by: Jakub Filak <jfilak@redhat.com>
Matej Habrnal fa1950
---
Matej Habrnal fa1950
 src/dbus/abrt-dbus.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++--
Matej Habrnal fa1950
 1 file changed, 70 insertions(+), 2 deletions(-)
Matej Habrnal fa1950
Matej Habrnal fa1950
diff --git a/src/dbus/abrt-dbus.c b/src/dbus/abrt-dbus.c
Matej Habrnal fa1950
index 308a9af..cf7785d 100644
Matej Habrnal fa1950
--- a/src/dbus/abrt-dbus.c
Matej Habrnal fa1950
+++ b/src/dbus/abrt-dbus.c
Matej Habrnal fa1950
@@ -49,6 +49,10 @@ static const gchar introspection_xml[] =
Matej Habrnal fa1950
   "      <arg type='s' name='problem_dir' direction='in'/>"
Matej Habrnal fa1950
   "      <arg type='s' name='name' direction='in'/>"
Matej Habrnal fa1950
   "    </method>"
Matej Habrnal fa1950
+  "    <method name='GetProblemData'>"
Matej Habrnal fa1950
+  "      <arg type='s' name='problem_dir' direction='in'/>"
Matej Habrnal fa1950
+  "      <arg type='a{s(its)}' name='problem_data' direction='out'/>"
Matej Habrnal fa1950
+  "    </method>"
Matej Habrnal fa1950
   "    <method name='ChownProblemDir'>"
Matej Habrnal fa1950
   "      <arg type='s' name='problem_dir' direction='in'/>"
Matej Habrnal fa1950
   "    </method>"
Matej Habrnal fa1950
@@ -545,6 +549,68 @@ static void handle_method_call(GDBusConnection *connection,
Matej Habrnal fa1950
         return;
Matej Habrnal fa1950
     }
Matej Habrnal fa1950
 
Matej Habrnal fa1950
+    if (g_strcmp0(method_name, "GetProblemData") == 0)
Matej Habrnal fa1950
+    {
Matej Habrnal fa1950
+        /* Parameter tuple is (s) */
Matej Habrnal fa1950
+        const char *problem_id;
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+        g_variant_get(parameters, "(&s)", &problem_id);
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+        int ddstat = dump_dir_stat_for_uid(problem_id, caller_uid);
Matej Habrnal fa1950
+        if ((ddstat & DD_STAT_ACCESSIBLE_BY_UID) == 0 &&
Matej Habrnal fa1950
+                polkit_check_authorization_dname(caller, "org.freedesktop.problems.getall") != PolkitYes)
Matej Habrnal fa1950
+        {
Matej Habrnal fa1950
+            log_notice("Unauthorized access : '%s'", problem_id);
Matej Habrnal fa1950
+            g_dbus_method_invocation_return_dbus_error(invocation,
Matej Habrnal fa1950
+                                              "org.freedesktop.problems.AuthFailure",
Matej Habrnal fa1950
+                                              _("Not Authorized"));
Matej Habrnal fa1950
+            return;
Matej Habrnal fa1950
+        }
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+        struct dump_dir *dd = dd_opendir(problem_id, DD_OPEN_READONLY);
Matej Habrnal fa1950
+        if (dd == NULL)
Matej Habrnal fa1950
+        {
Matej Habrnal fa1950
+            log_notice("Can't access the problem '%s' for reading", problem_id);
Matej Habrnal fa1950
+            g_dbus_method_invocation_return_dbus_error(invocation,
Matej Habrnal fa1950
+                                    "org.freedesktop.problems.Failure",
Matej Habrnal fa1950
+                                    _("Can't access the problem for reading"));
Matej Habrnal fa1950
+            return;
Matej Habrnal fa1950
+        }
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+        problem_data_t *pd = create_problem_data_from_dump_dir(dd);
Matej Habrnal fa1950
+        dd_close(dd);
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+        GVariantBuilder *response_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+        GHashTableIter pd_iter;
Matej Habrnal fa1950
+        char *element_name;
Matej Habrnal fa1950
+        struct problem_item *element_info;
Matej Habrnal fa1950
+        g_hash_table_iter_init(&pd_iter, pd);
Matej Habrnal fa1950
+        while (g_hash_table_iter_next(&pd_iter, (void**)&element_name, (void**)&element_info))
Matej Habrnal fa1950
+        {
Matej Habrnal fa1950
+            unsigned long size = 0;
Matej Habrnal fa1950
+            if (problem_item_get_size(element_info, &size) != 0)
Matej Habrnal fa1950
+            {
Matej Habrnal fa1950
+                log_notice("Can't get stat of : '%s'", element_info->content);
Matej Habrnal fa1950
+                continue;
Matej Habrnal fa1950
+            }
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+            g_variant_builder_add(response_builder, "{s(its)}",
Matej Habrnal fa1950
+                                                    element_name,
Matej Habrnal fa1950
+                                                    element_info->flags,
Matej Habrnal fa1950
+                                                    size,
Matej Habrnal fa1950
+                                                    element_info->content);
Matej Habrnal fa1950
+        }
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+        GVariant *response = g_variant_new("(a{s(its)})", response_builder);
Matej Habrnal fa1950
+        g_variant_builder_unref(response_builder);
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+        problem_data_free(pd);
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+        g_dbus_method_invocation_return_value(invocation, response);
Matej Habrnal fa1950
+        return;
Matej Habrnal fa1950
+    }
Matej Habrnal fa1950
+
Matej Habrnal fa1950
     if (g_strcmp0(method_name, "SetElement") == 0)
Matej Habrnal fa1950
     {
Matej Habrnal fa1950
         const char *problem_id;
Matej Habrnal fa1950
@@ -813,8 +879,10 @@ int main(int argc, char *argv[])
Matej Habrnal fa1950
     * the introspection data structures - so we just build
Matej Habrnal fa1950
     * them from XML.
Matej Habrnal fa1950
     */
Matej Habrnal fa1950
-    introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
Matej Habrnal fa1950
-    g_assert(introspection_data != NULL);
Matej Habrnal fa1950
+    GError *err = NULL;
Matej Habrnal fa1950
+    introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &err;;
Matej Habrnal fa1950
+    if (err != NULL)
Matej Habrnal fa1950
+        error_msg_and_die("Invalid D-Bus interface: %s", err->message);
Matej Habrnal fa1950
 
Matej Habrnal fa1950
     owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
Matej Habrnal fa1950
                              ABRT_DBUS_NAME,
Matej Habrnal fa1950
-- 
Matej Habrnal fa1950
2.1.0
Matej Habrnal fa1950