[gnome-software/wip/attente/ubuntu-xenial: 6/27] Add gs_ubuntuone_get_macaroon ()



commit 3561910e577cea049187c44e4a358469af9d8053
Author: William Hua <william hua canonical com>
Date:   Sun Apr 17 09:29:32 2016 -0400

    Add gs_ubuntuone_get_macaroon ()

 src/plugins/gs-ubuntuone-dialog.c |   23 ++++-
 src/plugins/gs-ubuntuone-dialog.h |    3 +-
 src/plugins/gs-ubuntuone.c        |  203 +++++++++++++++++++++++++++----------
 src/plugins/gs-ubuntuone.h        |    4 +
 4 files changed, 173 insertions(+), 60 deletions(-)
---
diff --git a/src/plugins/gs-ubuntuone-dialog.c b/src/plugins/gs-ubuntuone-dialog.c
index 5c323cc..52132cc 100644
--- a/src/plugins/gs-ubuntuone-dialog.c
+++ b/src/plugins/gs-ubuntuone-dialog.c
@@ -49,6 +49,9 @@ struct _GsUbuntuoneDialog
 
        SoupSession *session;
 
+       gboolean get_macaroon;
+
+       GVariant *macaroon;
        gchar *consumer_key;
        gchar *consumer_secret;
        gchar *token_key;
@@ -395,6 +398,7 @@ gs_ubuntuone_dialog_finalize (GObject *object)
        g_clear_pointer (&self->token_key, g_free);
        g_clear_pointer (&self->consumer_secret, g_free);
        g_clear_pointer (&self->consumer_key, g_free);
+       g_clear_pointer (&self->macaroon, g_variant_unref);
 
        G_OBJECT_CLASS (gs_ubuntuone_dialog_parent_class)->finalize (object);
 }
@@ -433,6 +437,13 @@ gs_ubuntuone_dialog_get_do_remember (GsUbuntuoneDialog *dialog)
        return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->remember_check));
 }
 
+GVariant *
+gs_ubuntuone_dialog_get_macaroon (GsUbuntuoneDialog *dialog)
+{
+       g_return_val_if_fail (GS_IS_UBUNTUONE_DIALOG (dialog), NULL);
+       return dialog->macaroon;
+}
+
 const gchar *
 gs_ubuntuone_dialog_get_consumer_key (GsUbuntuoneDialog *dialog)
 {
@@ -462,11 +473,15 @@ gs_ubuntuone_dialog_get_token_secret (GsUbuntuoneDialog *dialog)
 }
 
 GtkWidget *
-gs_ubuntuone_dialog_new (void)
+gs_ubuntuone_dialog_new (gboolean get_macaroon)
 {
-       return GTK_WIDGET (g_object_new (GS_TYPE_UBUNTUONE_DIALOG,
-                                        "use-header-bar", TRUE,
-                                        NULL));
+       GsUbuntuoneDialog *dialog = g_object_new (GS_TYPE_UBUNTUONE_DIALOG,
+                                                 "use-header-bar", TRUE,
+                                                 NULL);
+
+       dialog->get_macaroon = get_macaroon;
+
+       return GTK_WIDGET (dialog);
 }
 
 /* vim: set noexpandtab: */
diff --git a/src/plugins/gs-ubuntuone-dialog.h b/src/plugins/gs-ubuntuone-dialog.h
index 6bfcc2e..d98404e 100644
--- a/src/plugins/gs-ubuntuone-dialog.h
+++ b/src/plugins/gs-ubuntuone-dialog.h
@@ -30,8 +30,9 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (GsUbuntuoneDialog, gs_ubuntuone_dialog, GS, UBUNTUONE_DIALOG, GtkDialog)
 
-GtkWidget      *gs_ubuntuone_dialog_new                        (void);
+GtkWidget      *gs_ubuntuone_dialog_new                        (gboolean           get_macaroon);
 gboolean        gs_ubuntuone_dialog_get_do_remember            (GsUbuntuoneDialog *dialog);
+GVariant       *gs_ubuntuone_dialog_get_macaroon               (GsUbuntuoneDialog *dialog);
 const gchar    *gs_ubuntuone_dialog_get_consumer_key           (GsUbuntuoneDialog *dialog);
 const gchar    *gs_ubuntuone_dialog_get_consumer_secret        (GsUbuntuoneDialog *dialog);
 const gchar    *gs_ubuntuone_dialog_get_token_key              (GsUbuntuoneDialog *dialog);
