[gnome-software/wip/ubuntu] Use snapd-glib to perform snapd login. This fixes non-root access being removed in snapd.



commit 1787eee4aea37763987c6da50a431dd3adf832ed
Author: Robert Ancell <robert ancell canonical com>
Date:   Thu Sep 1 16:49:19 2016 +1200

    Use snapd-glib to perform snapd login. This fixes non-root access being removed in snapd.

 configure.ac                      |   23 ++++++
 src/plugins/Makefile.am           |   13 +++-
 src/plugins/gs-snapd.c            |   51 --------------
 src/plugins/gs-snapd.h            |    7 --
 src/plugins/gs-ubuntuone-dialog.c |  136 ++++++++++--------------------------
 5 files changed, 71 insertions(+), 159 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index b538a7f..18bfcf3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -241,6 +241,28 @@ GS_PLUGIN_API_VERSION=9
 AC_SUBST(GS_PLUGIN_API_VERSION)
 AC_DEFINE_UNQUOTED([GS_PLUGIN_API_VERSION], "$GS_PLUGIN_API_VERSION", [the plugin API version])
 
+# Snap
+AC_ARG_ENABLE(snap,
+              [AS_HELP_STRING([--enable-snap],
+                              [enable Snap support [default=auto]])],,
+              enable_snap=maybe)
+AS_IF([test "x$enable_snap" != "xno"], [
+    PKG_CHECK_MODULES(SNAP,
+                      [snapd-glib],
+                      [have_snap=yes],
+                      [have_snap=no])
+], [
+    have_snap=no
+])
+AS_IF([test "x$have_snap" = "xyes"], [
+    AC_DEFINE(HAVE_SNAP,1,[Build Snap support])
+], [
+    AS_IF([test "x$enable_snap" = "xyes"], [
+          AC_MSG_ERROR([Snap support requested but 'snapd-glib' was not found])
+    ])
+])
+AM_CONDITIONAL(HAVE_SNAP, test "$have_snap" != no)
+
 GLIB_TESTS
 
 dnl ---------------------------------------------------------------------------
@@ -286,4 +308,5 @@ echo "
         Limba support:             ${have_limba}
         XDG-APP support:           ${have_xdg_app}
         ODRS support:              ${have_odrs}
+        Snap support:              ${have_snap}
 "
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 68b0e0d..88bf1ba 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -15,6 +15,7 @@ AM_CPPFLAGS =                                         \
        $(XDG_APP_CFLAGS)                               \
        $(OAUTH_CFLAGS)                                 \
        $(LIBSECRET_CFLAGS)                             \
+       $(SNAP_CFLAGS)                                  \
        -DBINDIR=\"$(bindir)\"                          \
        -DDATADIR=\"$(datadir)\"                        \
        -DGS_MODULESETDIR=\"$(datadir)/gnome-software/modulesets.d\" \
@@ -44,14 +45,17 @@ plugin_LTLIBRARIES =                                        \
        libgs_plugin_ubuntu-reviews.la                  \
        libgs_plugin_fedora_tagger_usage.la             \
        libgs_plugin_epiphany.la                        \
-       libgs_plugin_icons.la                           \
-       libgs_plugin_snap.la
+       libgs_plugin_icons.la
 
 if HAVE_APT
 plugin_LTLIBRARIES +=                                  \
        libgs_plugin_apt.la
 endif
 
+if HAVE_SNAP
+plugin_LTLIBRARIES += libgs_plugin_snap.la
+endif
+
 if HAVE_PACKAGEKIT
 plugin_LTLIBRARIES +=                                  \
        libgs_plugin_systemd-updates.la                 \
@@ -280,6 +284,7 @@ libgs_plugin_packagekit_proxy_la_LIBADD = $(GS_PLUGIN_LIBS)
 libgs_plugin_packagekit_proxy_la_LDFLAGS = -module -avoid-version
 libgs_plugin_packagekit_proxy_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
 
+if HAVE_SNAP
 libgs_plugin_snap_la_SOURCES =                         \
        gs-plugin-snap.c                                \
        gs-ubuntuone.h                                  \
