You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
417 lines
15 KiB
417 lines
15 KiB
From 36010951c38483b4131012ebebd6b1f79c0ae799 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 37/37] Bugzilla: pass Bugzilla_token in all XML RPC |
|
calls |
|
|
|
Introduce the session parameters for XML RPC calls. These parameters are |
|
added to every XML RPC call. |
|
|
|
abrt_xmlrpc_call*() functions expected formatting string in form of |
|
"({...})" for some good but unknown reason. Since now, the functions |
|
expects formatting string without the outer brackets. |
|
|
|
() - means empty array (allowed in xmlrpc-c) |
|
{} - means empty structure (allowed in xmlrpc-c) |
|
|
|
Cite: |
|
|
|
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] |
|
|
|
Resolves rhbz#1090465 |
|
|
|
Signed-off-by: Jakub Filak <jfilak@redhat.com> |
|
|
|
mmilata: fix typo in commit message subject |
|
|
|
Signed-off-by: Jakub Filak <jfilak@redhat.com> |
|
--- |
|
src/lib/abrt_xmlrpc.c | 94 +++++++++++++++++++++++++++++++++-------- |
|
src/lib/abrt_xmlrpc.h | 3 ++ |
|
src/plugins/reporter-bugzilla.c | 34 --------------- |
|
src/plugins/rhbz.c | 64 ++++++++++++++++++++++++---- |
|
src/plugins/rhbz.h | 4 ++ |
|
5 files changed, 139 insertions(+), 60 deletions(-) |
|
|
|
diff --git a/src/lib/abrt_xmlrpc.c b/src/lib/abrt_xmlrpc.c |
|
index 48b556f..84ed50d 100644 |
|
--- a/src/lib/abrt_xmlrpc.c |
|
+++ b/src/lib/abrt_xmlrpc.c |
|
@@ -20,6 +20,12 @@ |
|
#include "abrt_xmlrpc.h" |
|
#include "proxies.h" |
|
|
|
+struct abrt_xmlrpc_param_pair |
|
+{ |
|
+ char *name; |
|
+ xmlrpc_value *value; |
|
+}; |
|
+ |
|
void abrt_xmlrpc_die(xmlrpc_env *env) |
|
{ |
|
error_msg_and_die("fatal: %s", env->fault_string); |
|
@@ -106,9 +112,77 @@ void abrt_xmlrpc_free_client(struct abrt_xmlrpc *ax) |
|
if (ax->ax_client) |
|
xmlrpc_client_destroy(ax->ax_client); |
|
|
|
+ for (GList *iter = ax->ax_session_params; iter; iter = g_list_next(iter)) |
|
+ { |
|
+ struct abrt_xmlrpc_param_pair *param_pair = (struct abrt_xmlrpc_param_pair *)iter->data; |
|
+ xmlrpc_DECREF(param_pair->value); |
|
+ free(param_pair->name); |
|
+ free(param_pair); |
|
+ } |
|
+ |
|
+ g_list_free(ax->ax_session_params); |
|
+ |
|
free(ax); |
|
} |
|
|
|
+void abrt_xmlrpc_client_add_session_param_string(xmlrpc_env *env, struct abrt_xmlrpc *ax, |
|
+ const char *name, const char *value) |
|
+{ |
|
+ struct abrt_xmlrpc_param_pair *new_ses_param = xmalloc(sizeof(*new_ses_param)); |
|
+ new_ses_param->name = xstrdup(name); |
|
+ |
|
+ new_ses_param->value = xmlrpc_string_new(env, value); |
|
+ if (env->fault_occurred) |
|
+ abrt_xmlrpc_die(env); |
|
+ |
|
+ ax->ax_session_params = g_list_append(ax->ax_session_params, new_ses_param); |
|
+} |
|
+ |
|
+/* internal helper function */ |
|
+static xmlrpc_value *abrt_xmlrpc_call_params_internal(xmlrpc_env *env, struct abrt_xmlrpc *ax, const char *method, xmlrpc_value *params) |
|
+{ |
|
+ xmlrpc_value *array = xmlrpc_array_new(env); |
|
+ if (env->fault_occurred) |
|
+ abrt_xmlrpc_die(env); |
|
+ |
|
+ bool destroy_params = false; |
|
+ if (xmlrpc_value_type(params) == XMLRPC_TYPE_NIL) |
|
+ { |
|
+ destroy_params = true; |
|
+ params = abrt_xmlrpc_params_new(env); |
|
+ } |
|
+ |
|
+ if (xmlrpc_value_type(params) == XMLRPC_TYPE_STRUCT) |
|
+ { |
|
+ for (GList *iter = ax->ax_session_params; iter; iter = g_list_next(iter)) |
|
+ { |
|
+ struct abrt_xmlrpc_param_pair *param_pair = (struct abrt_xmlrpc_param_pair *)iter->data; |
|
+ |
|
+ xmlrpc_struct_set_value(env, params, param_pair->name, param_pair->value); |
|
+ if (env->fault_occurred) |
|
+ abrt_xmlrpc_die(env); |
|
+ } |
|
+ } |
|
+ else |
|
+ { |
|
+ log_warning("Bug: not yet supported XML RPC call type."); |
|
+ } |
|
+ |
|
+ xmlrpc_array_append_item(env, array, params); |
|
+ if (env->fault_occurred) |
|
+ abrt_xmlrpc_die(env); |
|
+ |
|
+ xmlrpc_value *result = NULL; |
|
+ xmlrpc_client_call2(env, ax->ax_client, ax->ax_server_info, method, |
|
+ array, &result); |
|
+ |
|
+ if (destroy_params) |
|
+ xmlrpc_DECREF(params); |
|
+ |
|
+ xmlrpc_DECREF(array); |
|
+ return result; |
|
+} |
|
+ |
|
/* internal helper function */ |
|
static |
|
xmlrpc_value *abrt_xmlrpc_call_full_va(xmlrpc_env *env, struct abrt_xmlrpc *ax, |
|
@@ -133,10 +207,8 @@ xmlrpc_value *abrt_xmlrpc_call_full_va(xmlrpc_env *env, struct abrt_xmlrpc *ax, |
|
suffix); |
|
} |
|
else |
|
- { |
|
- xmlrpc_client_call2(env, ax->ax_client, ax->ax_server_info, method, |
|
- param, &result); |
|
- } |
|
+ result = abrt_xmlrpc_call_params_internal(env, ax, method, param); |
|
+ |
|
xmlrpc_DECREF(param); |
|
|
|
return result; |
|
@@ -192,25 +264,13 @@ void abrt_xmlrpc_params_add_array(xmlrpc_env *env, xmlrpc_value *params, const c |
|
if (env->fault_occurred) |
|
abrt_xmlrpc_die(env); |
|
} |
|
- |
|
xmlrpc_value *abrt_xmlrpc_call_params(xmlrpc_env *env, struct abrt_xmlrpc *ax, const char *method, xmlrpc_value *params) |
|
{ |
|
- xmlrpc_value *array = xmlrpc_array_new(env); |
|
- if (env->fault_occurred) |
|
- abrt_xmlrpc_die(env); |
|
- |
|
- xmlrpc_array_append_item(env, array, params); |
|
- if (env->fault_occurred) |
|
- abrt_xmlrpc_die(env); |
|
- |
|
- xmlrpc_value *result = NULL; |
|
- xmlrpc_client_call2(env, ax->ax_client, ax->ax_server_info, method, |
|
- array, &result); |
|
+ xmlrpc_value *result = abrt_xmlrpc_call_params_internal(env, ax, method, params); |
|
|
|
if (env->fault_occurred) |
|
abrt_xmlrpc_die(env); |
|
|
|
- xmlrpc_DECREF(array); |
|
return result; |
|
} |
|
|
|
diff --git a/src/lib/abrt_xmlrpc.h b/src/lib/abrt_xmlrpc.h |
|
index 945a887..e11dcec 100644 |
|
--- a/src/lib/abrt_xmlrpc.h |
|
+++ b/src/lib/abrt_xmlrpc.h |
|
@@ -23,6 +23,7 @@ |
|
* include/xmlrpc-c/base.h: typedef int32_t xmlrpc_int32; |
|
*/ |
|
|
|
+#include <glib.h> |
|
#include <xmlrpc-c/base.h> |
|
#include <xmlrpc-c/client.h> |
|
|
|
@@ -33,6 +34,7 @@ extern "C" { |
|
struct abrt_xmlrpc { |
|
xmlrpc_client *ax_client; |
|
xmlrpc_server_info *ax_server_info; |
|
+ GList *ax_session_params; |
|
}; |
|
|
|
xmlrpc_value *abrt_xmlrpc_array_new(xmlrpc_env *env); |
|
@@ -45,6 +47,7 @@ void abrt_xmlrpc_params_add_array(xmlrpc_env *env, xmlrpc_value *params, const c |
|
|
|
struct abrt_xmlrpc *abrt_xmlrpc_new_client(const char *url, int ssl_verify); |
|
void abrt_xmlrpc_free_client(struct abrt_xmlrpc *ax); |
|
+void abrt_xmlrpc_client_add_session_param_string(xmlrpc_env *env, struct abrt_xmlrpc *ax, const char *name, const char *value); |
|
void abrt_xmlrpc_die(xmlrpc_env *env) __attribute__((noreturn)); |
|
void abrt_xmlrpc_error(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..bad9ed4 100644 |
|
--- a/src/plugins/rhbz.c |
|
+++ b/src/plugins/rhbz.c |
|
@@ -85,7 +85,7 @@ 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)})", |
|
+ xmlrpc_value *xml_response = abrt_xmlrpc_call(ax, "Bug.comments", "{s:(i)}", |
|
"ids", bug_id); |
|
/* bugs |
|
* This is used for bugs specified in ids. This is a hash, where the |
|
@@ -215,7 +215,7 @@ bool rhbz_login(struct abrt_xmlrpc *ax, const char *login, const char *password) |
|
func_entry(); |
|
|
|
xmlrpc_env env; |
|
- xmlrpc_value *result = abrt_xmlrpc_call_full(&env, ax, "User.login", "({s:s,s:s})", |
|
+ xmlrpc_value *result = abrt_xmlrpc_call_full(&env, ax, "User.login", "{s:s,s:s}", |
|
"login", login, "password", password); |
|
|
|
if (env.fault_occurred) |
|
@@ -228,6 +228,14 @@ bool rhbz_login(struct abrt_xmlrpc *ax, const char *login, const char *password) |
|
return false; |
|
} |
|
|
|
+ char *token = rhbz_bug_read_item("token", result, RHBZ_READ_STR); |
|
+ if (token != NULL) |
|
+ { |
|
+ log_debug("Adding session param Bugzilla_token"); |
|
+ abrt_xmlrpc_client_add_session_param_string(&env, ax, "Bugzilla_token", token); |
|
+ free(token); |
|
+ } |
|
+ |
|
//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 |
|
@@ -297,7 +305,7 @@ unsigned rhbz_version(struct abrt_xmlrpc *ax) |
|
func_entry(); |
|
|
|
xmlrpc_value *result; |
|
- result = abrt_xmlrpc_call(ax, "Bugzilla.version", "()"); |
|
+ result = abrt_xmlrpc_call(ax, "Bugzilla.version", "{}"); |
|
char *version = NULL; |
|
if (result) |
|
version = rhbz_bug_read_item("version", result, RHBZ_READ_STR); |
|
@@ -472,7 +480,7 @@ 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)})", |
|
+ xmlrpc_value *xml_bug_response = abrt_xmlrpc_call(ax, "Bug.get", "{s:(i)}", |
|
"ids", bug_id); |
|
|
|
xmlrpc_value *bugs_memb = rhbz_get_member("bugs", xml_bug_response); |
|
@@ -668,7 +676,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}", |
|
"ids", bug_id, |
|
"summary", fn, |
|
"file_name", filename, |
|
@@ -737,7 +745,12 @@ 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", "{}"); |
|
+ |
|
+ if (env.fault_occurred) |
|
+ log_warning("xmlrpc fault: (%d) %s", env.fault_code, env.fault_string); |
|
+ |
|
if (result) |
|
xmlrpc_DECREF(result); |
|
} |
|
@@ -785,7 +798,7 @@ 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}}", |
|
"ids", bug_id, |
|
"cc", "add", mail, |
|
"nomail", nomail_notify |
|
@@ -822,7 +835,7 @@ 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}", |
|
"id", bug_id, "comment", comment, |
|
"private", private, "nomail", nomail_notify); |
|
|
|
@@ -835,7 +848,7 @@ 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}", |
|
"ids", bug_id, |
|
"url", url, |
|
|
|
@@ -848,3 +861,36 @@ void rhbz_set_url(struct abrt_xmlrpc *ax, int bug_id, const char *url, int flags |
|
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 = 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; |
|
+} |
|
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 |
|
|
|
|