[gnome-software/wip/attente/ubuntu-xenial: 1/7] Add snapd support to login dialog



commit 37c9aead9c57cb12ffe1dcb5c9aebbd357f7e714
Author: William Hua <william hua canonical com>
Date:   Sun Apr 17 14:46:39 2016 -0400

    Add snapd support to login dialog

 src/plugins/gs-ubuntuone-dialog.c |  186 +++++++++++++++++++++++++++++++++----
 1 files changed, 167 insertions(+), 19 deletions(-)
---
diff --git a/src/plugins/gs-ubuntuone-dialog.c b/src/plugins/gs-ubuntuone-dialog.c
index 4f1a28d..fcc3312 100644
--- a/src/plugins/gs-ubuntuone-dialog.c
+++ b/src/plugins/gs-ubuntuone-dialog.c
@@ -26,6 +26,8 @@
 #include <json-glib/json-glib.h>
 #include <libsoup/soup.h>
 
+#include "gs-ubuntu-snapd.h"
+
 #define UBUNTU_LOGIN_HOST "https://login.ubuntu.com";
 
 struct _GsUbuntuoneDialog
@@ -288,9 +290,87 @@ receive_login_response_cb (GsUbuntuoneDialog *self,
 }
 
 static void
+check_snapd_response (GsUbuntuoneDialog *self,
+                     guint              status_code,
+                     gchar             *reason_phrase,
+                     gchar             *response_type,
+                     gchar             *response,
+                     gsize              response_length)
+{
+       g_autoptr(GVariant) variant = NULL;
+       g_autoptr(GVariant) result = NULL;
+       g_autoptr(GVariant) discharges = NULL;
+       const gchar *type;
+       const gchar *kind;
+       const gchar *macaroon;
+       GVariantBuilder builder;
+       GVariantIter iter;
+       GVariant *discharge = NULL;
+
+       variant = json_gvariant_deserialize_data (response, -1, NULL, NULL);
+
+       if (variant == NULL)
+               goto err;
+
+       g_variant_ref_sink (variant);
+
+       if (!g_variant_lookup (variant, "type", "&s", &type))
+               goto err;
+
+       result = g_variant_lookup_value (variant, "result", G_VARIANT_TYPE_DICTIONARY);
+
+       if (result == NULL)
+               goto err;
+
+       if (g_str_equal (type, "sync")) {
+               if (!g_variant_lookup (result, "macaroon", "&s", &macaroon))
+                       goto err;
+
+               discharges = g_variant_lookup_value (result, "discharges", G_VARIANT_TYPE ("av"));
+
+               if (discharges == NULL)
+                       goto err;
+
+               g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
+               g_variant_iter_init (&iter, discharges);
+
+               while (g_variant_iter_loop (&iter, "v", &discharge))
+                       g_variant_builder_add (&builder, "s", g_variant_get_string (discharge, NULL));
+
+               self->macaroon = g_variant_ref_sink (g_variant_new ("(s as)", macaroon, g_variant_builder_end 
(&builder)));
+
+               gtk_stack_set_visible_child_name (GTK_STACK (self->page_stack), "page-2");
+               update_widgets (self);
+       } else if (g_variant_lookup (result, "kind", "&s", &kind)) {
+               if (g_str_equal (kind, "two-factor-required")) {
+                       gtk_stack_set_visible_child_name (GTK_STACK (self->page_stack), "page-1");
+                       gtk_widget_grab_focus (self->passcode_entry);
+                       update_widgets (self);
+               } else
+                       goto err;
+       } else
+               goto err;
+
+err:
+       show_status (self, _("An error occurred"), TRUE);
+       gtk_widget_grab_focus (self->password_entry);
+}
+
+static void
 send_login_request (GsUbuntuoneDialog *self)
 {
+       g_autoptr(GSocket) socket = NULL;
+       g_autofree gchar *content = NULL;
+       g_autofree gchar *username = NULL;
+       g_autofree gchar *password = NULL;
+       g_autofree gchar *otp = NULL;
        GVariant *request;
+       guint status_code;
+       g_autofree gchar *reason_phrase = NULL;
+       g_autofree gchar *response_type = NULL;
+       g_autofree gchar *response = NULL;
+       gsize response_length;
+       g_autoptr(GError) error = NULL;
 
        gtk_widget_set_sensitive (self->cancel_button, FALSE);
        gtk_widget_set_sensitive (self->next_button, FALSE);
@@ -304,27 +384,95 @@ send_login_request (GsUbuntuoneDialog *self)
 
        show_status (self, _("Signing in…"), FALSE);
 
-       if (gtk_entry_get_text_length (GTK_ENTRY (self->passcode_entry)) > 0) {
-               request = g_variant_new_parsed ("{"
-                                               "  'token_name' : <'GNOME Software'>,"
-                                               "  'email' : <%s>,"
-                                               "  'password' : <%s>,"
-                                               "  'otp' : <%s>"
-                                               "}",
-                                               gtk_entry_get_text (GTK_ENTRY (self->email_entry)),
-                                               gtk_entry_get_text (GTK_ENTRY (self->password_entry)),
-                                               gtk_entry_get_text (GTK_ENTRY (self->passcode_entry)));
+       if (self->get_macaroon) {
+               socket = open_snapd_socket (&error);
+
+               if (socket == NULL) {
+                       g_warning ("could not open snapd socket: %s", error->message);
+
+                       reenable_widgets (self);
+                       show_status (self, _("An error occurred"), TRUE);
+                       gtk_widget_grab_focus (self->password_entry);
+
+                       return;
+               }
+
+               username = g_strescape (gtk_entry_get_text (GTK_ENTRY (self->email_entry)), NULL);
+               password = g_strescape (gtk_entry_get_text (GTK_ENTRY (self->password_entry)), NULL);
+
+               if (gtk_entry_get_text_length (GTK_ENTRY (self->passcode_entry)) > 0) {
+                       otp = g_strescape (gtk_entry_get_text (GTK_ENTRY (self->passcode_entry)), NULL);
+
+                       content = g_strdup_printf ("{"
+                                                  "  \"username\" : \"%s\","
+                                                  "  \"password\" : \"%s\","
+                                                  "  \"otp\" : \"%s\""
+                                                  "}",
+                                                  username,
+                                                  password,
+                                                  otp);
+               } else {
+                       content = g_strdup_printf ("{"
+                                                  "  \"username\" : \"%s\","
+                                                  "  \"password\" : \"%s\""
+                                                  "}",
+                                                  username,
+                                                  password);
+               }
+
+               if (send_snapd_request (socket,
+                                       SOUP_METHOD_POST,
+                                       "/v2/login",
+                                       content,
+                                       &status_code,
+                                       &reason_phrase,
+                                       &response_type,
+                                       &response,
+                                       &response_length,
+                                       &error)) {
+                       reenable_widgets (self);
+
+                       check_snapd_response (self,
+                                             status_code,
+                                             reason_phrase,
+                                             response_type,
+                                             response,
+                                             response_length);
+               } else {
+                       g_warning ("could not send request: %s", error->message);
+
+                       reenable_widgets (self);
+                       show_status (self, _("An error occurred"), TRUE);
+                       gtk_widget_grab_focus (self->password_entry);
+               }
        } else {
-               request = g_variant_new_parsed ("{"
-                                               "  'token_name' : <'GNOME Software'>,"
-                                               "  'email' : <%s>,"
-                                               "  'password' : <%s>"
-                                               "}",
-                                               gtk_entry_get_text (GTK_ENTRY (self->email_entry)),
-                                               gtk_entry_get_text (GTK_ENTRY (self->password_entry)));
-       }
+               if (gtk_entry_get_text_length (GTK_ENTRY (self->passcode_entry)) > 0) {
+                       request = g_variant_new_parsed ("{"
+                                                       "  'token_name' : <'GNOME Software'>,"
+                                                       "  'email' : <%s>,"
+                                                       "  'password' : <%s>,"
+                                                       "  'otp' : <%s>"
+                                                       "}",
+                                                       gtk_entry_get_text (GTK_ENTRY (self->email_entry)),
+                                                       gtk_entry_get_text (GTK_ENTRY (self->password_entry)),
+                                                       gtk_entry_get_text (GTK_ENTRY 
(self->passcode_entry)));
+               } else {
+                       request = g_variant_new_parsed ("{"
+                                                       "  'token_name' : <'GNOME Software'>,"
+                                                       "  'email' : <%s>,"
+                                                       "  'password' : <%s>"
+                                                       "}",
+                                                       gtk_entry_get_text (GTK_ENTRY (self->email_entry)),
+                                                       gtk_entry_get_text (GTK_ENTRY 
(self->password_entry)));
+               }
 
-       send_request (self, SOUP_METHOD_POST, "/api/v2/tokens/oauth", request, receive_login_response_cb, 
NULL);
+               send_request (self,
+                             SOUP_METHOD_POST,
+                             "/api/v2/tokens/oauth",
+                             request,
+                             receive_login_response_cb,
+                             NULL);
+       }
 }
 
 static void


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