@@ -290,11 +295,13 @@ libgs_plugin_snap_la_SOURCES =                            \
        gs-snapd.c
 libgs_plugin_snap_la_LIBADD =                          \
        $(GS_PLUGIN_LIBS)                               \
+       $(SNAP_LIBS)                                    \
        $(SOUP_LIBS)                                    \
        $(JSON_GLIB_LIBS)                               \
        $(LIBSECRET_LIBS)
 libgs_plugin_snap_la_LDFLAGS = -module -avoid-version
-libgs_plugin_snap_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+libgs_plugin_snap_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS) -DUSE_SNAPD
+endif
 
 check_PROGRAMS =                                       \
        gs-self-test
diff --git a/src/plugins/gs-snapd.c b/src/plugins/gs-snapd.c
index c4e902a..cdef7e5 100644
--- a/src/plugins/gs-snapd.c
+++ b/src/plugins/gs-snapd.c
@@ -345,57 +345,6 @@ parse_result (const gchar *response, const gchar *response_type, GError **error)
        return g_object_ref (parser);
 }
 
-gchar *
-gs_snapd_login (const gchar *username, const gchar *password, const gchar *otp,
-               guint *status_code,
-               GCancellable *cancellable, GError **error)
-{
-       g_autofree gchar *escaped_username = NULL;
-       g_autofree gchar *escaped_password = NULL;
-       g_autofree gchar *escaped_otp = NULL;
-       g_autofree gchar *content = NULL;
-       g_autofree gchar *response = NULL;
-
-       escaped_username = g_strescape (username, NULL);
-       escaped_password = g_strescape (password, NULL);
-
-       if (otp != NULL) {
-               escaped_otp = g_strescape (otp, NULL);
-
-               content = g_strdup_printf ("{"
-                                          "  \"username\" : \"%s\","
-                                          "  \"password\" : \"%s\","
-                                          "  \"otp\" : \"%s\""
-                                          "}",
-                                          escaped_username,
-                                          escaped_password,
-                                          escaped_otp);
-       } else {
-               content = g_strdup_printf ("{"
-                                          "  \"username\" : \"%s\","
-                                          "  \"password\" : \"%s\""
-                                          "}",
-                                          escaped_username,
-                                          escaped_password);
-       }
-
-       if (!send_request ("POST",
-                          "/v2/login",
-                          content,
-                          FALSE, NULL, NULL,
-                          FALSE, NULL, NULL,
-                          status_code,
-                          NULL,
-                          NULL,
-                          &response,
-                          NULL,
-                          NULL,
-                          error))
-               return NULL;
-
-       return g_steal_pointer (&response);
-}
-
 JsonObject *
 gs_snapd_list_one (const gchar *name,
                   GCancellable *cancellable, GError **error)
diff --git a/src/plugins/gs-snapd.h b/src/plugins/gs-snapd.h
index 0edb1ec..7b0835e 100644
--- a/src/plugins/gs-snapd.h
+++ b/src/plugins/gs-snapd.h
@@ -29,13 +29,6 @@ typedef void (*GsSnapdProgressCallback) (JsonObject *object, gpointer user_data)
 
 gboolean gs_snapd_exists               (void);
 
-gchar *gs_snapd_login                  (const gchar    *username,
-                                        const gchar    *password,
-                                        const gchar    *otp,
-                                        guint          *status_code,
-                                        GCancellable   *cancellable,
-                                        GError         **error);
-
 JsonObject *gs_snapd_list_one          (const gchar    *name,
                                         GCancellable   *cancellable,
                                         GError         **error);
diff --git a/src/plugins/gs-ubuntuone-dialog.c b/src/plugins/gs-ubuntuone-dialog.c
index 5d77db0..0a6b5ef 100644
--- a/src/plugins/gs-ubuntuone-dialog.c
+++ b/src/plugins/gs-ubuntuone-dialog.c
@@ -25,8 +25,11 @@
 #include <glib/gi18n.h>
 #include <json-glib/json-glib.h>
 #include <libsoup/soup.h>
+#include <snapd-glib/snapd-glib.h>
 
+#ifdef USE_SNAPD
 #include "gs-snapd.h"
