[gnome-software/wip/temp/ubuntu-xenial-rebased: 255/329] Authenticate if needed



commit be733ea4dd1984b92e1f30b8b0bb72b8d4a045ba
Author: William Hua <william hua canonical com>
Date:   Sun Apr 17 15:15:46 2016 -0400

    Authenticate if needed

 src/plugins/gs-plugin-snappy.c    |   10 ++++----
 src/plugins/gs-ubuntu-snapd.c     |   46 ++++++++++++++++++++++++++++++++++++-
 src/plugins/gs-ubuntu-snapd.h     |    2 +
 src/plugins/gs-ubuntuone-dialog.c |    2 +
 4 files changed, 54 insertions(+), 6 deletions(-)
---
diff --git a/src/plugins/gs-plugin-snappy.c b/src/plugins/gs-plugin-snappy.c
index 28d9393..282f9d2 100644
--- a/src/plugins/gs-plugin-snappy.c
+++ b/src/plugins/gs-plugin-snappy.c
@@ -124,7 +124,7 @@ refine_app (GsPlugin *plugin, GsApp *app, JsonObject *package)
                gsize icon_response_length;
 
                icon_socket = open_snapd_socket (NULL);
-               if (icon_socket && send_snapd_request (icon_socket, "GET", icon_url, NULL, NULL, NULL, NULL, 
&icon_response, &icon_response_length, NULL)) {
+               if (icon_socket && send_snapd_request (icon_socket, TRUE, TRUE, "GET", icon_url, NULL, NULL, 
NULL, NULL, &icon_response, &icon_response_length, NULL)) {
                        g_autoptr(GdkPixbufLoader) loader = NULL;
 
                        loader = gdk_pixbuf_loader_new ();
@@ -195,7 +195,7 @@ get_apps (GsPlugin *plugin, const gchar *sources, gchar **search_terms, GList **
                g_string_append (path, fields);
        }
        g_ptr_array_free (query_fields, TRUE);
-       if (!send_snapd_request (socket, "GET", path->str, NULL, &status_code, &reason_phrase, 
&response_type, &response, NULL, error))
+       if (!send_snapd_request (socket, TRUE, TRUE, "GET", path->str, NULL, &status_code, &reason_phrase, 
&response_type, &response, NULL, error))
                return FALSE;
 
        if (status_code != SOUP_STATUS_OK) {
@@ -289,7 +289,7 @@ get_app (GsPlugin *plugin, GsApp *app, GError **error)
                return FALSE;
 
        path = g_strdup_printf ("/v2/snaps/%s", gs_app_get_id (app));
-       if (!send_snapd_request (socket, "GET", path, NULL, &status_code, &reason_phrase, &response_type, 
&response, NULL, error))
+       if (!send_snapd_request (socket, TRUE, TRUE, "GET", path, NULL, &status_code, &reason_phrase, 
&response_type, &response, NULL, error))
                return FALSE;
 
        if (status_code != SOUP_STATUS_OK) {
@@ -389,7 +389,7 @@ send_package_action (GsPlugin *plugin, const char *id, const gchar *action, GErr
 
        content = g_strdup_printf ("{\"action\": \"%s\"}", action);
        path = g_strdup_printf ("/v2/snaps/%s", id);
-       if (!send_snapd_request (socket, "POST", path, content, &status_code, &reason_phrase, &response_type, 
&response, NULL, error))
+       if (!send_snapd_request (socket, TRUE, TRUE, "POST", path, content, &status_code, &reason_phrase, 
&response_type, &response, NULL, error))
                return FALSE;
 
        if (status_code != SOUP_STATUS_ACCEPTED) {
@@ -414,7 +414,7 @@ send_package_action (GsPlugin *plugin, const char *id, const gchar *action, GErr
                /* Wait for a little bit before polling */
                g_usleep (100 * 1000);
 
-               if (!send_snapd_request (socket, "GET", resource_path, NULL, &status_code, 
&status_reason_phrase, &status_response_type, &status_response, NULL, error))
+               if (!send_snapd_request (socket, TRUE, TRUE, "GET", resource_path, NULL, &status_code, 
&status_reason_phrase, &status_response_type, &status_response, NULL, error))
                        return FALSE;
                if (status_code != SOUP_STATUS_OK) {
                        g_set_error (error,
diff --git a/src/plugins/gs-ubuntu-snapd.c b/src/plugins/gs-ubuntu-snapd.c
index d8dfef5..e90d865 100644
--- a/src/plugins/gs-ubuntu-snapd.c
+++ b/src/plugins/gs-ubuntu-snapd.c
@@ -25,6 +25,7 @@
 #include <libsoup/soup.h>
 #include <gio/gunixsocketaddress.h>
 #include "gs-ubuntu-snapd.h"
+#include "gs-ubuntuone.h"
 
 #define SNAPD_SOCKET_PATH "/run/snapd.socket"
 
@@ -73,6 +74,8 @@ read_from_snapd (GSocket *socket, gchar *buffer, gsize buffer_length, gsize *rea
 
 gboolean
 send_snapd_request (GSocket      *socket,
+                   gboolean      authenticate,
+                   gboolean      retry_after_login,
                    const gchar  *method,
                    const gchar  *path,
                    const gchar  *content,
@@ -90,6 +93,14 @@ send_snapd_request (GSocket      *socket,
        g_autoptr (SoupMessageHeaders) headers = NULL;
        gsize chunk_length, n_required;
        gchar *chunk_start = NULL;
+       g_autoptr (GVariant) macaroon = NULL;
+       const gchar *root;
+       const gchar *discharge;
+       GVariantIter *iter;
+       guint code;
+
+       if (authenticate)
+               macaroon = gs_ubuntuone_get_macaroon (TRUE, FALSE, NULL);
 
        // NOTE: Would love to use libsoup but it doesn't support unix sockets
        // https://bugzilla.gnome.org/show_bug.cgi?id=727563
@@ -97,6 +108,16 @@ send_snapd_request (GSocket      *socket,
        request = g_string_new ("");
        g_string_append_printf (request, "%s %s HTTP/1.1\r\n", method, path);
        g_string_append (request, "Host:\r\n");
+       if (macaroon != NULL) {
+               g_variant_get (macaroon, "(&sas)", &root, &iter);
+               g_string_append_printf (request, "Authorization: Macaroon root=\"%s\"", root);
+
+               while (g_variant_iter_next (iter, "&s", &discharge))
+                       g_string_append_printf (request, ",discharge=\"%s\"", discharge);
+
+               g_variant_iter_free (iter);
+               g_string_append (request, "\r\n");
+       }
        if (content)
                g_string_append_printf (request, "Content-Length: %zi\r\n", strlen (content));
        g_string_append (request, "\r\n");
@@ -128,7 +149,7 @@ send_snapd_request (GSocket      *socket,
 
        /* Parse headers */
        headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE);
-       if (!soup_headers_parse_response (data, header_length, headers, NULL, status_code, reason_phrase)) {
+       if (!soup_headers_parse_response (data, header_length, headers, NULL, &code, reason_phrase)) {
                g_set_error_literal (error,
                                     GS_PLUGIN_ERROR,
                                     GS_PLUGIN_ERROR_FAILED,
@@ -136,6 +157,29 @@ send_snapd_request (GSocket      *socket,
                return FALSE;
        }
 
+       if (status_code != NULL)
+               *status_code = code;
+
+       if (code == 403 && retry_after_login) {
+               macaroon = gs_ubuntuone_get_macaroon (FALSE, TRUE, NULL);
+
+               if (macaroon == NULL)
+                       return FALSE;
+
+               return send_snapd_request (socket,
+                                          TRUE,
+                                          FALSE,
+                                          method,
+                                          path,
+                                          content,
+                                          status_code,
+                                          reason_phrase,
+                                          response_type,
+                                          response,
+                                          response_length,
+                                          error);
+       }
+
        /* Work out how much data to follow */
        if (g_strcmp0 (soup_message_headers_get_one (headers, "Transfer-Encoding"), "chunked") == 0) {
                while (data_length < max_data_length) {
diff --git a/src/plugins/gs-ubuntu-snapd.h b/src/plugins/gs-ubuntu-snapd.h
index d2211b7..bfb4992 100644
--- a/src/plugins/gs-ubuntu-snapd.h
+++ b/src/plugins/gs-ubuntu-snapd.h
@@ -27,6 +27,8 @@
 GSocket * open_snapd_socket  (GError      **error);
 
 gboolean  send_snapd_request (GSocket      *socket,
+                             gboolean      authenticate,
+                             gboolean      retry_after_login,
                              const gchar  *method,
                              const gchar  *path,
                              const gchar  *content,
diff --git a/src/plugins/gs-ubuntuone-dialog.c b/src/plugins/gs-ubuntuone-dialog.c
index fcc3312..2eceb56 100644
--- a/src/plugins/gs-ubuntuone-dialog.c
+++ b/src/plugins/gs-ubuntuone-dialog.c
@@ -421,6 +421,8 @@ send_login_request (GsUbuntuoneDialog *self)
                }
 
                if (send_snapd_request (socket,
+                                       FALSE,
+                                       FALSE,
                                        SOUP_METHOD_POST,
                                        "/v2/login",
                                        content,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]