Blob Blame History Raw
From 2c86c3e41c49a6916fc44852555baccdbf7366da Mon Sep 17 00:00:00 2001
From: Jakub Filak <jfilak@redhat.com>
Date: Wed, 23 Apr 2014 13:33:52 +0200
Subject: [LIBREPORT PATCH 1/2] Bugzilla: pass Bugzilla_token in all relevant
 XML RPC calls

Affected functions:
    Bug.update
    Bug.add_attachement
    Bug.add_comment
    Bug.get
    Bug.comments
    Bug.create
    Bug.search
    User.logout

Not affected functions:
    Bugzilla.version

Instead of returning a cookie, the User.login call now returns a token
that clients must pass in the Bugzilla_token parameter to subsequent
RPC calls. If the token is not passed, Bugzilla will treat the RPC
call as unauthenticated and will not allow access to non-public data.

See
https://partner-bugzilla.redhat.com/docs/en/html/api/Bugzilla/WebService.html#LOGGING_IN
for more details.

Client scripts that access Red Hat Bugzilla via XML-RPC or JSON-RPC
and use login cookies for authentication must be updated to instead
remember the token received when logging in and pass that token back
to Bugzilla in subsequent RPC calls.

[http://post-office.corp.redhat.com/archives/bugzilla-list/2014-April/msg00005.html]

Signed-off-by: Jakub Filak <jfilak@redhat.com>

mmilata: fix typo in commit message subject
---
 src/lib/abrt_xmlrpc.c           |  3 ++
 src/lib/abrt_xmlrpc.h           |  4 +++
 src/plugins/reporter-bugzilla.c | 34 ------------------
 src/plugins/rhbz.c              | 78 ++++++++++++++++++++++++++++++++++-------
 src/plugins/rhbz.h              |  4 +++
 5 files changed, 76 insertions(+), 47 deletions(-)

diff --git a/src/lib/abrt_xmlrpc.c b/src/lib/abrt_xmlrpc.c
index 48b556f..24bdd9e 100644
--- a/src/lib/abrt_xmlrpc.c
+++ b/src/lib/abrt_xmlrpc.c
@@ -106,6 +106,9 @@ void abrt_xmlrpc_free_client(struct abrt_xmlrpc *ax)
     if (ax->ax_client)
         xmlrpc_client_destroy(ax->ax_client);
 
+    if (ax->ax_session_data && ax->ax_session_data_free)
+        ax->ax_session_data_free(ax->ax_session_data);
+
     free(ax);
 }
 
diff --git a/src/lib/abrt_xmlrpc.h b/src/lib/abrt_xmlrpc.h
index 945a887..ff7a65c 100644
--- a/src/lib/abrt_xmlrpc.h
+++ b/src/lib/abrt_xmlrpc.h
@@ -30,9 +30,13 @@
 extern "C" {
 #endif
 
+typedef void (*abrt_xmlrpc_destroy_fn)(void *);
+
 struct abrt_xmlrpc {
     xmlrpc_client *ax_client;
     xmlrpc_server_info *ax_server_info;
+    void *ax_session_data;
+    abrt_xmlrpc_destroy_fn ax_session_data_free;
 };
 
 xmlrpc_value *abrt_xmlrpc_array_new(xmlrpc_env *env);
diff --git a/src/plugins/reporter-bugzilla.c b/src/plugins/reporter-bugzilla.c
index 0e8b277..45aa2cc 100644
--- a/src/plugins/reporter-bugzilla.c
+++ b/src/plugins/reporter-bugzilla.c
@@ -807,40 +807,6 @@ void login(struct abrt_xmlrpc *client, struct bugzilla_struct *rhbz)
     }
 }
 
