[gnome-software/wip/ubuntu] Use snapd-glib to perform snapd login. This fixes non-root access being removed in snapd.
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/ubuntu] Use snapd-glib to perform snapd login. This fixes non-root access being removed in snapd.
- Date: Thu, 13 Oct 2016 02:24:06 +0000 (UTC)
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]