Blame SOURCES/0083-rhtsupport-submit-ureport-and-attach-case-ID-to-urep.patch

28bab8
From c25092c8a9b5fa42cd5388313b1db4d8ad81034f Mon Sep 17 00:00:00 2001
28bab8
From: Jakub Filak <jfilak@redhat.com>
28bab8
Date: Tue, 16 Sep 2014 13:34:28 +0200
28bab8
Subject: [LIBREPORT PATCH 83/93] rhtsupport: submit ureport and attach case ID
28bab8
 to ureport
28bab8
28bab8
ABRT Server for RHEL provides an authenticated way of uReport
28bab8
submission. The authentication can be done via client certificates or
28bab8
HTTP Basic auth. ABRT client uses the client certificates for
28bab8
Auto-reporting, but when user wants to report a problem manually he
28bab8
needs to have special permissions to work with the certificates or he
28bab8
cannot use this way of authentication. Fortunately, RHEL ABRT Server can
28bab8
authenticate user via RHTSupport user name an password, but we don't
28bab8
want to ask users to provide/configure the Customer Portal credentials
28bab8
twice, hence we will attach a case ID to a bthash from
28bab8
reporter-rhtsupport.
28bab8
28bab8
This commit also addresses complaints about no evidences of sending
28bab8
uReport to ABRT Server. This commit adds a log message
28bab8
"Sending ABRT crash statistics data".
28bab8
28bab8
Relate to rhbz#1139987, rhbz#1084028
28bab8
28bab8
Signed-off-by: Jakub Filak <jfilak@redhat.com>
28bab8
---
28bab8
 doc/reporter-rhtsupport.txt       |  18 +++++-
28bab8
 src/include/ureport.h             |  13 +++-
28bab8
 src/lib/ureport.c                 |  13 +++-
28bab8
 src/plugins/reporter-rhtsupport.c | 121 +++++++++++++++++++++++++++++++++++++-
28bab8
 src/plugins/reporter-ureport.c    |   2 +-
28bab8
 5 files changed, 162 insertions(+), 5 deletions(-)
28bab8
28bab8
diff --git a/doc/reporter-rhtsupport.txt b/doc/reporter-rhtsupport.txt
28bab8
index b018906..c4aa459 100644
28bab8
--- a/doc/reporter-rhtsupport.txt
28bab8
+++ b/doc/reporter-rhtsupport.txt
28bab8
@@ -7,7 +7,7 @@ reporter-rhtsupport - Reports problem to RHTSupport.
28bab8
 
28bab8
 SYNOPSIS
28bab8
 --------
28bab8
-'reporter-rhtsupport' [-v] [-c CONFFILE] -d DIR
28bab8
+'reporter-rhtsupport' [-v] [-c CONFFILE] [-u -C UR_CONFFILE] -d DIR
28bab8
 
28bab8
 Or:
28bab8
 
28bab8
@@ -18,6 +18,9 @@ DESCRIPTION
28bab8
 The tool reads problem directory DIR. Then it logs in to RHTSupport
28bab8
 and creates a new case.
28bab8
 
28bab8
+The tool can be configured to submit an uReport to RHTSupport together with
28bab8
+creating a new case.
28bab8
+
28bab8
 The URL to new case is printed to stdout and recorded in 'reported_to'
28bab8
 element in DIR.
28bab8
 
28bab8
@@ -30,6 +33,9 @@ If problem data in DIR was never reported to RHTSupport, upload will fail.
28bab8
 Option -tCASE uploads FILEs to the case CASE on RHTSupport site.
28bab8
 -d DIR is ignored.
28bab8
 
28bab8
+Option -u uploads uReport along with creating a new case. uReport configuration
28bab8
+is loaded from UR_CONFFILE which defaults to
28bab8
+/etc/libreport/plugins/ureport.conf.
28bab8
 
28bab8
 Configuration file
28bab8
 ~~~~~~~~~~~~~~~~~~
28bab8
@@ -47,6 +53,10 @@ Configuration file lines should have 'PARAM = VALUE' format. The parameters are:
28bab8
 'SSLVerify'::
