diff options
author | Günther Wagner <info@gunibert.de> | 2022-06-19 13:12:23 +0000 |
---|---|---|
committer | Günther Wagner <info@gunibert.de> | 2022-06-19 13:12:23 +0000 |
commit | eb5e8399ac1b816671e88dcce7a10d1187ca49d8 (patch) | |
tree | cb3e110c53e30f86a925488b18ae939a3660d611 | |
parent | 683bfdd41c2ae92d41b9984d79f285dff5bdff2a (diff) | |
parent | aa9e968e381ede159414c6338da24d61ad0b5d8b (diff) | |
download | librest-eb5e8399ac1b816671e88dcce7a10d1187ca49d8.tar.gz |
Merge branch 'release_0_9_1' into 'master'
Release 0.9.1
See merge request GNOME/librest!26
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .gitlab-ci.yml | 4 | ||||
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | examples/continuous-twitter.c | 90 | ||||
-rw-r--r-- | examples/demo/demo-rest-page.c | 165 | ||||
-rw-r--r-- | examples/demo/demo-rest-page.ui | 73 | ||||
-rw-r--r-- | examples/meson.build | 3 | ||||
-rw-r--r-- | examples/post-twitter-media.c | 101 | ||||
-rw-r--r-- | examples/post-twitter.c | 77 | ||||
-rw-r--r-- | meson.build | 4 | ||||
-rw-r--r-- | rest/meson.build | 23 | ||||
-rw-r--r-- | rest/oauth-proxy-call.c | 391 | ||||
-rw-r--r-- | rest/oauth-proxy-call.h | 51 | ||||
-rw-r--r-- | rest/oauth-proxy.c | 803 | ||||
-rw-r--r-- | rest/oauth-proxy.h | 110 | ||||
-rw-r--r-- | rest/rest.h | 2 | ||||
-rw-r--r-- | rest/test-runner.c | 34 |
17 files changed, 12 insertions, 1924 deletions
@@ -69,3 +69,4 @@ tests/proxy tests/proxy-continuous tests/threaded tests/xml +rust
\ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 73152d6..47d002c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,7 +6,7 @@ variables: MANIFEST_PATH: 'examples/demo/org.gnome.RestDemo.json' FLATPAK_MODULE: 'librest-demo' FLATPAK_BUILD_DIR: build - LAST_ABI_BREAK: "85bd00adfa6e06d3426ce7c9007e68e62f51be14" + LAST_ABI_BREAK: "a36606b6633e4244740793ab3a17d392b1cf6035" image: fedora:36 @@ -88,7 +88,7 @@ reference: libsoup3-devel gtk-doc json-glib-devel - MESON_VERSION: "0.55.3" + MESON_VERSION: "0.56" MESON_EXTRA_FLAGS: "-Dintrospection=true -Dexamples=false" DOCS_FLAGS: -Dgtk_doc=true DOCS_PATH: docs/librest-1.0 @@ -2,6 +2,10 @@ Overview of changes for 0.91 ============================ * removed RestAuth object * added an demo application to showcase librest +* removed OAuth1 Proxy +* added soupapiversion to pkg-config file in order to check the which soup version + this library got built with +* build against libsoup3 by default Overview of changes for 0.9 =========================== diff --git a/examples/continuous-twitter.c b/examples/continuous-twitter.c deleted file mode 100644 index 7a915e0..0000000 --- a/examples/continuous-twitter.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * librest - RESTful web services access - * Copyright (c) 2008, 2009, Intel Corporation. - * - * Authors: Rob Bradford <rob@linux.intel.com> - * Ross Burton <ross@linux.intel.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include <rest/oauth-proxy.h> -#include <stdio.h> - -static void -_call_continous_cb (RestProxyCall *call, - const gchar *buf, - gsize len, - const GError *error, - GObject *weak_object, - gpointer userdata) -{ - g_message ("%s", buf); -} - -int -main (int argc, char **argv) -{ - RestProxy *proxy; - RestProxyCall *call; - GError *error = NULL; - char pin[256]; - GMainLoop *loop; - - loop = g_main_loop_new (NULL, FALSE); - - /* Create the proxy */ - proxy = oauth_proxy_new ("UfXFxDbUjk41scg0kmkFwA", - "pYQlfI2ZQ1zVK0f01dnfhFTWzizBGDnhNJIw6xwto", - "https://api.twitter.com/", FALSE); - - /* First stage authentication, this gets a request token */ - if (!oauth_proxy_request_token (OAUTH_PROXY (proxy), "oauth/request_token", "oob", &error)) - g_error ("Cannot get request token: %s", error->message); - - /* From the token construct a URL for the user to visit */ - g_print ("Go to http://twitter.com/oauth/authorize?oauth_token=%s then enter the PIN\n", - oauth_proxy_get_token (OAUTH_PROXY (proxy))); - - fgets (pin, sizeof (pin), stdin); - g_strchomp (pin); - - /* Second stage authentication, this gets an access token */ - if (!oauth_proxy_access_token (OAUTH_PROXY (proxy), "oauth/access_token", pin, &error)) - g_error ("Cannot get access token: %s", error->message); - - /* We're now authenticated */ - - /* Post the status message */ - call = rest_proxy_new_call (proxy); - g_object_set (proxy, "url-format", "http://stream.twitter.com/", NULL); - rest_proxy_call_set_function (call, "1/statuses/filter.json"); - rest_proxy_call_set_method (call, "GET"); - rest_proxy_call_add_param (call, "track", "Cameron"); - rest_proxy_call_add_param (call, "delimited", "length"); - - rest_proxy_call_continuous (call, - _call_continous_cb, - NULL, - NULL, - NULL); - - g_main_loop_run (loop); - - g_object_unref (call); - g_object_unref (proxy); - - return 0; -} diff --git a/examples/demo/demo-rest-page.c b/examples/demo/demo-rest-page.c index e36fee7..d33d7b6 100644 --- a/examples/demo/demo-rest-page.c +++ b/examples/demo/demo-rest-page.c @@ -52,12 +52,6 @@ struct _DemoRestPage GtkWidget *digest_username; GtkWidget *digest_password; - /* oauth 1 auth */ - GtkWidget *oauth1_client_identifier; - GtkWidget *oauth1_client_secret; - GtkWidget *oauth1_get_access_token; - RestProxy *oauth1_proxy; - /* oauth 2 auth */ GtkWidget *oauth2_client_identifier; GtkWidget *oauth2_client_secret; @@ -73,7 +67,6 @@ typedef enum { AUTHMODE_NO, AUTHMODE_BASIC, AUTHMODE_DIGEST, - AUTHMODE_OAUTH1, AUTHMODE_OAUTH2 } AuthMode; @@ -90,7 +83,6 @@ demo_rest_page_finalize (GObject *object) { DemoRestPage *self = (DemoRestPage *)object; - g_clear_object (&self->oauth1_proxy); g_clear_object (&self->oauth2_proxy); g_clear_pointer (&self->pkce, rest_pkce_code_challenge_free); @@ -111,8 +103,6 @@ get_current_auth_mode (DemoRestPage *self) return AUTHMODE_BASIC; else if (g_strcmp0 (stack_name, "digest") == 0) return AUTHMODE_DIGEST; - else if (g_strcmp0 (stack_name, "oauth1") == 0) - return AUTHMODE_OAUTH1; else if (g_strcmp0 (stack_name, "oauth2") == 0) return AUTHMODE_OAUTH2; @@ -135,9 +125,7 @@ set_oauth_btn_active (DemoRestPage *self, { gtk_button_set_label (btn, "Get access token..."); gtk_widget_set_css_classes (GTK_WIDGET (btn), (const char*[]){ "suggested-action", NULL }); - if (proxy == self->oauth1_proxy) - g_clear_object (&self->oauth1_proxy); - else if (proxy == self->oauth2_proxy) + if (proxy == self->oauth2_proxy) g_clear_object (&self->oauth2_proxy); } } @@ -196,23 +184,6 @@ set_text_response (DemoRestPage *self, } static void -demo_rest_page_fetched_oauth1_access_token (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - DemoRestPage *self = (DemoRestPage *)user_data; - RestProxy *proxy = (RestProxy *)object; - g_autoptr(GError) error = NULL; - - g_assert (G_IS_OBJECT (object)); - g_assert (G_IS_ASYNC_RESULT (result)); - - oauth_proxy_access_token_finish (OAUTH_PROXY (proxy), result, &error); - if (error) - set_oauth_btn_active (self, GTK_BUTTON (self->oauth1_get_access_token), proxy, FALSE); -} - -static void demo_rest_page_fetched_oauth2_access_token (GObject *object, GAsyncResult *result, gpointer user_data) @@ -232,35 +203,6 @@ demo_rest_page_fetched_oauth2_access_token (GObject *object, } static void -oauth1_dialog_response (GtkDialog *dialog, - gint response_id, - DemoRestPage *self) -{ - switch (response_id) - { - case GTK_RESPONSE_OK: - { - const gchar *verifier = NULL; - GtkWidget *content_area = gtk_dialog_get_content_area (dialog); - GtkWidget *box = gtk_widget_get_first_child (content_area); - GtkWidget *entry = gtk_widget_get_last_child (box); - - verifier = gtk_editable_get_text (GTK_EDITABLE (entry)); - oauth_proxy_access_token_async (OAUTH_PROXY (self->oauth1_proxy), - "access_token", - verifier, - NULL, - demo_rest_page_fetched_oauth1_access_token, - self); - break; - } - case GTK_RESPONSE_CANCEL: - set_oauth_btn_active (self, GTK_BUTTON (self->oauth1_get_access_token), self->oauth1_proxy, FALSE); - break; - } -} - -static void oauth2_dialog_response (GtkDialog *dialog, gint response_id, DemoRestPage *self) @@ -290,48 +232,6 @@ oauth2_dialog_response (GtkDialog *dialog, } static GtkWidget * -demo_rest_page_create_oauth1_dialog (DemoRestPage *self, - RestProxy *proxy) -{ - GtkWidget *dialog = NULL; - GtkWidget *content_area; - GtkWidget *box, *lbl, *token_lbl, *verifier_entry; - g_autofree char *token_str = NULL; - - dialog = gtk_dialog_new_with_buttons ("Get Verifier...", - GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self))), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR, - "Ok", - GTK_RESPONSE_OK, - "Cancel", - GTK_RESPONSE_CANCEL, - NULL); - - content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); - gtk_widget_set_margin_top (content_area, 6); - gtk_widget_set_margin_start (content_area, 6); - gtk_widget_set_margin_bottom (content_area, 6); - gtk_widget_set_margin_end (content_area, 6); - - box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - lbl = gtk_label_new ("Open a browser and authorize this application..."); - gtk_box_append (GTK_BOX (box), lbl); - token_str = g_strdup_printf ("Use this token: %s", oauth_proxy_get_token (OAUTH_PROXY (proxy))); - token_lbl = gtk_label_new (token_str); - gtk_label_set_selectable (GTK_LABEL (token_lbl), TRUE); - gtk_box_append (GTK_BOX (box), token_lbl); - verifier_entry = gtk_entry_new (); - gtk_box_append (GTK_BOX (box), verifier_entry); - - gtk_box_append (GTK_BOX (content_area), box); - - g_signal_connect (dialog, "response", G_CALLBACK (oauth1_dialog_response), self); - g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_window_destroy), dialog); - - return dialog; -} - -static GtkWidget * demo_rest_page_create_oauth2_dialog (DemoRestPage *self, RestProxy *proxy) { @@ -378,57 +278,6 @@ demo_rest_page_create_oauth2_dialog (DemoRestPage *self, } static void -demo_rest_page_fetched_oauth1_request_token (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - DemoRestPage *self = (DemoRestPage *)user_data; - RestProxy *proxy = (RestProxy *)object; - GtkWidget *dialog = NULL; - g_autoptr(GError) error = NULL; - - g_assert (G_IS_OBJECT (object)); - g_assert (G_IS_ASYNC_RESULT (result)); - - oauth_proxy_request_token_finish (OAUTH_PROXY (proxy), result, &error); - if (error) - { - set_oauth_btn_active (self, GTK_BUTTON (self->oauth1_get_access_token), proxy, FALSE); - return; - } - - /* here we show a dialog requesting the user to a browser for authentication */ - dialog = demo_rest_page_create_oauth1_dialog (self, proxy); - - gtk_widget_show (dialog); -} - -static void -on_oauth1_get_access_token_clicked (GtkButton *btn, - gpointer user_data) -{ - DemoRestPage *self = (DemoRestPage *)user_data; - const char *url = NULL; - const char *consumer_key = NULL, *consumer_secret = NULL; - const char *function = NULL; - - if (self->oauth1_proxy != NULL) - { - set_oauth_btn_active (self, btn, self->oauth1_proxy, FALSE); - return; - } - - url = gtk_editable_get_text (GTK_EDITABLE (self->host)); - consumer_key = gtk_editable_get_text (GTK_EDITABLE (self->oauth1_client_identifier)); - consumer_secret = gtk_editable_get_text (GTK_EDITABLE (self->oauth1_client_secret)); - function = gtk_editable_get_text (GTK_EDITABLE (self->function)); - - self->oauth1_proxy = oauth_proxy_new (consumer_key, consumer_secret, url, FALSE); - oauth_proxy_request_token_async (OAUTH_PROXY (self->oauth1_proxy), function, "https://www.gnome.org", NULL, demo_rest_page_fetched_oauth1_request_token, self); - set_oauth_btn_active (self, btn, self->oauth1_proxy, TRUE); -} - -static void on_oauth2_get_access_token_clicked (GtkButton *btn, gpointer user_data) { @@ -533,13 +382,6 @@ on_send_clicked (GtkButton *btn, proxy = rest_proxy_new_with_authentication (url, FALSE, username, password); break; } - case AUTHMODE_OAUTH1: - { - g_object_set (self->oauth1_proxy, "url-format", url, NULL); - proxy = self->oauth1_proxy; - - break; - } case AUTHMODE_OAUTH2: { proxy = rest_proxy_new (url, FALSE); @@ -620,10 +462,6 @@ demo_rest_page_class_init (DemoRestPageClass *klass) /* digest auth */ gtk_widget_class_bind_template_child (widget_class, DemoRestPage, digest_username); gtk_widget_class_bind_template_child (widget_class, DemoRestPage, digest_password); - /* oauth 1 auth */ - gtk_widget_class_bind_template_child (widget_class, DemoRestPage, oauth1_client_identifier); - gtk_widget_class_bind_template_child (widget_class, DemoRestPage, oauth1_client_secret); - gtk_widget_class_bind_template_child (widget_class, DemoRestPage, oauth1_get_access_token); /* oauth 2 auth */ gtk_widget_class_bind_template_child (widget_class, DemoRestPage, oauth2_client_identifier); gtk_widget_class_bind_template_child (widget_class, DemoRestPage, oauth2_client_secret); @@ -635,7 +473,6 @@ demo_rest_page_class_init (DemoRestPageClass *klass) /* callbacks */ gtk_widget_class_bind_template_callback (widget_class, on_send_clicked); gtk_widget_class_bind_template_callback (widget_class, on_auth_method_activated); - gtk_widget_class_bind_template_callback (widget_class, on_oauth1_get_access_token_clicked); gtk_widget_class_bind_template_callback (widget_class, on_oauth2_get_access_token_clicked); } diff --git a/examples/demo/demo-rest-page.ui b/examples/demo/demo-rest-page.ui index a5771c8..3bfc004 100644 --- a/examples/demo/demo-rest-page.ui +++ b/examples/demo/demo-rest-page.ui @@ -81,7 +81,6 @@ <item>No Auth</item> <item>Basic</item> <item>Digest</item> - <item>OAuth1</item> <item>OAuth2</item> </items> </object> @@ -199,78 +198,6 @@ </child> <child> <object class="GtkStackPage"> - <property name="name">oauth1</property> - <property name="child"> - <object class="GtkGrid"> - <property name="column-spacing">8</property> - <property name="row-spacing">6</property> - <child> - <object class="GtkLabel"> - <property name="hexpand">true</property> - <property name="label">Client Identifier:</property> - <property name="xalign">1.0</property> - <layout> - <property name="column">0</property> - <property name="row">0</property> - </layout> - </object> - </child> - <child> - <object class="GtkEntry" id="oauth1_client_identifier"> - <property name="hexpand">true</property> - <layout> - <property name="column">1</property> - <property name="row">0</property> - </layout> - </object> - </child> - <child> - <object class="GtkImage"> - <property name="icon-name">dialog-question-symbolic</property> - <property name="tooltip-text">Typically the consumer key and secret can be obtained from the oauth provider.</property> - <layout> - <property name="column">2</property> - <property name="row">0</property> - </layout> - </object> - </child> - <child> - <object class="GtkLabel"> - <property name="label">Client Secret:</property> - <property name="xalign">1.0</property> - <layout> - <property name="column">0</property> - <property name="row">1</property> - </layout> - </object> - </child> - <child> - <object class="GtkEntry" id="oauth1_client_secret"> - <layout> - <property name="column">1</property> - <property name="row">1</property> - </layout> - </object> - </child> - <child> - <object class="GtkButton" id="oauth1_get_access_token"> - <property name="label">Get access token...</property> - <layout> - <property name="column">1</property> - <property name="row">2</property> - </layout> - <signal name="clicked" handler="on_oauth1_get_access_token_clicked" swapped="no" object="DemoRestPage"/> - <style> - <class name="suggested-action"/> - </style> - </object> - </child> - </object> - </property> - </object> - </child> - <child> - <object class="GtkStackPage"> <property name="name">oauth2</property> <property name="child"> <object class="GtkGrid"> diff --git a/examples/meson.build b/examples/meson.build index 37ea0ca..34c8f33 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -2,11 +2,8 @@ example_names = [ 'test-raw', 'test-xml', 'dump-xml', - 'post-twitter', - 'post-twitter-media', 'get-flickr-favorites', 'lastfm-shout', - 'continuous-twitter', 'gitlab-oauth2-example', ] diff --git a/examples/post-twitter-media.c b/examples/post-twitter-media.c deleted file mode 100644 index afae309..0000000 --- a/examples/post-twitter-media.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * librest - RESTful web services access - * Copyright (c) 2008, 2009, Intel Corporation. - * - * Authors: Rob Bradford <rob@linux.intel.com> - * Ross Burton <ross@linux.intel.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include <rest/oauth-proxy.h> -#include <stdio.h> - - -int -main (int argc, char **argv) -{ - RestProxy *proxy; - RestProxyCall *call; - RestParam *img_param; - GError *error = NULL; - char pin[256]; - gsize length; - gchar *contents; - - if (argc != 2) { - g_printerr ("$ post-twitter-media \"message\"\n"); - return -1; - } - - /* Create the proxy */ - proxy = oauth_proxy_new ("UfXFxDbUjk41scg0kmkFwA", - "pYQlfI2ZQ1zVK0f01dnfhFTWzizBGDnhNJIw6xwto", - "https://api.twitter.com/", FALSE); - - /* First stage authentication, this gets a request token */ - if (!oauth_proxy_request_token (OAUTH_PROXY (proxy), "oauth/request_token", "oob", &error)) - g_error ("Cannot get request token: %s", error->message); - - /* From the token construct a URL for the user to visit */ - g_print ("Go to http://twitter.com/oauth/authorize?oauth_token=%s then enter the PIN\n", - oauth_proxy_get_token (OAUTH_PROXY (proxy))); - - - fgets (pin, sizeof(pin), stdin); - g_strchomp (pin); - - - /* Second stage authentication, this gets an access token */ - if (!oauth_proxy_access_token (OAUTH_PROXY (proxy), "oauth/access_token", pin, &error)) - g_error ("Cannot get access token: %s", error->message); - - /* We're now authenticated */ - - - /* In order to send an image to twitter, we first need to load it ourselves. */ - if (!g_file_get_contents("test-media.png", &contents, &length, NULL)){ - g_error("reading file failed."); - return -1; - } - - - /* Create the multipart/form-data parameter */ - img_param = rest_param_new_full("media[]", REST_MEMORY_COPY, contents, - length, "multipart/form-data", "test-media.png"); - - - /* Post the status message */ - call = rest_proxy_new_call (REST_PROXY(proxy)); - rest_proxy_call_set_function (call, "1.1/statuses/update_with_media.json"); - rest_proxy_call_set_method (call, "POST"); - rest_proxy_call_add_param (call, "status", argv[1]); - rest_proxy_call_add_param_full(call, img_param); - - if (!rest_proxy_call_sync (call, &error)) { - g_message("Return Code: %u", rest_proxy_call_get_status_code(call)); - g_message("Payload: %s", rest_proxy_call_get_payload(call)); - g_error ("Cannot make call: %s", error->message); - } - - /* TODO: parse the XML and print something useful */ - g_print ("%s\n", rest_proxy_call_get_payload (call)); - - g_object_unref (call); - g_object_unref (proxy); - g_free (contents); - - return 0; -} diff --git a/examples/post-twitter.c b/examples/post-twitter.c deleted file mode 100644 index d87eb24..0000000 --- a/examples/post-twitter.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * librest - RESTful web services access - * Copyright (c) 2008, 2009, Intel Corporation. - * - * Authors: Rob Bradford <rob@linux.intel.com> - * Ross Burton <ross@linux.intel.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include <rest/oauth-proxy.h> -#include <stdio.h> - -int -main (int argc, char **argv) -{ - RestProxy *proxy; - RestProxyCall *call; - GError *error = NULL; - char pin[256]; - - if (argc != 2) { - g_printerr ("$ post-twitter \"message\"\n"); - return 1; - } - - /* Create the proxy */ - proxy = oauth_proxy_new ("UfXFxDbUjk41scg0kmkFwA", - "pYQlfI2ZQ1zVK0f01dnfhFTWzizBGDnhNJIw6xwto", - "https://api.twitter.com/", FALSE); - - /* First stage authentication, this gets a request token */ - if (!oauth_proxy_request_token (OAUTH_PROXY (proxy), "oauth/request_token", "oob", &error)) - g_error ("Cannot get request token: %s", error->message); - - /* From the token construct a URL for the user to visit */ - g_print ("Go to http://twitter.com/oauth/authorize?oauth_token=%s then enter the PIN\n", - oauth_proxy_get_token (OAUTH_PROXY (proxy))); - - fgets (pin, sizeof (pin), stdin); - g_strchomp (pin); - - /* Second stage authentication, this gets an access token */ - if (!oauth_proxy_access_token (OAUTH_PROXY (proxy), "oauth/access_token", pin, &error)) - g_error ("Cannot get access token: %s", error->message); - - /* We're now authenticated */ - - /* Post the status message */ - call = rest_proxy_new_call (proxy); - rest_proxy_call_set_function (call, "1/statuses/update.xml"); - rest_proxy_call_set_method (call, "POST"); - rest_proxy_call_add_param (call, "status", argv[1]); - - if (!rest_proxy_call_sync (call, &error)) - g_error ("Cannot make call: %s", error->message); - - /* TODO: parse the XML and print something useful */ - g_print ("%s\n", rest_proxy_call_get_payload (call)); - - g_object_unref (call); - g_object_unref (proxy); - - return 0; -} diff --git a/meson.build b/meson.build index db4eee6..5fb5956 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project('rest', 'c', - version: '0.9.0', + version: '0.9.1', license: 'LGPL2.1+', - meson_version: '>= 0.53', + meson_version: '>= 0.56', ) # Versioning diff --git a/rest/meson.build b/rest/meson.build index 5378ec7..0a16c36 100644 --- a/rest/meson.build +++ b/rest/meson.build @@ -17,8 +17,6 @@ librest_sources = [ 'rest-xml-node.c', 'rest-xml-parser.c', 'rest-main.c', - 'oauth-proxy.c', - 'oauth-proxy-call.c', 'sha1.c', 'rest-oauth2-proxy.c', @@ -31,8 +29,6 @@ librest_sources = [ ] librest_headers = [ - 'oauth-proxy-call.h', - 'oauth-proxy.h', 'rest-param.h', 'rest-params.h', 'rest-proxy-call.h', @@ -96,6 +92,7 @@ if get_option('introspection') namespace: 'Rest', symbol_prefix: 'rest', identifier_prefix: 'Rest', + export_packages: librest_pkg_string, includes: [ 'GObject-2.0', 'Gio-2.0', 'Soup-@0@'.format(libsoup_api_version) ], extra_args: librest_gir_extra_args, install: true, @@ -118,20 +115,4 @@ librest_dep = declare_dependency( dependencies: librest_deps, ) -meson.override_dependency('rest-1.0', librest_dep) - -# Test suite -test_runner_c_args = [ - '-DBUILD_TESTS', -] - -test_runner_bin = executable('test-runner', - [ 'test-runner.c', librest_sources ], - dependencies: librest_deps, - c_args: test_runner_c_args, - include_directories: config_h_inc, -) - -test('test-runner', test_runner_bin, - suite: 'rest', -) +meson.override_dependency('rest-1.0', librest_dep)
\ No newline at end of file diff --git a/rest/oauth-proxy-call.c b/rest/oauth-proxy-call.c deleted file mode 100644 index 560e928..0000000 --- a/rest/oauth-proxy-call.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * librest - RESTful web services access - * Copyright (c) 2008, 2009, Intel Corporation. - * - * Authors: Rob Bradford <rob@linux.intel.com> - * Ross Burton <ross@linux.intel.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include <string.h> -#include <libsoup/soup.h> -#include <rest/rest-proxy-call.h> -#include "oauth-proxy-call.h" -#include "oauth-proxy.h" -#include "rest-proxy-call-private.h" -#include "sha1.h" - -G_DEFINE_TYPE (OAuthProxyCall, oauth_proxy_call, REST_TYPE_PROXY_CALL) - -#define OAUTH_ENCODE_STRING(x_) (x_ ? g_uri_escape_string( (x_), NULL, TRUE) : g_strdup ("")) - -static char * -sign_plaintext (OAuthProxy *proxy) -{ - char *cs; - char *ts; - char *rv; - - cs = OAUTH_ENCODE_STRING (oauth_proxy_get_consumer_secret (proxy)); - ts = OAUTH_ENCODE_STRING (oauth_proxy_get_token_secret (proxy)); - rv = g_strconcat (cs, "&", ts, NULL); - - g_free (cs); - g_free (ts); - - return rv; -} - -static char * -encode_params (GHashTable *hash) -{ - GList *l, *keys; - GString *s; - - s = g_string_new (NULL); - - keys = g_hash_table_get_keys (hash); - keys = g_list_sort (keys, (GCompareFunc)strcmp); - - for (l = keys; l; l = l->next) { - const char *key; - const char *value; - char *k, *v; - - key = l->data; - value = g_hash_table_lookup (hash, key); - - k = OAUTH_ENCODE_STRING (key); - v = OAUTH_ENCODE_STRING (value); - - if (s->len) - g_string_append (s, "&"); - - g_string_append_printf (s, "%s=%s", k, v); - - g_free (k); - g_free (v); - } - - g_list_free (keys); - - return g_string_free (s, FALSE); -} - -/* - * Add the keys in @from to @hash. - */ -static void -merge_hashes (GHashTable *hash, GHashTable *from) -{ - GHashTableIter iter; - gpointer key, value; - - g_hash_table_iter_init (&iter, from); - while (g_hash_table_iter_next (&iter, &key, &value)) { - g_hash_table_insert (hash, key, value); - } -} - -static void -merge_params (GHashTable *hash, RestParams *params) -{ - RestParamsIter iter; - const char *name; - RestParam *param; - - rest_params_iter_init (&iter, params); - while (rest_params_iter_next (&iter, &name, ¶m)) { - if (rest_param_is_string (param)) - g_hash_table_insert (hash, (gpointer)name, (gpointer)rest_param_get_content (param)); - } -} - -static char * -sign_hmac (OAuthProxy *proxy, RestProxyCall *call, GHashTable *oauth_params) -{ - const char *url_str; - char *key, *signature, *ep, *eep; - const char *content_type; - GString *text; - GHashTable *all_params; - RestParamsIter params_iter; - RestParam *param; - gboolean encode_query_params = TRUE; - - url_str = rest_proxy_call_get_url (call); - - text = g_string_new (NULL); - g_string_append (text, rest_proxy_call_get_method (call)); - g_string_append_c (text, '&'); - if (oauth_proxy_is_echo (proxy)) - g_string_append_uri_escaped (text, oauth_proxy_get_service_url (proxy), NULL, FALSE); - else if (oauth_proxy_get_signature_host (proxy) != NULL) { - GUri *url = g_uri_parse (url_str, G_URI_FLAGS_ENCODED, NULL); - GUri *new_url; - gchar *signing_url; - - new_url = g_uri_build (g_uri_get_flags (url), - g_uri_get_scheme (url), - g_uri_get_userinfo (url), - oauth_proxy_get_signature_host (proxy), - g_uri_get_port (url), - g_uri_get_path (url), - g_uri_get_query (url), - g_uri_get_fragment (url)); - signing_url = g_uri_to_string (new_url); - - g_string_append_uri_escaped (text, signing_url, NULL, FALSE); - - g_uri_unref (new_url); - g_uri_unref (url); - g_free (signing_url); - } else { - g_string_append_uri_escaped (text, url_str, NULL, FALSE); - } - g_string_append_c (text, '&'); - - - - /* If one of the call's parameters is a multipart/form-data parameter, the - signature base string must be generated with only the oauth parameters */ - rest_params_iter_init(¶ms_iter, rest_proxy_call_get_params (call)); - while(rest_params_iter_next(¶ms_iter, (gpointer)&key, (gpointer)¶m)) { - content_type = rest_param_get_content_type(param); - if (strcmp(content_type, "multipart/form-data") == 0){ - encode_query_params = FALSE; - break; - } - } - - - - /* Merge the OAuth parameters with the query parameters */ - all_params = g_hash_table_new (g_str_hash, g_str_equal); - merge_hashes (all_params, oauth_params); - if (encode_query_params && !oauth_proxy_is_echo (proxy)) { - merge_params (all_params, rest_proxy_call_get_params (call)); - } - - - ep = encode_params (all_params); - eep = OAUTH_ENCODE_STRING (ep); - g_string_append (text, eep); - g_free (ep); - g_free (eep); - g_hash_table_destroy (all_params); - - /* PLAINTEXT signature value is the HMAC-SHA1 key value */ - key = sign_plaintext (proxy); - - signature = hmac_sha1 (key, text->str); - - g_free (key); - g_string_free (text, TRUE); - - return signature; -} - -/* - * From the OAuth parameters in @params, construct a HTTP Authorized header. - */ -static char * -make_authorized_header (GHashTable *oauth_params) -{ - GString *auth; - GHashTableIter iter; - const char *key, *value; - - g_assert (oauth_params); - - /* TODO: is "" okay for the realm, or should this be magically calculated or a - parameter? */ - auth = g_string_new ("OAuth realm=\"\""); - - g_hash_table_iter_init (&iter, oauth_params); - while (g_hash_table_iter_next (&iter, (gpointer)&key, (gpointer)&value)) { - gchar *encoded_value = OAUTH_ENCODE_STRING (value); - g_string_append_printf (auth, ", %s=\"%s\"", key, encoded_value); - g_free (encoded_value); - } - - return g_string_free (auth, FALSE); -} - -/* - * Remove any OAuth parameters from the @call parameters and add them to - * @oauth_params for building an Authorized header with. - */ -static void -steal_oauth_params (RestProxyCall *call, GHashTable *oauth_params) -{ - RestParams *params; - RestParamsIter iter; - const char *name; - RestParam *param; - GList *to_remove = NULL; - - params = rest_proxy_call_get_params (call); - - rest_params_iter_init (&iter, params); - while (rest_params_iter_next (&iter, &name, ¶m)) { - if (rest_param_is_string (param) && g_str_has_prefix (name, "oauth_")) { - g_hash_table_insert (oauth_params, - g_strdup (name), - g_strdup (rest_param_get_content (param))); - to_remove = g_list_prepend (to_remove, g_strdup (name)); - } - } - - while (to_remove) { - rest_params_remove (params, to_remove->data); - g_free (to_remove->data); - to_remove = g_list_delete_link (to_remove, to_remove); - } -} - -static gboolean -_prepare (RestProxyCall *call, GError **error) -{ - OAuthProxy *proxy = NULL; - char *s; - GHashTable *oauth_params; - - g_object_get (call, "proxy", &proxy, NULL); - - /* We have to make this hash free the strings and thus duplicate when we put - * them in since when we call call steal_oauth_params that has to duplicate - * the param names since it removes them from the main hash - */ - oauth_params = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - - /* First, steal any OAuth properties in the regular params */ - steal_oauth_params (call, oauth_params); - - g_hash_table_insert (oauth_params, g_strdup ("oauth_version"), g_strdup ("1.0")); - - s = g_strdup_printf ("%"G_GINT64_FORMAT , (gint64) time (NULL)); - g_hash_table_insert (oauth_params, g_strdup ("oauth_timestamp"), s); - - s = g_strdup_printf ("%u", g_random_int ()); - g_hash_table_insert (oauth_params, g_strdup ("oauth_nonce"), s); - - g_hash_table_insert (oauth_params, g_strdup ("oauth_consumer_key"), - g_strdup (oauth_proxy_get_consumer_key (proxy))); - - if (oauth_proxy_get_token (proxy)) - g_hash_table_insert (oauth_params, g_strdup ("oauth_token"), g_strdup (oauth_proxy_get_token (proxy))); - - switch (oauth_proxy_get_sign_method (proxy)) { - case PLAINTEXT: - g_hash_table_insert (oauth_params, g_strdup ("oauth_signature_method"), g_strdup ("PLAINTEXT")); - s = sign_plaintext (proxy); - break; - case HMAC_SHA1: - g_hash_table_insert (oauth_params, g_strdup ("oauth_signature_method"), g_strdup ("HMAC-SHA1")); - s = sign_hmac (proxy, call, oauth_params); - break; - } - g_hash_table_insert (oauth_params, g_strdup ("oauth_signature"), s); - - s = make_authorized_header (oauth_params); - if (oauth_proxy_is_echo (proxy)) { - rest_proxy_call_add_header (call, "X-Verify-Credentials-Authorization", s); - rest_proxy_call_add_param (call, "X-Auth-Service-Provider", oauth_proxy_get_service_url (proxy)); - } else { - rest_proxy_call_add_header (call, "Authorization", s); - } - g_free (s); - g_hash_table_destroy (oauth_params); - - g_object_unref (proxy); - - return TRUE; -} - -static void -oauth_proxy_call_class_init (OAuthProxyCallClass *klass) -{ - RestProxyCallClass *call_class = REST_PROXY_CALL_CLASS (klass); - - call_class->prepare = _prepare; -} - -static void -oauth_proxy_call_init (OAuthProxyCall *self) -{ -} - -void -oauth_proxy_call_parse_token_response (OAuthProxyCall *call) -{ - GHashTable *form; - OAuthProxy *proxy; - g_autofree gchar *formstr = NULL; - - /* TODO: sanity checks, error handling, probably return gboolean */ - - g_return_if_fail (OAUTH_IS_PROXY_CALL (call)); - - g_object_get (call, "proxy", &proxy, NULL); - g_object_unref (proxy); - - formstr = g_strndup (rest_proxy_call_get_payload (REST_PROXY_CALL (call)), rest_proxy_call_get_payload_length (REST_PROXY_CALL (call))); - form = soup_form_decode (formstr); - - oauth_proxy_set_token (proxy, g_hash_table_lookup (form, "oauth_token")); - oauth_proxy_set_token_secret (proxy, g_hash_table_lookup (form, "oauth_token_secret")); - /* This header should only exist for request_token replies, but its easier just to always check it */ - oauth_proxy_set_oauth10a (proxy, g_hash_table_lookup (form, "oauth_callback_confirmed") != NULL); - - g_hash_table_destroy (form); -} - -#if BUILD_TESTS -/* Test cases from http://wiki.oauth.net/TestCases */ -void -test_param_encoding (void) -{ - GHashTable *hash; - char *s; - -#define TEST(expected) \ - s = encode_params (hash); \ - g_assert_cmpstr (s, ==, expected); \ - g_free (s); \ - g_hash_table_remove_all (hash); - - hash = g_hash_table_new (g_str_hash, g_str_equal); - - g_hash_table_insert (hash, "name", NULL); - TEST("name="); - - g_hash_table_insert (hash, "a", "b"); - TEST("a=b"); - - g_hash_table_insert (hash, "a", "b"); - g_hash_table_insert (hash, "c", "d"); - TEST("a=b&c=d"); - - /* Because we don't (yet) support multiple parameters with the same key we've - changed this case slightly */ - g_hash_table_insert (hash, "b", "x!y"); - g_hash_table_insert (hash, "a", "x y"); - TEST("a=x%20y&b=x%21y"); - -#undef TEST -} -#endif diff --git a/rest/oauth-proxy-call.h b/rest/oauth-proxy-call.h deleted file mode 100644 index 6f473ee..0000000 --- a/rest/oauth-proxy-call.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * librest - RESTful web services access - * Copyright (c) 2008, 2009, Intel Corporation. - * - * Authors: Rob Bradford <rob@linux.intel.com> - * Ross Burton <ross@linux.intel.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef _OAUTH_PROXY_CALL -#define _OAUTH_PROXY_CALL - -#include <rest/rest-proxy-call.h> - -G_BEGIN_DECLS - -#define OAUTH_TYPE_PROXY_CALL oauth_proxy_call_get_type() -G_DECLARE_DERIVABLE_TYPE (OAuthProxyCall, oauth_proxy_call, OAUTH, PROXY_CALL, RestProxyCall) - -/** - * OAuthProxyCall: - * - * #OAuthProxyCall has no publicly available members. - */ - -struct _OAuthProxyCallClass { - RestProxyCallClass parent_class; - /*< private >*/ - /* padding for future expansion */ - gpointer _padding_dummy[8]; -}; - -void oauth_proxy_call_parse_token_response (OAuthProxyCall *call); - -G_END_DECLS - -#endif /* _OAUTH_PROXY_CALL */ - diff --git a/rest/oauth-proxy.c b/rest/oauth-proxy.c deleted file mode 100644 index d81c0d7..0000000 --- a/rest/oauth-proxy.c +++ /dev/null @@ -1,803 +0,0 @@ -/* - * librest - RESTful web services access - * Copyright (c) 2008, 2009, Intel Corporation. - * - * Authors: Rob Bradford <rob@linux.intel.com> - * Ross Burton <ross@linux.intel.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include <rest/rest-proxy.h> -#include <libsoup/soup.h> -#include "oauth-proxy.h" -#include "oauth-proxy-call.h" - -typedef struct { - /* Application "consumer" keys */ - char *consumer_key; - char *consumer_secret; - /* Authorisation "user" tokens */ - char *token; - char *token_secret; - /* How we're signing */ - OAuthSignatureMethod method; - /* OAuth 1.0a */ - gboolean oauth_10a; - char *verifier; - /* OAuth Echo */ - gboolean oauth_echo; - char *service_url; - /* URL to use for signatures */ - char *signature_host; -} OAuthProxyPrivate; - -struct _OAuthProxy { - RestProxy parent_instance; -}; - -G_DEFINE_TYPE_WITH_PRIVATE (OAuthProxy, oauth_proxy, REST_TYPE_PROXY) - -enum { - PROP_0, - PROP_CONSUMER_KEY, - PROP_CONSUMER_SECRET, - PROP_TOKEN, - PROP_TOKEN_SECRET, - PROP_SIGNATURE_HOST, - PROP_SIGNATURE_METHOD, -}; - -static RestProxyCall * -_new_call (RestProxy *proxy) -{ - RestProxyCall *call; - - call = g_object_new (OAUTH_TYPE_PROXY_CALL, - "proxy", proxy, - NULL); - - return call; -} - -static void -oauth_proxy_get_property (GObject *object, guint property_id, - GValue *value, GParamSpec *pspec) -{ - OAuthProxy *self = OAUTH_PROXY (object); - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (self); - - switch (property_id) { - case PROP_CONSUMER_KEY: - g_value_set_string (value, priv->consumer_key); - break; - case PROP_CONSUMER_SECRET: - g_value_set_string (value, priv->consumer_secret); - break; - case PROP_TOKEN: - g_value_set_string (value, priv->token); - break; - case PROP_TOKEN_SECRET: - g_value_set_string (value, priv->token_secret); - break; - case PROP_SIGNATURE_HOST: - g_value_set_string (value, priv->signature_host); - break; - case PROP_SIGNATURE_METHOD: - g_value_set_enum (value, priv->method); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -oauth_proxy_set_property (GObject *object, guint property_id, - const GValue *value, GParamSpec *pspec) -{ - OAuthProxy *self = OAUTH_PROXY (object); - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (self); - - switch (property_id) { - case PROP_CONSUMER_KEY: - if (priv->consumer_key) - g_free (priv->consumer_key); - priv->consumer_key = g_value_dup_string (value); - break; - case PROP_CONSUMER_SECRET: - if (priv->consumer_secret) - g_free (priv->consumer_secret); - priv->consumer_secret = g_value_dup_string (value); - break; - case PROP_TOKEN: - if (priv->token) - g_free (priv->token); - priv->token = g_value_dup_string (value); - break; - case PROP_TOKEN_SECRET: - if (priv->token_secret) - g_free (priv->token_secret); - priv->token_secret = g_value_dup_string (value); - break; - case PROP_SIGNATURE_HOST: - if (priv->signature_host) - g_free (priv->signature_host); - priv->signature_host = g_value_dup_string (value); - break; - case PROP_SIGNATURE_METHOD: - priv->method = g_value_get_enum (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -oauth_proxy_finalize (GObject *object) -{ - OAuthProxy *self = OAUTH_PROXY (object); - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (self); - - g_free (priv->consumer_key); - g_free (priv->consumer_secret); - g_free (priv->token); - g_free (priv->token_secret); - g_free (priv->verifier); - g_free (priv->service_url); - - G_OBJECT_CLASS (oauth_proxy_parent_class)->finalize (object); -} - -#ifndef G_PARAM_STATIC_STRINGS -#define G_PARAM_STATIC_STRINGS (G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB) -#endif - -static void -oauth_proxy_class_init (OAuthProxyClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - RestProxyClass *proxy_class = REST_PROXY_CLASS (klass); - GParamSpec *pspec; - - object_class->get_property = oauth_proxy_get_property; - object_class->set_property = oauth_proxy_set_property; - object_class->finalize = oauth_proxy_finalize; - - proxy_class->new_call = _new_call; - - pspec = g_param_spec_string ("consumer-key", "consumer-key", - "The consumer key", NULL, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY|G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_CONSUMER_KEY, - pspec); - - pspec = g_param_spec_string ("consumer-secret", "consumer-secret", - "The consumer secret", NULL, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY|G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_CONSUMER_SECRET, - pspec); - - pspec = g_param_spec_string ("token", "token", - "The request or access token", NULL, - G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_TOKEN, - pspec); - - pspec = g_param_spec_string ("token-secret", "token-secret", - "The request or access token secret", NULL, - G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_TOKEN_SECRET, - pspec); - - pspec = g_param_spec_string ("signature-host", "signature-host", - "The base URL used in the signature string", - NULL, G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_SIGNATURE_HOST, - pspec); - - pspec = g_param_spec_enum ("signature-method", "signature-method", - "Signature method used", - OAUTH_TYPE_SIGNATURE_METHOD, HMAC_SHA1, - G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_SIGNATURE_METHOD, - pspec); -} - -static void -oauth_proxy_init (OAuthProxy *self) -{ - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (self); - priv->method = HMAC_SHA1; -} - -/** - * oauth_proxy_new: - * @consumer_key: the Consumer Key - * @consumer_secret: the Consumer Secret - * @url_format: the endpoint URL - * @binding_required: whether the URL needs to be bound before calling - * - * Create a new #OAuthProxy for the specified endpoint @url_format, using the - * specified API key and secret. - * - * This proxy won't have the Token or Token Secret set so as such will be - * unauthorised. If the tokens are unknown then oauth_proxy_request_token() and - * oauth_proxy_access_token() should be called to do the OAuth authorisation, or - * the tokens should be set using oauth_proxy_set_token() and - * oauth_proxy_set_token_secret(). - * - * Set @binding_required to %TRUE if the URL contains string formatting - * operations (for example "http://foo.com/%<!-- -->s". These must be expanded - * using rest_proxy_bind() before invoking the proxy. - * - * Returns: A new #OAuthProxy. - */ -RestProxy * -oauth_proxy_new (const char *consumer_key, - const char *consumer_secret, - const gchar *url_format, - gboolean binding_required) -{ - return g_object_new (OAUTH_TYPE_PROXY, - "consumer-key", consumer_key, - "consumer-secret", consumer_secret, - "url-format", url_format, - "binding-required", binding_required, - NULL); -} - -/** - * oauth_proxy_new_with_token: - * @consumer_key: the Consumer Key - * @consumer_secret: the Consumer Secret - * @token: the Access Token - * @token_secret: the Token Secret - * @url_format: the endpoint URL - * @binding_required: whether the URL needs to be bound before calling - * - * Create a new #OAuthProxy for the specified endpoint @url_format, using the - * specified API key and secret. - * - * @token and @token_secret are used for the Access Token and Token Secret, so - * if they are still valid then this proxy is authorised. - * - * Set @binding_required to %TRUE if the URL contains string formatting - * operations (for example "http://foo.com/%<!-- -->s". These must be expanded - * using rest_proxy_bind() before invoking the proxy. - * - * Returns: A new #OAuthProxy. - */ -RestProxy * -oauth_proxy_new_with_token (const char *consumer_key, - const char *consumer_secret, - const char *token, - const char *token_secret, - const gchar *url_format, - gboolean binding_required) -{ - return g_object_new (OAUTH_TYPE_PROXY, - "consumer-key", consumer_key, - "consumer-secret", consumer_secret, - "token", token, - "token-secret", token_secret, - "url-format", url_format, - "binding-required", binding_required, - NULL); -} - -/** - * oauth_proxy_request_token: - * @proxy: an #OAuthProxy - * @function: the function name to invoke - * @callback_uri: the callback URI - * @error: a #GError, or %NULL - * - * Perform the Request Token phase of OAuth, invoking @function (defaulting to - * "request_token" if @function is NULL). - * - * The value of @callback depends on whether you wish to use OAuth 1.0 or 1.0a. - * If you wish to use 1.0 then callback must be NULL. To use 1.0a then - * @callback should either be your callback URI, or "oob" (out-of-band). - * - * Returns: %TRUE on success, or %FALSE on failure. On failure @error is set. - */ -gboolean -oauth_proxy_request_token (OAuthProxy *proxy, - const char *function, - /* NULL: 1.0 only, "oob", or URL */ - const char *callback_uri, - GError **error) -{ - RestProxyCall *call; - - call = rest_proxy_new_call (REST_PROXY (proxy)); - rest_proxy_call_set_function (call, function ? function : "request_token"); - rest_proxy_call_set_method (call, "POST"); - - if (callback_uri) - rest_proxy_call_add_param (call, "oauth_callback", callback_uri); - - if (!rest_proxy_call_sync (call, error)) - { - g_object_unref (call); - return FALSE; - } - - /* TODO: sanity check response */ - oauth_proxy_call_parse_token_response (OAUTH_PROXY_CALL (call)); - - g_object_unref (call); - - return TRUE; -} - -static void -request_token_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - GTask *task = G_TASK (user_data); - RestProxyCall *call = REST_PROXY_CALL (source_object); - GError *error = NULL; - gboolean call_status; - - call_status = rest_proxy_call_invoke_finish (call, result, &error); - - if (error != NULL) { - g_task_return_error (task, error); - } else { - oauth_proxy_call_parse_token_response (OAUTH_PROXY_CALL (call)); - g_task_return_boolean (task, call_status); - } - - g_object_unref (task); -} - -/** - * oauth_proxy_request_token_async: - * @proxy: an #OAuthProxy - * @function: (nullable): the function name to invoke - * @callback_uri: (nullable): the callback URI - * @callback: (scope async): a #OAuthProxyAuthCallback to invoke on completion - * @user_data: user data to pass to @callback - * - * Perform the Request Token phase of OAuth, invoking @function (defaulting to - * "request_token" if @function is NULL). - * - * The value of @callback depends on whether you wish to use OAuth 1.0 or 1.0a. - * If you wish to use 1.0 then callback must be NULL. To use 1.0a then - * @callback should either be your callback URI, or "oob" (out-of-band). - * - * This method will return once the method has been queued, @callback will be - * invoked when it has completed. - */ -void -oauth_proxy_request_token_async (OAuthProxy *proxy, - const char *function, - const char *callback_uri, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - RestProxyCall *call; - GTask *task; - - call = rest_proxy_new_call (REST_PROXY (proxy)); - rest_proxy_call_set_function (call, function ? function : "request_token"); - rest_proxy_call_set_method (call, "POST"); - - if (callback_uri) - rest_proxy_call_add_param (call, "oauth_callback", callback_uri); - - task = g_task_new (proxy, cancellable, callback, user_data); - - rest_proxy_call_invoke_async (call, cancellable, request_token_cb, task); - - g_object_unref (call); -} - -/** - * oauth_proxy_request_token_finish: - * @proxy: a #OAuthProxy - * @result: a #GAsyncResult - * @error: a #GError or %NULL - * - * Finishes an operation started with oauth_proxy_request_token_async() - * - * Returns: %TRUE on success, %FALSE if an error occurred, in which case - * @error will be set. - */ -gboolean -oauth_proxy_request_token_finish (OAuthProxy *proxy, - GAsyncResult *result, - GError **error) -{ - g_return_val_if_fail (OAUTH_IS_PROXY (proxy), FALSE); - g_return_val_if_fail (g_task_is_valid (result, proxy), FALSE); - - return g_task_propagate_boolean (G_TASK (result), error); -} - -/** - * oauth_proxy_access_token: - * @proxy: an #OAuthProxy - * @function: the function name to invoke - * @verifier: the verifier - * @error: a #GError, or %NULL - * - * Perform the Access Token phase of OAuth, invoking @function (defaulting to - * "access_token" if @function is NULL). - * - * @verifier is only used if you are using OAuth 1.0a. This is either the - * "oauth_verifier" parameter that was passed to your callback URI, or a string - * that the user enters in some other manner (for example in a popup dialog) if - * "oob" was passed to oauth_proxy_request_token(). For OAuth 1.0, pass %NULL. - * - * Returns: %TRUE on success, or %FALSE on failure. On failure @error is set. - */ -gboolean -oauth_proxy_access_token (OAuthProxy *proxy, - const char *function, - const char *verifier, - GError **error) -{ - RestProxyCall *call; - - call = rest_proxy_new_call (REST_PROXY (proxy)); - rest_proxy_call_set_function (call, function ? function : "access_token"); - rest_proxy_call_set_method (call, "POST"); - - if (verifier) - rest_proxy_call_add_param (call, "oauth_verifier", verifier); - - if (!rest_proxy_call_sync (call, error)) - { - g_object_unref (call); - return FALSE; - } - - /* TODO: sanity check response */ - oauth_proxy_call_parse_token_response (OAUTH_PROXY_CALL (call)); - - g_object_unref (call); - - return TRUE; -} - -static void -access_token_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - GTask *task = G_TASK (user_data); - RestProxyCall *call = REST_PROXY_CALL (source_object); - GError *error = NULL; - gboolean call_status; - - call_status = rest_proxy_call_invoke_finish (call, result, &error); - - if (error != NULL) { - g_task_return_error (task, error); - } else { - oauth_proxy_call_parse_token_response (OAUTH_PROXY_CALL (call)); - g_task_return_boolean (task, call_status); - } - - g_object_unref (task); -} - -/** - * oauth_proxy_access_token_async: - * @proxy: an #OAuthProxy - * @function: the function name to invoke - * @verifier: the verifier - * @callback: (scope async): a #OAuthProxyAuthCallback to invoke on completion - * @user_data: user data to pass to @callback - * - * Perform the Access Token phase of OAuth, invoking @function (defaulting to - * "access_token" if @function is NULL). - * - * @verifier is only used if you are using OAuth 1.0a. This is either the - * "oauth_verifier" parameter that was passed to your callback URI, or a string - * that the user enters in some other manner (for example in a popup dialog) if - * "oob" was passed to oauth_proxy_request_token(). For OAuth 1.0, pass %NULL. - * - * This method will return once the method has been queued, @callback will be - * invoked when it has completed. - */ -void -oauth_proxy_access_token_async (OAuthProxy *proxy, - const char *function, - const char *verifier, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - RestProxyCall *call; - GTask *task; - - call = rest_proxy_new_call (REST_PROXY (proxy)); - rest_proxy_call_set_function (call, function ? function : "access_token"); - rest_proxy_call_set_method (call, "POST"); - - if (verifier) - rest_proxy_call_add_param (call, "oauth_verifier", verifier); - - task = g_task_new (proxy, cancellable, callback, user_data); - - rest_proxy_call_invoke_async (call, cancellable, access_token_cb, task); - g_object_unref (call); -} - -gboolean -oauth_proxy_access_token_finish (OAuthProxy *proxy, - GAsyncResult *result, - GError **error) -{ - g_return_val_if_fail (OAUTH_IS_PROXY (proxy), FALSE); - g_return_val_if_fail (g_task_is_valid (result, proxy), FALSE); - - return g_task_propagate_boolean (G_TASK (result), error); -} - -const char * -oauth_proxy_get_consumer_key (OAuthProxy *self) -{ - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (self); - - return priv->consumer_key; -} - -const char * -oauth_proxy_get_consumer_secret (OAuthProxy *self) -{ - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (self); - - return priv->consumer_secret; -} - -/** - * oauth_proxy_get_token: - * @proxy: an #OAuthProxy - * - * Get the current request or access token. - * - * Returns: the token, or %NULL if there is no token yet. This string is owned - * by #OAuthProxy and should not be freed. - */ -const char * -oauth_proxy_get_token (OAuthProxy *proxy) -{ - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (proxy); - - return priv->token; -} - -/** - * oauth_proxy_set_token: - * @proxy: an #OAuthProxy - * @token: the access token - * - * Set the access token. - */ -void -oauth_proxy_set_token (OAuthProxy *proxy, const char *token) -{ - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (proxy); - - g_return_if_fail (OAUTH_IS_PROXY (proxy)); - - g_free (priv->token); - priv->token = g_strdup (token); -} - -/** - * oauth_proxy_get_token_secret: - * @proxy: an #OAuthProxy - * - * Get the current request or access token secret. - * - * Returns: the token secret, or %NULL if there is no token secret yet. This - * string is owned by #OAuthProxy and should not be freed. - */ -const char * -oauth_proxy_get_token_secret (OAuthProxy *proxy) -{ - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (proxy); - - return priv->token_secret; -} - -/** - * oauth_proxy_set_token_secret: - * @proxy: an #OAuthProxy - * @token_secret: the access token secret - * - * Set the access token secret. - */ -void -oauth_proxy_set_token_secret (OAuthProxy *proxy, const char *token_secret) -{ - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (proxy); - - g_return_if_fail (OAUTH_IS_PROXY (proxy)); - - if (priv->token_secret) - g_free (priv->token_secret); - - priv->token_secret = g_strdup (token_secret); -} - -/** - * oauth_proxy_is_oauth10a: - * @proxy: a valid #OAuthProxy - * - * Determines if the server supports OAuth 1.0a with this proxy. This is only - * valid after oauth_proxy_request_token() or oauth_proxy_request_token_async() - * has been called. - * - * Returns: %TRUE if the server supports OAuth 1.0a, %FALSE otherwise. - */ -gboolean -oauth_proxy_is_oauth10a (OAuthProxy *proxy) -{ - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (proxy); - - g_return_val_if_fail (OAUTH_IS_PROXY (proxy), FALSE); - - return priv->oauth_10a; -} - -void -oauth_proxy_set_oauth10a (OAuthProxy *self, - gboolean oauth10a) -{ - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (self); - - g_return_if_fail (OAUTH_IS_PROXY (self)); - - priv->oauth_10a = oauth10a; -} - -/** - * oauth_proxy_get_signature_host: - * @proxy: an #OAuthProxy - * - * Get the signature hostname used when creating a signature base string. - * - * Returns: the signature hostname, or %NULL if there is none set. - * This string is owned by #OAuthProxy and should not be freed. - */ -const char * -oauth_proxy_get_signature_host (OAuthProxy *proxy) -{ - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (proxy); - - g_return_val_if_fail (OAUTH_IS_PROXY (proxy), NULL); - - return priv->signature_host; -} - -/** - * oauth_proxy_set_signature_host: - * @proxy: an #OAuthProxy - * @signature_host: the signature host - * - * Set the signature hostname used when creating a signature base string. - */ -void -oauth_proxy_set_signature_host (OAuthProxy *proxy, - const char *signature_host) -{ - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (proxy); - - g_return_if_fail (OAUTH_IS_PROXY (proxy)); - - g_free (priv->signature_host); - - priv->signature_host = g_strdup (signature_host); -} - -/** - * oauth_proxy_new_echo_proxy: - * @proxy: an #OAuthProxy - * @service_url: the service URL - * @url_format: the URL format - * @binding_required: whether a binding is required - * - * Create a new <ulink - * url="http://www.scribd.com/doc/26707268/OAuth-Echo-Identity-Veri%EF%AC%81cation-Delegation-Draft">OAuth - * Echo</ulink> proxy. - * - * Returns: (transfer full): a new OAuth Echo proxy - */ -RestProxy * -oauth_proxy_new_echo_proxy (OAuthProxy *proxy, - /* TODO: should this be a function on the base url? */ - const char *service_url, - const gchar *url_format, - gboolean binding_required) -{ - OAuthProxy *echo_proxy; - OAuthProxyPrivate *echo_priv; - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (proxy); - - g_return_val_if_fail (OAUTH_IS_PROXY (proxy), NULL); - g_return_val_if_fail (service_url, NULL); - g_return_val_if_fail (url_format, NULL); - - echo_proxy = g_object_new (OAUTH_TYPE_PROXY, - "url-format", url_format, - "binding-required", binding_required, - "user-agent", rest_proxy_get_user_agent ((RestProxy *)proxy), - "consumer-key", priv->consumer_key, - "consumer-secret", priv->consumer_secret, - "token", priv->token, - "token-secret", priv->token_secret, - NULL); - echo_priv = oauth_proxy_get_instance_private (echo_proxy); - - echo_priv->oauth_echo = TRUE; - echo_priv->service_url = g_strdup (service_url); - - return (RestProxy *)echo_proxy; -} - -GType -oauth_signature_method_get_type (void) -{ - static GType enum_type_id = 0; - if (G_UNLIKELY (!enum_type_id)) - { - static const GEnumValue values[] = - { - { PLAINTEXT, "PLAINTEXT", "plaintext" }, - { HMAC_SHA1, "HMAC_SHA1", "hmac-sha1" }, - { 0, NULL, NULL } - }; - enum_type_id = g_enum_register_static ("OAuthSignatureMethod", values); - } - return enum_type_id; -} - -gboolean -oauth_proxy_is_echo (OAuthProxy *self) -{ - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (self); - - return priv->oauth_echo; -} - -const char * -oauth_proxy_get_service_url (OAuthProxy *self) -{ - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (self); - - return priv->service_url; -} - -OAuthSignatureMethod -oauth_proxy_get_sign_method (OAuthProxy *self) -{ - OAuthProxyPrivate *priv = oauth_proxy_get_instance_private (self); - - return priv->method; -} diff --git a/rest/oauth-proxy.h b/rest/oauth-proxy.h deleted file mode 100644 index 2616a34..0000000 --- a/rest/oauth-proxy.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * librest - RESTful web services access - * Copyright (c) 2008, 2009, Intel Corporation. - * - * Authors: Rob Bradford <rob@linux.intel.com> - * Ross Burton <ross@linux.intel.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef _OAUTH_PROXY -#define _OAUTH_PROXY - -#include <rest/rest-proxy.h> - -G_BEGIN_DECLS - -#define OAUTH_TYPE_PROXY oauth_proxy_get_type() -G_DECLARE_FINAL_TYPE (OAuthProxy, oauth_proxy, OAUTH, PROXY, RestProxy) - -GType oauth_signature_method_get_type (void) G_GNUC_CONST; -#define OAUTH_TYPE_SIGNATURE_METHOD (oauth_signature_method_get_type()) - -/** - * OAuthSignatureMethod: - * @PLAINTEXT: plain text signatures (not recommended) - * @HMAC_SHA1: HMAC-SHA1 signatures (recommended) - * - * The signature method to use when signing method calls. @PLAINTEXT is only - * recommended for testing, in general @HMAC_SHA1 is well supported and more - * secure. - */ -typedef enum { - PLAINTEXT, - HMAC_SHA1 -} OAuthSignatureMethod; - -RestProxy *oauth_proxy_new (const char *consumer_key, - const char *consumer_secret, - const gchar *url_format, - gboolean binding_required); -RestProxy *oauth_proxy_new_with_token (const char *consumer_key, - const char *consumer_secret, - const char *token, - const char *token_secret, - const gchar *url_format, - gboolean binding_required); -gboolean oauth_proxy_request_token (OAuthProxy *proxy, - const char *function, - const char *callback_uri, - GError **error); -void oauth_proxy_request_token_async (OAuthProxy *proxy, - const char *function, - const char *callback_uri, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean oauth_proxy_request_token_finish (OAuthProxy *proxy, - GAsyncResult *result, - GError **error); -gboolean oauth_proxy_is_oauth10a (OAuthProxy *proxy); -void oauth_proxy_set_oauth10a (OAuthProxy *proxy, - gboolean oauth10a); -gboolean oauth_proxy_access_token (OAuthProxy *proxy, - const char *function, - const char *verifier, - GError **error); -void oauth_proxy_access_token_async (OAuthProxy *proxy, - const char *function, - const char *verifier, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean oauth_proxy_access_token_finish (OAuthProxy *proxy, - GAsyncResult *result, - GError **error); -const char *oauth_proxy_get_consumer_key (OAuthProxy *proxy); -const char *oauth_proxy_get_consumer_secret (OAuthProxy *proxy); -const char *oauth_proxy_get_token (OAuthProxy *proxy); -void oauth_proxy_set_token (OAuthProxy *proxy, - const char *token); -const char *oauth_proxy_get_token_secret (OAuthProxy *proxy); -void oauth_proxy_set_token_secret (OAuthProxy *proxy, - const char *token_secret); -const char *oauth_proxy_get_signature_host (OAuthProxy *proxy); -void oauth_proxy_set_signature_host (OAuthProxy *proxy, - const char *signature_host); -RestProxy *oauth_proxy_new_echo_proxy (OAuthProxy *proxy, - const char *service_url, - const gchar *url_format, - gboolean binding_required); -gboolean oauth_proxy_is_echo (OAuthProxy *proxy); -const char *oauth_proxy_get_service_url (OAuthProxy *proxy); -OAuthSignatureMethod oauth_proxy_get_sign_method (OAuthProxy *proxy); - -G_END_DECLS - -#endif /* _OAUTH_PROXY */ diff --git a/rest/rest.h b/rest/rest.h index 2db9eb7..0c4afbb 100644 --- a/rest/rest.h +++ b/rest/rest.h @@ -27,8 +27,6 @@ G_BEGIN_DECLS #define REST_INSIDE # include "rest-proxy.h" # include "rest-proxy-call.h" -# include "oauth-proxy.h" -# include "oauth-proxy-call.h" # include "rest-oauth2-proxy.h" # include "rest-utils.h" # include "rest-pkce-code-challenge.h" diff --git a/rest/test-runner.c b/rest/test-runner.c deleted file mode 100644 index 990718e..0000000 --- a/rest/test-runner.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * librest - RESTful web services access - * Copyright (C) 2009 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <config.h> -#include <glib-object.h> - -#define test_add(unit_name, func) G_STMT_START { \ - extern void func (void); \ - g_test_add_func (unit_name, func); } G_STMT_END - -int -main (int argc, char *argv[]) -{ - g_test_init (&argc, &argv, NULL); - - test_add ("/oauth/param-encoding", test_param_encoding); - - return g_test_run (); -} |