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

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