28bab8
 	Use yes/true/on/1 to verify server's SSL certificate. (default: yes)
28bab8
 
28bab8
+'SubmitUReport'::
28bab8
+	Use yes/true/on/1 to enable submitting uReport together wit creating a new
28bab8
+	case. (default: no)
28bab8
+
28bab8
 Parameters can be overridden via $RHTSupport_PARAM environment variables.
28bab8
 
28bab8
 Integration with ABRT events
28bab8
@@ -71,6 +81,12 @@ OPTIONS
28bab8
 -t[ID]::
28bab8
    Upload FILEs to the already created case on RHTSupport site.
28bab8
 
28bab8
+-u::
28bab8
+   Submit uReport together with creating a new case.
28bab8
+
28bab8
+-C UR_CONFFILE::
28bab8
+   Configuration file for submitting uReports.
28bab8
+
28bab8
 FILES
28bab8
 -----
28bab8
 /usr/share/libreport/conf.d/plugins/rhtsupport.conf::
28bab8
diff --git a/src/include/ureport.h b/src/include/ureport.h
28bab8
index 3ee12cd..8bb1f6c 100644
28bab8
--- a/src/include/ureport.h
28bab8
+++ b/src/include/ureport.h
28bab8
@@ -47,7 +47,7 @@ struct ureport_preferences
28bab8
  */
28bab8
 struct ureport_server_config
28bab8
 {
28bab8
-    const char *ur_url;   ///< Web service URL
28bab8
+    char *ur_url;         ///< Web service URL
28bab8
     bool ur_ssl_verify;   ///< Verify HOST and PEER certificates
28bab8
     char *ur_client_cert; ///< Path to certificate used for client
28bab8
                           ///< authentication (or NULL)
28bab8
@@ -91,6 +91,17 @@ ureport_server_config_load(struct ureport_server_config *config,
28bab8
                            map_string_t *settings);
28bab8
 
28bab8
 /*
28bab8
+ * Configure HTTP(S) URL to server's index page
28bab8
+ *
28bab8
+ * @param config Where the url is stored
28bab8
+ * @param server_url Index URL
28bab8
+ */
28bab8
+#define ureport_server_config_set_url libreport_ureport_server_config_set_url
28bab8
+void
28bab8
+ureport_server_config_set_url(struct ureport_server_config *config,
28bab8
+                              char *server_url);
28bab8
+
28bab8
+/*
28bab8
  * Configure client certificate paths
28bab8
  *
28bab8
  * @param config Where the paths are stored
28bab8
diff --git a/src/lib/ureport.c b/src/lib/ureport.c
28bab8
index 5453a37..26f3562 100644
28bab8
--- a/src/lib/ureport.c
28bab8
+++ b/src/lib/ureport.c
28bab8
@@ -62,6 +62,14 @@ error:
28bab8
 }
28bab8
 
28bab8
 void
28bab8
+ureport_server_config_set_url(struct ureport_server_config *config,
28bab8
+                              char *server_url)
28bab8
+{
28bab8
+    free(config->ur_url);
28bab8
+    config->ur_url = server_url;
28bab8
+}
28bab8
+
28bab8
+void
28bab8
 ureport_server_config_set_client_auth(struct ureport_server_config *config,
28bab8
                                       const char *client_auth)
28bab8
 {
28bab8
@@ -211,7 +219,7 @@ void
28bab8
 ureport_server_config_load(struct ureport_server_config *config,
28bab8
                            map_string_t *settings)
28bab8
 {
28bab8
-    UREPORT_OPTION_VALUE_FROM_CONF(settings, "URL", config->ur_url, (const char *));
28bab8
+    UREPORT_OPTION_VALUE_FROM_CONF(settings, "URL", config->ur_url, xstrdup);
28bab8
     UREPORT_OPTION_VALUE_FROM_CONF(settings, "SSLVerify", config->ur_ssl_verify, string_to_bool);
28bab8
 
28bab8
     bool include_auth = false;
28bab8
@@ -248,6 +256,9 @@ ureport_server_config_init(struct ureport_server_config *config)
28bab8
 void
28bab8
 ureport_server_config_destroy(struct ureport_server_config *config)
28bab8
 {
28bab8
+    free(config->ur_url);
28bab8
+    config->ur_url = DESTROYED_POINTER;
28bab8
+
28bab8
     free(config->ur_client_cert);
28bab8
     config->ur_client_cert = DESTROYED_POINTER;
28bab8
 
28bab8
diff --git a/src/plugins/reporter-rhtsupport.c b/src/plugins/reporter-rhtsupport.c
28bab8
index 55bcda6..cd72c87 100644
28bab8
--- a/src/plugins/reporter-rhtsupport.c
28bab8
+++ b/src/plugins/reporter-rhtsupport.c
28bab8
@@ -17,6 +17,7 @@
28bab8
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28bab8
 */
28bab8
 #include <libtar.h>
28bab8
+#include "ureport.h"
28bab8
 #include "internal_libreport.h"
28bab8
 #include "client.h"
28bab8
 #include "libreport_curl.h"
28bab8
@@ -169,6 +170,51 @@ ret_clean:
28bab8
 }