diff --git a/src/plugins/gs-ubuntuone.c b/src/plugins/gs-ubuntuone.c
index 6d24ae6..29165e8 100644
--- a/src/plugins/gs-ubuntuone.c
+++ b/src/plugins/gs-ubuntuone.c
@@ -29,6 +29,7 @@
 #include "gs-ubuntuone-dialog.h"
 
 #define SCHEMA_NAME     "com.ubuntu.UbuntuOne.GnomeSoftware"
+#define MACAROON        "macaroon"
 #define CONSUMER_KEY    "consumer-key"
 #define CONSUMER_SECRET "consumer-secret"
 #define TOKEN_KEY       "token-key"
@@ -42,6 +43,152 @@ static SecretSchema schema = {
 
 typedef struct
 {
+       GError **error;
+
+       GCond cond;
+       GMutex mutex;
+
+       gboolean get_macaroon;
+
+       gboolean done;
+       gboolean success;
+       gboolean remember;
+
+       GVariant *macaroon;
+       gchar *consumer_key;
+       gchar *consumer_secret;
+       gchar *token_key;
+       gchar *token_secret;
+} LoginContext;
+
+static gboolean
+show_login_dialog (gpointer user_data)
+{
+       LoginContext *context = user_data;
+       GtkWidget *dialog;
+
+       dialog = gs_ubuntuone_dialog_new (context->get_macaroon);
+
+       switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
+       case GTK_RESPONSE_DELETE_EVENT:
+       case GTK_RESPONSE_CANCEL:
+               if (context->get_macaroon) {
+                       g_set_error (context->error,
+                                    GS_PLUGIN_ERROR,
+                                    GS_PLUGIN_ERROR_FAILED,
+                                    "Unable to obtain snapd macaroon");
+               } else {
+                       g_set_error (context->error,
+                                    GS_PLUGIN_ERROR,
+                                    GS_PLUGIN_ERROR_FAILED,
+                                    "Unable to sign into Ubuntu One");
+               }
+
+               context->success = FALSE;
+               break;
+
+       case GTK_RESPONSE_OK:
+               context->remember = gs_ubuntuone_dialog_get_do_remember (GS_UBUNTUONE_DIALOG (dialog));
+               context->macaroon = gs_ubuntuone_dialog_get_macaroon (GS_UBUNTUONE_DIALOG (dialog));
+               context->consumer_key = g_strdup (gs_ubuntuone_dialog_get_consumer_key (GS_UBUNTUONE_DIALOG 
(dialog)));
+               context->consumer_secret = g_strdup (gs_ubuntuone_dialog_get_consumer_secret 
(GS_UBUNTUONE_DIALOG (dialog)));
+               context->token_key = g_strdup (gs_ubuntuone_dialog_get_token_key (GS_UBUNTUONE_DIALOG 
(dialog)));
+               context->token_secret = g_strdup (gs_ubuntuone_dialog_get_token_secret (GS_UBUNTUONE_DIALOG 
(dialog)));
+               context->success = TRUE;
+
+               if (context->macaroon != NULL)
+                       g_variant_ref (context->macaroon);
+
+               break;
+       }
+
+       gtk_widget_destroy (dialog);
+
+       g_mutex_lock (&context->mutex);
+       context->done = TRUE;
+       g_cond_signal (&context->cond);
+       g_mutex_unlock (&context->mutex);
+
+       return G_SOURCE_REMOVE;
+}
+
+GVariant *
+gs_ubuntuone_get_macaroon (gboolean   use_cache,
+                          gboolean   show_dialog,
+                          GError   **error)
+{
+       LoginContext login_context = { 0 };
+       g_autofree gchar *password = NULL;
+       g_autofree gchar *printed = NULL;
+       GVariant *macaroon = NULL;
+       GError *error_local = NULL;
+
+       if (use_cache) {
+               password = secret_password_lookup_sync (&schema,
+                                                       NULL,
+                                                       &error_local,
+                                                       "key", MACAROON,
+                                                       NULL);
+
+               if (password) {
+                       macaroon = g_variant_parse (G_VARIANT_TYPE ("(sas)"),
+                                                   password,
+                                                   NULL,
+                                                   NULL,
+                                                   &error_local);
+
+                       if (macaroon)
+                               return macaroon;
+
+                       g_warning ("could not parse macaroon: %s", error_local->message);
+                       g_clear_error (&error_local);
+               } else if (error_local != NULL) {
+                       g_warning ("could not lookup cached macaroon: %s", error_local->message);
+                       g_clear_error (&error_local);
+               }
+       }
+
+       if (show_dialog) {
+               /* Pop up a login dialog */
+               login_context.error = error;
+               login_context.get_macaroon = TRUE;
+               g_cond_init (&login_context.cond);
+               g_mutex_init (&login_context.mutex);
+               g_mutex_lock (&login_context.mutex);
+
+               gdk_threads_add_idle (show_login_dialog, &login_context);
+
+               while (!login_context.done)
+                       g_cond_wait (&login_context.cond, &login_context.mutex);
+
+               g_mutex_unlock (&login_context.mutex);
+               g_mutex_clear (&login_context.mutex);
+               g_cond_clear (&login_context.cond);
+
+               if (login_context.macaroon) {
+                       printed = g_variant_print (login_context.macaroon, FALSE);
+
+                       if (!secret_password_store_sync (&schema,
+                                                        NULL,
+                                                        SCHEMA_NAME,
+                                                        printed,
+                                                        NULL,
+                                                        &error_local,
+                                                        "key", MACAROON,
+                                                        NULL)) {
+                               g_warning ("could not store macaroon: %s", error_local->message);
+                               g_clear_error (&error_local);
+                       }
+               }
+
+               return login_context.macaroon;
+       }
+
+       return NULL;
+}
+
+typedef struct
+{
        GCancellable *cancellable;
        GCond cond;
        GMutex mutex;
@@ -122,61 +269,6 @@ lookup_token_secret (GObject      *source_object,
        g_mutex_unlock (&context->mutex);
 }
 
-typedef struct
-{
-       GError **error;
-
-       GCond cond;
-       GMutex mutex;
-
-       gboolean done;
-       gboolean success;
-       gboolean remember;
-
-       gchar *consumer_key;
-       gchar *consumer_secret;
-       gchar *token_key;
-       gchar *token_secret;
-} LoginContext;
-
-static gboolean
-show_login_dialog (gpointer user_data)
-{
-       LoginContext *context = user_data;
-       GtkWidget *dialog;
-
-       dialog = gs_ubuntuone_dialog_new ();
-       switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
-       case GTK_RESPONSE_DELETE_EVENT:
-       case GTK_RESPONSE_CANCEL:
-               g_set_error (context->error,
-                            GS_PLUGIN_ERROR,
-                            GS_PLUGIN_ERROR_FAILED,
-                            "Unable to sign into Ubuntu One");
-
-               context->success = FALSE;
-               break;
-
-       case GTK_RESPONSE_OK:
-               context->remember = gs_ubuntuone_dialog_get_do_remember (GS_UBUNTUONE_DIALOG (dialog));
-               context->consumer_key = g_strdup (gs_ubuntuone_dialog_get_consumer_key (GS_UBUNTUONE_DIALOG 
(dialog)));
-               context->consumer_secret = g_strdup (gs_ubuntuone_dialog_get_consumer_secret 
(GS_UBUNTUONE_DIALOG (dialog)));
-               context->token_key = g_strdup (gs_ubuntuone_dialog_get_token_key (GS_UBUNTUONE_DIALOG 
(dialog)));
-               context->token_secret = g_strdup (gs_ubuntuone_dialog_get_token_secret (GS_UBUNTUONE_DIALOG 
(dialog)));
-               context->success = TRUE;
-               break;
-       }
-
-       gtk_widget_destroy (dialog);
-
-       g_mutex_lock (&context->mutex);
-       context->done = TRUE;
-       g_cond_signal (&context->cond);
-       g_mutex_unlock (&context->mutex);
-
-       return G_SOURCE_REMOVE;
-}
-
 gboolean
 gs_ubuntuone_get_credentials (gchar **consumer_key, gchar **consumer_secret, gchar **token_key, gchar 
**token_secret)
 {
@@ -248,6 +340,7 @@ gs_ubuntuone_sign_in (gchar **consumer_key, gchar **consumer_secret, gchar **tok
 
        /* Pop up a login dialog */
        login_context.error = error;
+       login_context.get_macaroon = FALSE;
        g_cond_init (&login_context.cond);
        g_mutex_init (&login_context.mutex);
        g_mutex_lock (&login_context.mutex);
diff --git a/src/plugins/gs-ubuntuone.h b/src/plugins/gs-ubuntuone.h
index d1256ae..39bbd89 100644
--- a/src/plugins/gs-ubuntuone.h
+++ b/src/plugins/gs-ubuntuone.h
@@ -26,6 +26,10 @@
 
 G_BEGIN_DECLS
 
+GVariant       *gs_ubuntuone_get_macaroon      (gboolean         use_cache,
+                                                gboolean         show_dialog,
+                                                GError         **error);
+
 gboolean        gs_ubuntuone_get_credentials   (gchar  **consumer_key,
                                                 gchar  **consumer_secret,
                                                 gchar  **token_key,


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