-static
-xmlrpc_value *rhbz_search_duphash(struct abrt_xmlrpc *ax,
-                        const char *product,
-                        const char *version,
-                        const char *component,
-                        const char *duphash)
-{
-    struct strbuf *query = strbuf_new();
-
-    strbuf_append_strf(query, "ALL whiteboard:\"%s\"", duphash);
-
-    if (product)
-        strbuf_append_strf(query, " product:\"%s\"", product);
-
-    if (version)
-        strbuf_append_strf(query, " version:\"%s\"", version);
-
-    if (component)
-        strbuf_append_strf(query, " component:\"%s\"", component);
-
-    char *s = strbuf_free_nobuf(query);
-    log_debug("search for '%s'", s);
-    xmlrpc_value *search = abrt_xmlrpc_call(ax, "Bug.search", "({s:s})",
-                                         "quicksearch", s);
-    free(s);
-    xmlrpc_value *bugs = rhbz_get_member("bugs", search);
-    xmlrpc_DECREF(search);
-
-    if (!bugs)
-        error_msg_and_die(_("Bug.search(quicksearch) return value did not contain member 'bugs'"));
-
-    return bugs;
-}
-
 int main(int argc, char **argv)
 {
     abrt_init(argv);
diff --git a/src/plugins/rhbz.c b/src/plugins/rhbz.c
index 534aaed..bc0f87a 100644
--- a/src/plugins/rhbz.c
+++ b/src/plugins/rhbz.c
@@ -85,8 +85,9 @@ static GList *rhbz_comments(struct abrt_xmlrpc *ax, int bug_id)
      *           <value><array>
      * ...
      */
-    xmlrpc_value *xml_response = abrt_xmlrpc_call(ax, "Bug.comments", "({s:(i)})",
-                                                                      "ids", bug_id);
+    xmlrpc_value *xml_response = abrt_xmlrpc_call(ax, "Bug.comments", "({s:(i),s:s})",
+                                                                      "ids", bug_id,
+                                                                      "Bugzilla_token", (char *)ax->ax_session_data);
     /* bugs
      *     This is used for bugs specified in ids. This is a hash, where the
      *     keys are the numeric ids of the bugs, and the value is a hash with a
@@ -228,6 +229,9 @@ bool rhbz_login(struct abrt_xmlrpc *ax, const char *login, const char *password)
         return false;
     }
 
+    ax->ax_session_data = rhbz_bug_read_item("token", result, RHBZ_READ_STR);
+    ax->ax_session_data_free = (abrt_xmlrpc_destroy_fn)free;
+
 //TODO: with URL like http://bugzilla.redhat.com (that is, with http: instead of https:)
 //we are getting this error:
 //Logging into Bugzilla at http://bugzilla.redhat.com
@@ -472,8 +476,9 @@ struct bug_info *rhbz_bug_info(struct abrt_xmlrpc *ax, int bug_id)
      *        <value><array><data>
      *        ...
      */
-    xmlrpc_value *xml_bug_response = abrt_xmlrpc_call(ax, "Bug.get", "({s:(i)})",
-                                                          "ids", bug_id);
+    xmlrpc_value *xml_bug_response = abrt_xmlrpc_call(ax, "Bug.get", "({s:(i),s:s})",
+                                                          "ids", bug_id,
+                                                          "Bugzilla_token", (char *)ax->ax_session_data);
 
     xmlrpc_value *bugs_memb = rhbz_get_member("bugs", xml_bug_response);
     xmlrpc_value *bug_item = rhbz_array_item_at(bugs_memb, 0);
@@ -599,6 +604,7 @@ int rhbz_new_bug(struct abrt_xmlrpc *ax,
     abrt_xmlrpc_params_add_string(&env, params, "summary", (summary ? summary : bzsummary));
     abrt_xmlrpc_params_add_string(&env, params, "description", bzcomment);
     abrt_xmlrpc_params_add_string(&env, params, "status_whiteboard", status_whiteboard);
+    abrt_xmlrpc_params_add_string(&env, params, "Bugzilla_token", (char *)ax->ax_session_data);
 
     if(arch)
         abrt_xmlrpc_params_add_string(&env, params, "platform", arch);
@@ -668,7 +674,7 @@ int rhbz_attach_blob(struct abrt_xmlrpc *ax, const char *bug_id,
      *   6 -> base64,  two arguments (char* plain data which will be encoded by xmlrpc-c to base64,
      *                                size_t number of bytes to encode)
      */
-    result = abrt_xmlrpc_call(ax, "Bug.add_attachment", "({s:(s),s:s,s:s,s:s,s:6,s:i})",
+    result = abrt_xmlrpc_call(ax, "Bug.add_attachment", "({s:(s),s:s,s:s,s:s,s:6,s:i,s:s})",
                 "ids", bug_id,
                 "summary", fn,
                 "file_name", filename,
@@ -681,7 +687,8 @@ int rhbz_attach_blob(struct abrt_xmlrpc *ax, const char *bug_id,
                 /* Undocumented argument but it works with Red Hat Bugzilla version 4.2.4-7
                  * and version 4.4.rc1.b02
                  */
-                "nomail", nomail_notify
+                "nomail", nomail_notify,
+                "Bugzilla_token", (char *)ax->ax_session_data
     );
 
     free(fn);
@@ -737,7 +744,13 @@ void rhbz_logout(struct abrt_xmlrpc *ax)
 {
     func_entry();
 
-    xmlrpc_value* result = abrt_xmlrpc_call(ax, "User.logout", "(s)", "");
+    xmlrpc_env env;
+    xmlrpc_value *result = abrt_xmlrpc_call_full(&env, ax, "User.logout", "({s:s})",
+                                    "Bugzilla_token", (char *)ax->ax_session_data);
+
+    if (env.fault_occurred)
+        log_warning("xmlrpc fault: (%d) %s", env.fault_code, env.fault_string);
+
     if (result)
         xmlrpc_DECREF(result);
 }
@@ -785,10 +798,11 @@ void rhbz_mail_to_cc(struct abrt_xmlrpc *ax, int bug_id, const char *mail, int f
     );
 #endif
     /* Bugzilla 4.0+ uses this API: */
-    result = abrt_xmlrpc_call(ax, "Bug.update", "({s:i,s:{s:(s),s:i}})",
+    result = abrt_xmlrpc_call(ax, "Bug.update", "({s:i,s:{s:(s),s:i},s:s})",
                               "ids", bug_id,
                               "cc", "add", mail,
-                                    "nomail", nomail_notify
+                                    "nomail", nomail_notify,
+                              "Bugzilla_token", (char *)ax->ax_session_data
     );
     if (result)
         xmlrpc_DECREF(result);
@@ -822,9 +836,10 @@ void rhbz_add_comment(struct abrt_xmlrpc *ax, int bug_id, const char *comment,
     int nomail_notify = !!IS_NOMAIL_NOTIFY(flags);
 
     xmlrpc_value *result;
-    result = abrt_xmlrpc_call(ax, "Bug.add_comment", "({s:i,s:s,s:b,s:i})",
+    result = abrt_xmlrpc_call(ax, "Bug.add_comment", "({s:i,s:s,s:b,s:i,s:s})",
                               "id", bug_id, "comment", comment,
-                              "private", private, "nomail", nomail_notify);
+                              "private", private, "nomail", nomail_notify,
+                              "Bugzilla_token", (char *)ax->ax_session_data);
 
     if (result)
         xmlrpc_DECREF(result);
@@ -835,16 +850,53 @@ void rhbz_set_url(struct abrt_xmlrpc *ax, int bug_id, const char *url, int flags
     func_entry();
 
     const int nomail_notify = !!IS_NOMAIL_NOTIFY(flags);
-    xmlrpc_value *result = abrt_xmlrpc_call(ax, "Bug.update", "({s:i,s:s,s:i})",
+    xmlrpc_value *result = abrt_xmlrpc_call(ax, "Bug.update", "({s:i,s:s,s:i,s:s})",
                               "ids", bug_id,
                               "url", url,
 
                 /* Undocumented argument but it works with Red Hat Bugzilla version 4.2.4-7
                  * and version 4.4.rc1.b02
                  */
-                              "nomail", nomail_notify
+                              "nomail", nomail_notify,
+                              "Bugzilla_token", (char *)ax->ax_session_data
     );
 
     if (result)
         xmlrpc_DECREF(result);
 }
+
+xmlrpc_value *rhbz_search_duphash(struct abrt_xmlrpc *ax,
+                        const char *product,
+                        const char *version,
+                        const char *component,
+                        const char *duphash)
+{
+    struct strbuf *query = strbuf_new();
+
+    strbuf_append_strf(query, "ALL whiteboard:\"%s\"", duphash);
+
+    if (product)
+        strbuf_append_strf(query, " product:\"%s\"", product);
+
+    if (version)
+        strbuf_append_strf(query, " version:\"%s\"", version);
+
+    if (component)
+        strbuf_append_strf(query, " component:\"%s\"", component);
+
+    char *s = strbuf_free_nobuf(query);
+    log_debug("search for '%s'", s);
+    xmlrpc_value *search = (ax->ax_session_data == NULL)
+            ? abrt_xmlrpc_call(ax, "Bug.search", "({s:s})", "quicksearch", s)
+            : abrt_xmlrpc_call(ax, "Bug.search", "({s:s,s:s})", "quicksearch", s,
+                               "Bugzilla_token", (char *)ax->ax_session_data);
+
+    free(s);
+    xmlrpc_value *bugs = rhbz_get_member("bugs", search);
+    xmlrpc_DECREF(search);
+
+    if (!bugs)
+        error_msg_and_die(_("Bug.search(quicksearch) return value did not contain member 'bugs'"));
+
+    return bugs;
+}
diff --git a/src/plugins/rhbz.h b/src/plugins/rhbz.h
index 742927a..976d333 100644
--- a/src/plugins/rhbz.h
+++ b/src/plugins/rhbz.h
@@ -112,6 +112,10 @@ struct bug_info *rhbz_find_origin_bug_closed_duplicate(struct abrt_xmlrpc *ax,
                                                        struct bug_info *bi);
 unsigned rhbz_version(struct abrt_xmlrpc *ax);
 
+xmlrpc_value *rhbz_search_duphash(struct abrt_xmlrpc *ax,
+                        const char *product, const char *version, const char *component,
+                        const char *duphash);
+
 #ifdef __cplusplus
 }
 #endif
-- 
1.8.3.1