28bab8
 
28bab8
 static
28bab8
+char *submit_ureport(const char *dump_dir_name, struct ureport_server_config *conf)
28bab8
+{
28bab8
+    struct dump_dir *dd = dd_opendir(dump_dir_name, DD_OPEN_READONLY);
28bab8
+    if (dd == NULL)
28bab8
+        return NULL;
28bab8
+
28bab8
+    report_result_t *rr_bthash = find_in_reported_to(dd, "uReport");
28bab8
+    dd_close(dd);
28bab8
+
28bab8
+    if (rr_bthash != NULL)
28bab8
+    {
28bab8
+        log_notice("uReport has already been submitted.");
28bab8
+        char *ret = xstrdup(rr_bthash->bthash);
28bab8
+        free_report_result(rr_bthash);
28bab8
+        return ret;
28bab8
+    }
28bab8
+
28bab8
+    char *json = ureport_from_dump_dir(dump_dir_name);
28bab8
+    if (json == NULL)
28bab8
+        return NULL;
28bab8
+
28bab8
+    struct ureport_server_response *resp = ureport_submit(json, conf);
28bab8
+    free(json);
28bab8
+    if (resp == NULL)
28bab8
+        return NULL;
28bab8
+
28bab8
+    char *bthash = NULL;
28bab8
+    if (!resp->urr_is_error)
28bab8
+    {
28bab8
+        if (resp->urr_bthash != NULL)
28bab8
+            bthash = xstrdup(resp->urr_bthash);
28bab8
+
28bab8
+        ureport_server_response_save_in_dump_dir(resp, dump_dir_name, conf);
28bab8
+
28bab8
+        if (resp->urr_message)
28bab8
+            log(resp->urr_message);
28bab8
+    }
28bab8
+    else if (g_verbose > 2)
28bab8
+        error_msg(_("Server responded with an error: '%s'"), resp->urr_value);
28bab8
+
28bab8
+    ureport_server_response_free(resp);
28bab8
+    return bthash;
28bab8
+}
28bab8
+
28bab8
+static
28bab8
 char *ask_rh_login(const char *message)
