From 502491485b3c1c69120c1413b18f7fd55f6a94c7 Mon Sep 17 00:00:00 2001
From: Jakub Filak <jfilak@redhat.com>
Date: Tue, 24 Mar 2015 20:48:33 +0100
Subject: [PATCH] dbus: add new method to test existence of an element

It is sometimes necessary to check if some elemen exist, so this method
should be fast as much as it is possible to do this task over DBus.

I was thinking about calling the GetInfo method with a single element
but I refused this idea as it is inherently overcomplicated and error
prone.

Signed-off-by: Jakub Filak <jfilak@redhat.com>
---
 .../org.freedesktop.Problems.xml.in                | 16 ++++++++
 src/dbus/abrt-dbus.c                               | 44 ++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/doc/problems-service/org.freedesktop.Problems.xml.in b/doc/problems-service/org.freedesktop.Problems.xml.in
index 6fcd990..2bf8c32 100644
--- a/doc/problems-service/org.freedesktop.Problems.xml.in
+++ b/doc/problems-service/org.freedesktop.Problems.xml.in
@@ -253,6 +253,22 @@ for prblmid in problems.GetProblems():
                 </arg>
             </method>
 
+            <method name='TestElementExists'>
+                <tp:docstring>Checks whether the element exists.</tp:docstring>
+
+                <arg type='s' name='problem_dir' direction='in'>
+                    <tp:docstring>An identifier of problem.</tp:docstring>
+                </arg>
+
+                <arg type='s' name='name' direction='in'>
+                    <tp:docstring>A name of checked element.</tp:docstring>
+                </arg>
+
+                <arg type='b' name='response' direction='out'>
+                    <tp:docstring>True if the element exists; otherwise false.</tp:docstring>
+                </arg>
+            </method>
+
             <method name='GetProblemData'>"
                 <tp:docstring>Returns problem's data.</tp:docstring>
 
diff --git a/src/dbus/abrt-dbus.c b/src/dbus/abrt-dbus.c
index cf7785d..4eeff41 100644
--- a/src/dbus/abrt-dbus.c
+++ b/src/dbus/abrt-dbus.c
@@ -49,6 +49,11 @@ static const gchar introspection_xml[] =
   "      <arg type='s' name='problem_dir' direction='in'/>"
   "      <arg type='s' name='name' direction='in'/>"
   "    </method>"
+  "    <method name='TestElementExists'>"
+  "      <arg type='s' name='problem_dir' direction='in'/>"
+  "      <arg type='s' name='name' direction='in'/>"
+  "      <arg type='b' name='response' direction='out'/>"
+  "    </method>"
   "    <method name='GetProblemData'>"
   "      <arg type='s' name='problem_dir' direction='in'/>"
   "      <arg type='a{s(its)}' name='problem_data' direction='out'/>"
@@ -703,6 +708,45 @@ static void handle_method_call(GDBusConnection *connection,
         return;
     }
 
+    if (g_strcmp0(method_name, "TestElementExists") == 0)
+    {
+        const char *problem_id;
+        const char *element;
+
+        g_variant_get(parameters, "(&s&s)", &problem_id, &element);
+
+
+        struct dump_dir *dd = dd_opendir(problem_id, DD_OPEN_READONLY);
+        if (!dd)
+        {
+            log_notice("Can't access the problem '%s'", problem_id);
+            g_dbus_method_invocation_return_dbus_error(invocation,
+                                    "org.freedesktop.problems.Failure",
+                                    _("Can't access the problem"));
+            return;
+        }
+
+        int ddstat = dump_dir_stat_for_uid(problem_id, caller_uid);
+        if ((ddstat & DD_STAT_ACCESSIBLE_BY_UID) == 0 &&
+                polkit_check_authorization_dname(caller, "org.freedesktop.problems.getall") != PolkitYes)
+        {
+            dd_close(dd);
+            log_notice("Unauthorized access : '%s'", problem_id);
+            g_dbus_method_invocation_return_dbus_error(invocation,
+                                              "org.freedesktop.problems.AuthFailure",
+                                              _("Not Authorized"));
+            return;
+        }
+
+        int ret = dd_exist(dd, element);
+        dd_close(dd);
+
+        GVariant *response = g_variant_new("(b)", ret);
+        g_dbus_method_invocation_return_value(invocation, response);
+
+        return;
+    }
+
     if (g_strcmp0(method_name, "DeleteProblem") == 0)
     {
         /* Dbus parameters are always tuples.
-- 
2.1.0

