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

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