28bab8
 {
28bab8
     char *login = ask(message);
28bab8
@@ -203,6 +249,40 @@ char *get_param_string(const char *name, map_string_t *settings, const char *dfl
28bab8
     return xstrdup(envvar ? envvar : (get_map_string_item_or_NULL(settings, name) ? : dflt));
28bab8
 }
28bab8
 
28bab8
+static
28bab8
+void prepare_ureport_configuration(const char *urcfile,
28bab8
+        map_string_t *settings, struct ureport_server_config *urconf,
28bab8
+        const char *portal_url, const char *login, const char *password, bool ssl_verify)
28bab8
+{
28bab8
+    load_conf_file(urcfile, settings, false);
28bab8
+    ureport_server_config_init(urconf);
28bab8
+
28bab8
+    char *url = NULL;
28bab8
+    UREPORT_OPTION_VALUE_FROM_CONF(settings, "URL", url, xstrdup);
28bab8
+    if (url == NULL)
28bab8
+    {
28bab8
+        ureport_server_config_set_url(urconf, concat_path_file(portal_url, "/telemetry/abrt"));
28bab8
+        urconf->ur_ssl_verify = ssl_verify;
28bab8
+    }
28bab8
+    else
28bab8
+    {
28bab8
+        UREPORT_OPTION_VALUE_FROM_CONF(settings, "SSLVerify", urconf->ur_ssl_verify, string_to_bool);
28bab8
+        ureport_server_config_set_url(urconf, url);
28bab8
+    }
28bab8
+
28bab8
+    ureport_server_config_set_basic_auth(urconf, login, password);
28bab8
+
28bab8
+    bool include_auth = true;
28bab8
+    UREPORT_OPTION_VALUE_FROM_CONF(settings, "IncludeAuthData", include_auth, string_to_bool);
28bab8
+
28bab8
+    if (include_auth)
28bab8
+    {
28bab8
+        const char *auth_items = NULL;
28bab8
+        UREPORT_OPTION_VALUE_FROM_CONF(settings, "AuthDataItems", auth_items, (const char *));
28bab8
+        urconf->ur_prefs.urp_auth_items = parse_list(auth_items);
28bab8
+    }
28bab8
+}
28bab8
+
28bab8
 int main(int argc, char **argv)
28bab8
 {
28bab8
     abrt_init(argv);
28bab8
@@ -217,13 +297,14 @@ int main(int argc, char **argv)
28bab8
     const char *dump_dir_name = ".";
28bab8
     const char *case_no = NULL;
28bab8
     GList *conf_file = NULL;
28bab8
+    const char *urconf_file = UREPORT_CONF_FILE_PATH;
28bab8
 
28bab8
     /* Can't keep these strings/structs static: _() doesn't support that */
28bab8
     const char *program_usage_string = _(
28bab8
         "\n"
28bab8
         "& [-v] [-c CONFFILE] -d DIR\n"
28bab8
         "or:\n"
28bab8
-        "& [-v] [-c CONFFILE] [-d DIR] -t[ID] FILE...\n"
28bab8
+        "& [-v] [-c CONFFILE] [-d DIR] -t[ID] [-u -C UR_CONFFILE] FILE...\n"
28bab8
         "\n"
28bab8
         "Reports a problem to RHTSupport.\n"
28bab8
         "\n"
28bab8
@@ -240,6 +321,10 @@ int main(int argc, char **argv)
28bab8
         "\n"
28bab8
         "Option -tCASE uploads FILEs to the case CASE on RHTSupport site.\n"
28bab8
         "-d DIR is ignored."
28bab8
+        "\n"
28bab8
+        "Option -u sends ABRT crash statistics data (uReport) before creating a new case.\n"
28bab8
+        "uReport configuration is loaded from UR_CONFFILE which defaults to\n"
28bab8
+        UREPORT_CONF_FILE_PATH".\n"
28bab8
     );
28bab8
     enum {
28bab8
         OPT_v = 1 << 0,
28bab8
@@ -247,6 +332,7 @@ int main(int argc, char **argv)
28bab8
         OPT_c = 1 << 2,
28bab8
         OPT_t = 1 << 3,
28bab8
         OPT_f = 1 << 4,
28bab8
+        OPT_u = 1 << 5,
28bab8
     };
28bab8
     /* Keep enum above and order of options below in sync! */
28bab8
     struct options program_options[] = {
28bab8
@@ -255,6 +341,8 @@ int main(int argc, char **argv)
28bab8
         OPT_LIST(     'c', NULL, &conf_file    , "FILE", _("Configuration file (may be given many times)")),
28bab8
         OPT_OPTSTRING('t', NULL, &case_no      , "ID"  , _("Upload FILEs [to case with this ID]")),
28bab8
         OPT_BOOL(     'f', NULL, NULL          ,         _("Force reporting even if this problem is already reported")),
28bab8
+        OPT_BOOL(     'u', NULL, NULL          ,         _("Submit uReport before creating a new case")),
28bab8
+        OPT_STRING(   'C', NULL, &urconf_file  , "FILE", _("Configuration file for uReport")),
28bab8
         OPT_END()
28bab8
     };
28bab8
     unsigned opts = parse_opts(argc, argv, program_options, program_usage_string);
28bab8
@@ -303,6 +391,12 @@ int main(int argc, char **argv)
28bab8
                 /* RH has a 250m limit for web attachments (as of 2013) */
28bab8
                 envvar ? envvar : (get_map_string_item_or_NULL(settings, "BigSizeMB") ? : "200")
28bab8
     );
28bab8
+    envvar = getenv("RHTSupport_SubmitUReport");
28bab8
+    bool submit_ur = string_to_bool(
28bab8
+                envvar ? envvar :
28bab8
+                    (get_map_string_item_or_NULL(settings, "SubmitUReport") ? :
28bab8
+                        ((opts & OPT_u) ? "1" : "0"))
28bab8
+    );
28bab8
     free_map_string(settings);
28bab8
 
28bab8
     char *base_api_url = xstrdup(url);
28bab8
@@ -484,6 +578,21 @@ int main(int argc, char **argv)
28bab8
 
28bab8
     if (!(opts & OPT_t))
28bab8
     {
28bab8
+        char *bthash = NULL;
28bab8
+
28bab8
+        map_string_t *ursettings = new_map_string();
28bab8
+        struct ureport_server_config urconf;
28bab8
+
28bab8
+        prepare_ureport_configuration(urconf_file, ursettings, &urconf,
28bab8
+                url, login, password, ssl_verify);
28bab8
+
28bab8
+        if (submit_ur)
28bab8
+        {
28bab8
+            log(_("Sending ABRT crash statistics data"));
28bab8
+
28bab8
+            bthash = submit_ureport(dump_dir_name, &urconf);
28bab8
+        }
28bab8
+
28bab8
         log(_("Creating a new case"));
28bab8
 
28bab8
         char *product = NULL;
28bab8
@@ -555,10 +664,20 @@ int main(int argc, char **argv)
28bab8
         }
28bab8
         /* else: error msg was already emitted by dd_opendir */
28bab8
 
28bab8
+        if (bthash)
28bab8
+        {
28bab8
+            log(_("Linking ABRT crash statistics record with the case"));
28bab8
+            ureport_attach_string(bthash, "RHCID", result->url, &urconf);
28bab8
+        }
28bab8
+
28bab8
         url = result->url;
28bab8
         result->url = NULL;
28bab8
         free_rhts_result(result);
28bab8
         result = NULL;
28bab8
+
28bab8
+        ureport_server_config_destroy(&urconf);
28bab8
+        free_map_string(ursettings);
28bab8
+        free(bthash);
28bab8
     }
28bab8
 
28bab8
     char *remote_filename = NULL;
28bab8
diff --git a/src/plugins/reporter-ureport.c b/src/plugins/reporter-ureport.c
28bab8
index 7bd3fb3..06b5341 100644
28bab8
--- a/src/plugins/reporter-ureport.c
28bab8
+++ b/src/plugins/reporter-ureport.c
28bab8
@@ -100,7 +100,7 @@ int main(int argc, char **argv)
28bab8
     ureport_server_config_load(&config, settings);
28bab8
 
28bab8
     if (opts & OPT_u)
28bab8
-        config.ur_url = arg_server_url;
28bab8
+        ureport_server_config_set_url(&config, xstrdup(arg_server_url));
28bab8
     if (opts & OPT_k)
28bab8
         config.ur_ssl_verify = !insecure;
28bab8
     if (opts & OPT_t)
28bab8
-- 
28bab8
1.8.3.1
28bab8