Blame SOURCES/0037-Bugzilla-pass-Bugzilla_token-in-all-XML-RPC-calls.patch

562801
From 36010951c38483b4131012ebebd6b1f79c0ae799 Mon Sep 17 00:00:00 2001
562801
From: Jakub Filak <jfilak@redhat.com>
562801
Date: Wed, 23 Apr 2014 13:33:52 +0200
562801
Subject: [LIBREPORT PATCH 37/37] Bugzilla: pass Bugzilla_token in all XML RPC
562801
 calls
562801
562801
Introduce the session parameters for XML RPC calls. These parameters are
562801
added to every XML RPC call.
562801
562801
abrt_xmlrpc_call*() functions expected formatting string in form of
562801
"({...})" for some good but unknown reason. Since now, the functions
562801
expects formatting string without the outer brackets.
562801
562801
() - means empty array (allowed in xmlrpc-c)
562801
{} - means empty structure (allowed in xmlrpc-c)
562801
562801
Cite:
562801
562801
Instead of returning a cookie, the User.login call now returns a token
562801
that clients must pass in the Bugzilla_token parameter to subsequent
562801
RPC calls. If the token is not passed, Bugzilla will treat the RPC
562801
call as unauthenticated and will not allow access to non-public data.
562801
562801
See
562801
https://partner-bugzilla.redhat.com/docs/en/html/api/Bugzilla/WebService.html#LOGGING_IN
562801
for more details.
562801
562801
Client scripts that access Red Hat Bugzilla via XML-RPC or JSON-RPC
562801
and use login cookies for authentication must be updated to instead
562801
remember the token received when logging in and pass that token back
562801
to Bugzilla in subsequent RPC calls.
562801
562801
[http://post-office.corp.redhat.com/archives/bugzilla-list/2014-April/msg00005.html]
562801
562801
Resolves rhbz#1090465
562801
562801
Signed-off-by: Jakub Filak <jfilak@redhat.com>
562801
562801
mmilata: fix typo in commit message subject
562801
562801
Signed-off-by: Jakub Filak <jfilak@redhat.com>
562801
---
562801
 src/lib/abrt_xmlrpc.c           | 94 +++++++++++++++++++++++++++++++++--------
562801
 src/lib/abrt_xmlrpc.h           |  3 ++
562801
 src/plugins/reporter-bugzilla.c | 34 ---------------
562801
 src/plugins/rhbz.c              | 64 ++++++++++++++++++++++++----
562801
 src/plugins/rhbz.h              |  4 ++
562801
 5 files changed, 139 insertions(+), 60 deletions(-)
562801
562801
diff --git a/src/lib/abrt_xmlrpc.c b/src/lib/abrt_xmlrpc.c
562801
index 48b556f..84ed50d 100644
562801
--- a/src/lib/abrt_xmlrpc.c
562801
+++ b/src/lib/abrt_xmlrpc.c
562801
@@ -20,6 +20,12 @@
562801
 #include "abrt_xmlrpc.h"
562801
 #include "proxies.h"
562801
 
562801
+struct abrt_xmlrpc_param_pair
562801
+{
562801
+    char *name;
562801
+    xmlrpc_value *value;
562801
+};
562801
+
562801
 void abrt_xmlrpc_die(xmlrpc_env *env)
562801
 {
562801
     error_msg_and_die("fatal: %s", env->fault_string);
562801
@@ -106,9 +112,77 @@ void abrt_xmlrpc_free_client(struct abrt_xmlrpc *ax)
562801
     if (ax->ax_client)
562801
         xmlrpc_client_destroy(ax->ax_client);
562801
 
562801
+    for (GList *iter = ax->ax_session_params; iter; iter = g_list_next(iter))
562801
+    {
562801
+        struct abrt_xmlrpc_param_pair *param_pair = (struct abrt_xmlrpc_param_pair *)iter->data;
562801
+        xmlrpc_DECREF(param_pair->value);
562801
+        free(param_pair->name);
562801
+        free(param_pair);
562801
+    }
562801
+
562801
+    g_list_free(ax->ax_session_params);
562801
+
562801
     free(ax);
562801
 }
562801
 
562801
+void abrt_xmlrpc_client_add_session_param_string(xmlrpc_env *env, struct abrt_xmlrpc *ax,
562801
+        const char *name, const char *value)
562801
+{
562801
+    struct abrt_xmlrpc_param_pair *new_ses_param = xmalloc(sizeof(*new_ses_param));
562801
+    new_ses_param->name = xstrdup(name);
562801
+
562801
+    new_ses_param->value = xmlrpc_string_new(env, value);
562801
+    if (env->fault_occurred)
562801
+        abrt_xmlrpc_die(env);
562801
+
562801
+    ax->ax_session_params = g_list_append(ax->ax_session_params, new_ses_param);
562801
+}
562801
+
562801
+/* internal helper function */
562801
+static xmlrpc_value *abrt_xmlrpc_call_params_internal(xmlrpc_env *env, struct abrt_xmlrpc *ax, const char *method, xmlrpc_value *params)
562801
+{
562801
+    xmlrpc_value *array = xmlrpc_array_new(env);
562801
+    if (env->fault_occurred)
562801
+        abrt_xmlrpc_die(env);
562801
+
562801
+    bool destroy_params = false;
562801
+    if (xmlrpc_value_type(params) == XMLRPC_TYPE_NIL)
562801
+    {
562801
+        destroy_params = true;
562801
+        params = abrt_xmlrpc_params_new(env);
562801
+    }
562801
+
562801
+    if (xmlrpc_value_type(params) == XMLRPC_TYPE_STRUCT)
562801
+    {
562801
+        for (GList *iter = ax->ax_session_params; iter; iter = g_list_next(iter))
562801
+        {
562801
+            struct abrt_xmlrpc_param_pair *param_pair = (struct abrt_xmlrpc_param_pair *)iter->data;
562801
+
562801
+            xmlrpc_struct_set_value(env, params, param_pair->name, param_pair->value);
562801
+            if (env->fault_occurred)
562801
+                abrt_xmlrpc_die(env);
562801
+        }
562801
+    }
562801
+    else
562801
+    {
562801
+        log_warning("Bug: not yet supported XML RPC call type.");
562801
+    }
562801
+
562801
+    xmlrpc_array_append_item(env, array, params);
562801
+    if (env->fault_occurred)
562801
+        abrt_xmlrpc_die(env);
562801
+
562801
+    xmlrpc_value *result = NULL;
562801
+    xmlrpc_client_call2(env, ax->ax_client, ax->ax_server_info, method,
562801
+                        array, &result);
562801
+
562801
+    if (destroy_params)
562801
+        xmlrpc_DECREF(params);
562801
+
562801
+    xmlrpc_DECREF(array);
562801
+    return result;
562801
+}
562801
+
562801
 /* internal helper function */
562801
 static
562801
 xmlrpc_value *abrt_xmlrpc_call_full_va(xmlrpc_env *env, struct abrt_xmlrpc *ax,
562801
@@ -133,10 +207,8 @@ xmlrpc_value *abrt_xmlrpc_call_full_va(xmlrpc_env *env, struct abrt_xmlrpc *ax,
562801
             suffix);
562801
     }
562801
     else
562801
-    {
562801
-        xmlrpc_client_call2(env, ax->ax_client, ax->ax_server_info, method,
562801
-                            param, &result);
562801
-    }
562801
+        result = abrt_xmlrpc_call_params_internal(env, ax, method, param);
562801
+
562801
     xmlrpc_DECREF(param);
562801
 
562801
     return result;
562801
@@ -192,25 +264,13 @@ void abrt_xmlrpc_params_add_array(xmlrpc_env *env, xmlrpc_value *params, const c
562801
     if (env->fault_occurred)
562801
         abrt_xmlrpc_die(env);
562801
 }
562801
-
562801
 xmlrpc_value *abrt_xmlrpc_call_params(xmlrpc_env *env, struct abrt_xmlrpc *ax, const char *method, xmlrpc_value *params)
562801
 {
562801
-    xmlrpc_value *array = xmlrpc_array_new(env);
562801
-    if (env->fault_occurred)
562801
-        abrt_xmlrpc_die(env);
562801
-
562801
-    xmlrpc_array_append_item(env, array, params);
562801
-    if (env->fault_occurred)
562801
-        abrt_xmlrpc_die(env);
562801
-
562801
-    xmlrpc_value *result = NULL;
562801
-    xmlrpc_client_call2(env, ax->ax_client, ax->ax_server_info, method,
562801
-                        array, &result);
562801
+    xmlrpc_value *result = abrt_xmlrpc_call_params_internal(env, ax, method, params);
562801
 
562801
     if (env->fault_occurred)
562801
         abrt_xmlrpc_die(env);
562801
 
562801
-    xmlrpc_DECREF(array);
562801
     return result;
562801
 }
562801
 
562801
diff --git a/src/lib/abrt_xmlrpc.h b/src/lib/abrt_xmlrpc.h
562801
index 945a887..e11dcec 100644
562801
--- a/src/lib/abrt_xmlrpc.h
562801
+++ b/src/lib/abrt_xmlrpc.h
562801
@@ -23,6 +23,7 @@
562801
  * include/xmlrpc-c/base.h: typedef int32_t xmlrpc_int32;
562801
  */
562801
 
562801
+#include <glib.h>
562801
 #include <xmlrpc-c/base.h>
562801
 #include <xmlrpc-c/client.h>
562801
 
562801
@@ -33,6 +34,7 @@ extern "C" {
562801
 struct abrt_xmlrpc {
562801
     xmlrpc_client *ax_client;
562801
     xmlrpc_server_info *ax_server_info;
562801
+    GList *ax_session_params;
562801
 };
562801
 
562801
 xmlrpc_value *abrt_xmlrpc_array_new(xmlrpc_env *env);
562801
@@ -45,6 +47,7 @@ void abrt_xmlrpc_params_add_array(xmlrpc_env *env, xmlrpc_value *params, const c
562801
 
562801
 struct abrt_xmlrpc *abrt_xmlrpc_new_client(const char *url, int ssl_verify);
562801
 void abrt_xmlrpc_free_client(struct abrt_xmlrpc *ax);
562801
+void abrt_xmlrpc_client_add_session_param_string(xmlrpc_env *env, struct abrt_xmlrpc *ax, const char *name, const char *value);
562801
 void abrt_xmlrpc_die(xmlrpc_env *env) __attribute__((noreturn));
562801
 void abrt_xmlrpc_error(xmlrpc_env *env);
562801
 
562801
diff --git a/src/plugins/reporter-bugzilla.c b/src/plugins/reporter-bugzilla.c
562801
index 0e8b277..45aa2cc 100644
562801
--- a/src/plugins/reporter-bugzilla.c
562801
+++ b/src/plugins/reporter-bugzilla.c
562801
@@ -807,40 +807,6 @@ void login(struct abrt_xmlrpc *client, struct bugzilla_struct *rhbz)
562801
     }
562801
 }
562801
 
562801
-static
562801
-xmlrpc_value *rhbz_search_duphash(struct abrt_xmlrpc *ax,
562801
-                        const char *product,
562801
-                        const char *version,
562801
-                        const char *component,
562801
-                        const char *duphash)
562801
-{
562801
-    struct strbuf *query = strbuf_new();
562801
-
562801
-    strbuf_append_strf(query, "ALL whiteboard:\"%s\"", duphash);
562801
-
562801
-    if (product)
562801
-        strbuf_append_strf(query, " product:\"%s\"", product);
562801
-
562801
-    if (version)
562801
-        strbuf_append_strf(query, " version:\"%s\"", version);
562801
-
562801
-    if (component)
562801
-        strbuf_append_strf(query, " component:\"%s\"", component);
562801
-
562801
-    char *s = strbuf_free_nobuf(query);
562801
-    log_debug("search for '%s'", s);
562801
-    xmlrpc_value *search = abrt_xmlrpc_call(ax, "Bug.search", "({s:s})",
562801
-                                         "quicksearch", s);
562801
-    free(s);
562801
-    xmlrpc_value *bugs = rhbz_get_member("bugs", search);
562801
-    xmlrpc_DECREF(search);
562801
-
562801
-    if (!bugs)
562801
-        error_msg_and_die(_("Bug.search(quicksearch) return value did not contain member 'bugs'"));
562801
-
562801
-    return bugs;
562801
-}
562801
-
562801
 int main(int argc, char **argv)
562801
 {
562801
     abrt_init(argv);
562801
diff --git a/src/plugins/rhbz.c b/src/plugins/rhbz.c
562801
index 534aaed..bad9ed4 100644
562801
--- a/src/plugins/rhbz.c
562801
+++ b/src/plugins/rhbz.c
562801
@@ -85,7 +85,7 @@ static GList *rhbz_comments(struct abrt_xmlrpc *ax, int bug_id)
562801
      *           <value><array>
562801
      * ...
562801
      */
562801
-    xmlrpc_value *xml_response = abrt_xmlrpc_call(ax, "Bug.comments", "({s:(i)})",
562801
+    xmlrpc_value *xml_response = abrt_xmlrpc_call(ax, "Bug.comments", "{s:(i)}",
562801
                                                                       "ids", bug_id);
562801
     /* bugs
562801
      *     This is used for bugs specified in ids. This is a hash, where the
562801
@@ -215,7 +215,7 @@ bool rhbz_login(struct abrt_xmlrpc *ax, const char *login, const char *password)
562801
     func_entry();
562801
 
562801
     xmlrpc_env env;
562801
-    xmlrpc_value *result = abrt_xmlrpc_call_full(&env, ax, "User.login", "({s:s,s:s})",
562801
+    xmlrpc_value *result = abrt_xmlrpc_call_full(&env, ax, "User.login", "{s:s,s:s}",
562801
                                                  "login", login, "password", password);
562801
 
562801
     if (env.fault_occurred)
562801
@@ -228,6 +228,14 @@ bool rhbz_login(struct abrt_xmlrpc *ax, const char *login, const char *password)
562801
         return false;
562801
     }
562801
 
562801
+    char *token = rhbz_bug_read_item("token", result, RHBZ_READ_STR);
562801
+    if (token != NULL)
562801
+    {
562801
+        log_debug("Adding session param Bugzilla_token");
562801
+        abrt_xmlrpc_client_add_session_param_string(&env, ax, "Bugzilla_token", token);
562801
+        free(token);
562801
+    }
562801
+
562801
 //TODO: with URL like http://bugzilla.redhat.com (that is, with http: instead of https:)
562801
 //we are getting this error:
562801
 //Logging into Bugzilla at http://bugzilla.redhat.com
562801
@@ -297,7 +305,7 @@ unsigned rhbz_version(struct abrt_xmlrpc *ax)
562801
     func_entry();
562801
 
562801
     xmlrpc_value *result;
562801
-    result = abrt_xmlrpc_call(ax, "Bugzilla.version", "()");
562801
+    result = abrt_xmlrpc_call(ax, "Bugzilla.version", "{}");
562801
     char *version = NULL;
562801
     if (result)
562801
         version = rhbz_bug_read_item("version", result, RHBZ_READ_STR);
562801
@@ -472,7 +480,7 @@ struct bug_info *rhbz_bug_info(struct abrt_xmlrpc *ax, int bug_id)
562801
      *        <value><array><data>
562801
      *        ...
562801
      */
562801
-    xmlrpc_value *xml_bug_response = abrt_xmlrpc_call(ax, "Bug.get", "({s:(i)})",
562801
+    xmlrpc_value *xml_bug_response = abrt_xmlrpc_call(ax, "Bug.get", "{s:(i)}",
562801
                                                           "ids", bug_id);
562801
 
562801
     xmlrpc_value *bugs_memb = rhbz_get_member("bugs", xml_bug_response);
562801
@@ -668,7 +676,7 @@ int rhbz_attach_blob(struct abrt_xmlrpc *ax, const char *bug_id,
562801
      *   6 -> base64,  two arguments (char* plain data which will be encoded by xmlrpc-c to base64,
562801
      *                                size_t number of bytes to encode)
562801
      */
562801
-    result = abrt_xmlrpc_call(ax, "Bug.add_attachment", "({s:(s),s:s,s:s,s:s,s:6,s:i})",
562801
+    result = abrt_xmlrpc_call(ax, "Bug.add_attachment", "{s:(s),s:s,s:s,s:s,s:6,s:i}",
562801
                 "ids", bug_id,
562801
                 "summary", fn,
562801
                 "file_name", filename,
562801
@@ -737,7 +745,12 @@ void rhbz_logout(struct abrt_xmlrpc *ax)
562801
 {
562801
     func_entry();
562801
 
562801
-    xmlrpc_value* result = abrt_xmlrpc_call(ax, "User.logout", "(s)", "");
562801
+    xmlrpc_env env;
562801
+    xmlrpc_value *result = abrt_xmlrpc_call_full(&env, ax, "User.logout", "{}");
562801
+
562801
+    if (env.fault_occurred)
562801
+        log_warning("xmlrpc fault: (%d) %s", env.fault_code, env.fault_string);
562801
+
562801
     if (result)
562801
         xmlrpc_DECREF(result);
562801
 }
562801
@@ -785,7 +798,7 @@ void rhbz_mail_to_cc(struct abrt_xmlrpc *ax, int bug_id, const char *mail, int f
562801
     );
562801
 #endif
562801
     /* Bugzilla 4.0+ uses this API: */
562801
-    result = abrt_xmlrpc_call(ax, "Bug.update", "({s:i,s:{s:(s),s:i}})",
562801
+    result = abrt_xmlrpc_call(ax, "Bug.update", "{s:i,s:{s:(s),s:i}}",
562801
                               "ids", bug_id,
562801
                               "cc", "add", mail,
562801
                                     "nomail", nomail_notify
562801
@@ -822,7 +835,7 @@ void rhbz_add_comment(struct abrt_xmlrpc *ax, int bug_id, const char *comment,
562801
     int nomail_notify = !!IS_NOMAIL_NOTIFY(flags);
562801
 
562801
     xmlrpc_value *result;
562801
-    result = abrt_xmlrpc_call(ax, "Bug.add_comment", "({s:i,s:s,s:b,s:i})",
562801
+    result = abrt_xmlrpc_call(ax, "Bug.add_comment", "{s:i,s:s,s:b,s:i}",
562801
                               "id", bug_id, "comment", comment,
562801
                               "private", private, "nomail", nomail_notify);
562801
 
562801
@@ -835,7 +848,7 @@ void rhbz_set_url(struct abrt_xmlrpc *ax, int bug_id, const char *url, int flags
562801
     func_entry();
562801
 
562801
     const int nomail_notify = !!IS_NOMAIL_NOTIFY(flags);
562801
-    xmlrpc_value *result = abrt_xmlrpc_call(ax, "Bug.update", "({s:i,s:s,s:i})",
562801
+    xmlrpc_value *result = abrt_xmlrpc_call(ax, "Bug.update", "{s:i,s:s,s:i}",
562801
                               "ids", bug_id,
562801
                               "url", url,
562801
 
562801
@@ -848,3 +861,36 @@ void rhbz_set_url(struct abrt_xmlrpc *ax, int bug_id, const char *url, int flags
562801
     if (result)
562801
         xmlrpc_DECREF(result);
562801
 }
562801
+
562801
+xmlrpc_value *rhbz_search_duphash(struct abrt_xmlrpc *ax,
562801
+                        const char *product,
562801
+                        const char *version,
562801
+                        const char *component,
562801
+                        const char *duphash)
562801
+{
562801
+    struct strbuf *query = strbuf_new();
562801
+
562801
+    strbuf_append_strf(query, "ALL whiteboard:\"%s\"", duphash);
562801
+
562801
+    if (product)
562801
+        strbuf_append_strf(query, " product:\"%s\"", product);
562801
+
562801
+    if (version)
562801
+        strbuf_append_strf(query, " version:\"%s\"", version);
562801
+
562801
+    if (component)
562801
+        strbuf_append_strf(query, " component:\"%s\"", component);
562801
+
562801
+    char *s = strbuf_free_nobuf(query);
562801
+    log_debug("search for '%s'", s);
562801
+    xmlrpc_value *search = abrt_xmlrpc_call(ax, "Bug.search", "{s:s}", "quicksearch", s);
562801
+
562801
+    free(s);
562801
+    xmlrpc_value *bugs = rhbz_get_member("bugs", search);
562801
+    xmlrpc_DECREF(search);
562801
+
562801
+    if (!bugs)
562801
+        error_msg_and_die(_("Bug.search(quicksearch) return value did not contain member 'bugs'"));
562801
+
562801
+    return bugs;
562801
+}
562801
diff --git a/src/plugins/rhbz.h b/src/plugins/rhbz.h
562801
index 742927a..976d333 100644
562801
--- a/src/plugins/rhbz.h
562801
+++ b/src/plugins/rhbz.h
562801
@@ -112,6 +112,10 @@ struct bug_info *rhbz_find_origin_bug_closed_duplicate(struct abrt_xmlrpc *ax,
562801
                                                        struct bug_info *bi);
562801
 unsigned rhbz_version(struct abrt_xmlrpc *ax);
562801
 
562801
+xmlrpc_value *rhbz_search_duphash(struct abrt_xmlrpc *ax,
562801
+                        const char *product, const char *version, const char *component,
562801
+                        const char *duphash);
562801
+
562801
 #ifdef __cplusplus
562801
 }
562801
 #endif
562801
-- 
562801
1.8.3.1
562801