+#endif
 
 #define UBUNTU_LOGIN_HOST "https://login.ubuntu.com";
 
@@ -299,87 +302,8 @@ receive_login_response_cb (GsUbuntuoneDialog *self,
 }
 
 static void
-check_snapd_response (GsUbuntuoneDialog *self,
-                     guint              status_code,
-                     gchar             *response)
-{
-       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;
-
-       if (status_code == 401) {
-               /* snapd isn't giving us enough information to tell why the authentication failed... */
-               if (g_str_equal (gtk_stack_get_visible_child_name (GTK_STACK (self->page_stack)), "page-1")) {
-                       show_status (self, _("Two-factor authentication failed"), TRUE);
-                       gtk_widget_grab_focus (self->passcode_entry);
-                       return;
-               }
-       }
-
-       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;
-
-       return;
-
-err:
-       /* snapd isn't giving us enough information to tell why the authentication failed... */
-       show_status (self, status_code == 401 ? _("Incorrect email or password") : _("An error occurred"), 
TRUE);
-       gtk_widget_grab_focus (self->password_entry);
-}
-
-static void
 send_login_request (GsUbuntuoneDialog *self)
 {
-       GVariant *request;
-       g_autoptr(GError) error = NULL;
-
        gtk_widget_set_sensitive (self->cancel_button, FALSE);
        gtk_widget_set_sensitive (self->next_button, FALSE);
        gtk_widget_set_sensitive (self->login_radio, FALSE);
@@ -393,28 +317,44 @@ send_login_request (GsUbuntuoneDialog *self)
        show_status (self, _("Signing in…"), FALSE);
 
        if (self->get_macaroon) {
-               g_autofree gchar *response = NULL;
-               guint status_code;
-
-               response = gs_snapd_login (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)),
-                                          &status_code,
-                                          NULL, &error);
-               if (response != NULL) {
-                       reenable_widgets (self);
-
-                       check_snapd_response (self,
-                                             status_code,
-                                             response);
+#ifdef USE_SNAPD
+               const gchar *username, *password, *otp;
+               g_autoptr(SnapdAuthData) auth_data = NULL;
+               g_autoptr(GError) error = NULL;
+
+               username = gtk_entry_get_text (GTK_ENTRY (self->email_entry));
+               password = gtk_entry_get_text (GTK_ENTRY (self->password_entry));
+               otp = gtk_entry_get_text (GTK_ENTRY (self->passcode_entry));
+               if (otp[0] == '\0')
+                       otp = NULL;
+
+               auth_data = snapd_login_sync (username, password, otp, NULL, &error);
+               reenable_widgets (self);
+               if (auth_data != NULL) {
+                       self->macaroon = g_variant_ref_sink (g_variant_new ("(s^as)", 
snapd_auth_data_get_macaroon (auth_data), snapd_auth_data_get_discharges (auth_data)));
+                       gtk_stack_set_visible_child_name (GTK_STACK (self->page_stack), "page-2");
+                       update_widgets (self);
                } 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);
+                       if (g_error_matches (error, SNAPD_ERROR, SNAPD_ERROR_AUTH_DATA_INVALID) ||
+                           g_error_matches (error, SNAPD_ERROR, SNAPD_ERROR_AUTH_DATA_REQUIRED)) {
+                               show_status (self, _("Incorrect email or password"), TRUE);
+                               gtk_widget_grab_focus (self->password_entry);
+                       } else if (g_error_matches (error, SNAPD_ERROR, SNAPD_ERROR_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 if (g_error_matches (error, SNAPD_ERROR, SNAPD_ERROR_TWO_FACTOR_INVALID)) {
+                               show_status (self, _("Two-factor authentication failed"), TRUE);
+                               gtk_widget_grab_focus (self->passcode_entry);
+                       } else {
+                               show_status (self, _("An error occurred"), TRUE);
+                               gtk_widget_grab_focus (self->password_entry);
+                       }
                }
+#endif
        } else {
+               GVariant *request;
+
                if (gtk_entry_get_text_length (GTK_ENTRY (self->passcode_entry)) > 0) {
                        request = g_variant_new_parsed ("{"
                                                        "  'token_name' : <'GNOME Software'>,"


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