[gnome-software/wip/kalev/flatpak-auth-support: 63/65] Add basic auth support to flatpak plugin
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/kalev/flatpak-auth-support: 63/65] Add basic auth support to flatpak plugin
- Date: Tue, 30 Jun 2020 16:46:25 +0000 (UTC)
commit f52394e809ab8a52b5ea47fb6e9b83895aca95b7
Author: Kalev Lember <klember redhat com>
Date: Mon May 18 14:45:35 2020 +0200
Add basic auth support to flatpak plugin
This is useful for e.g. OCI remotes that can use basic auth.
All user visible strings in the basic auth dialog are taken from the
flatpak CLI client.
lib/gs-plugin-loader.c | 29 +++++-
lib/gs-plugin-loader.h | 7 +-
lib/gs-plugin.c | 68 +++++++++++-
lib/gs-plugin.h | 13 ++-
plugins/flatpak/gs-plugin-flatpak.c | 55 +++++++++-
po/POTFILES.in | 2 +
src/gnome-software.gresource.xml | 1 +
src/gs-basic-auth-dialog.c | 130 +++++++++++++++++++++++
src/gs-basic-auth-dialog.h | 28 +++++
src/gs-basic-auth-dialog.ui | 203 ++++++++++++++++++++++++++++++++++++
src/gs-shell.c | 25 ++++-
src/meson.build | 1 +
12 files changed, 556 insertions(+), 6 deletions(-)
---
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index d7de62c8..dbe35aca 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2007-2018 Richard Hughes <richard hughsie com>
- * Copyright (C) 2014-2018 Kalev Lember <klember redhat com>
+ * Copyright (C) 2014-2020 Kalev Lember <klember redhat com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -74,6 +74,7 @@ enum {
SIGNAL_PENDING_APPS_CHANGED,
SIGNAL_UPDATES_CHANGED,
SIGNAL_RELOAD,
+ SIGNAL_BASIC_AUTH_START,
SIGNAL_LAST
};
@@ -2016,6 +2017,23 @@ gs_plugin_loader_status_changed_cb (GsPlugin *plugin,
0, app, status);
}
+static void
+gs_plugin_loader_basic_auth_start_cb (GsPlugin *plugin,
+ const gchar *remote,
+ const gchar *realm,
+ GCallback callback,
+ gpointer user_data,
+ GsPluginLoader *plugin_loader)
+{
+ g_debug ("emitting basic-auth-start %s", realm);
+ g_signal_emit (plugin_loader,
+ signals[SIGNAL_BASIC_AUTH_START], 0,
+ remote,
+ realm,
+ callback,
+ user_data);
+}
+
static gboolean
gs_plugin_loader_job_actions_changed_delay_cb (gpointer user_data)
{
@@ -2102,6 +2120,9 @@ gs_plugin_loader_open_plugin (GsPluginLoader *plugin_loader,
g_signal_connect (plugin, "status-changed",
G_CALLBACK (gs_plugin_loader_status_changed_cb),
plugin_loader);
+ g_signal_connect (plugin, "basic-auth-start",
+ G_CALLBACK (gs_plugin_loader_basic_auth_start_cb),
+ plugin_loader);
g_signal_connect (plugin, "report-event",
G_CALLBACK (gs_plugin_loader_report_event_cb),
plugin_loader);
@@ -2712,6 +2733,12 @@ gs_plugin_loader_class_init (GsPluginLoaderClass *klass)
G_STRUCT_OFFSET (GsPluginLoaderClass, reload),
NULL, NULL, g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ signals [SIGNAL_BASIC_AUTH_START] =
+ g_signal_new ("basic-auth-start",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsPluginLoaderClass, basic_auth_start),
+ NULL, NULL, g_cclosure_marshal_generic,
+ G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER);
}
static void
diff --git a/lib/gs-plugin-loader.h b/lib/gs-plugin-loader.h
index 51e27f9b..665eab67 100644
--- a/lib/gs-plugin-loader.h
+++ b/lib/gs-plugin-loader.h
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2007-2017 Richard Hughes <richard hughsie com>
- * Copyright (C) 2015 Kalev Lember <klember redhat com>
+ * Copyright (C) 2015-2020 Kalev Lember <klember redhat com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -31,6 +31,11 @@ struct _GsPluginLoaderClass
void (*pending_apps_changed) (GsPluginLoader *plugin_loader);
void (*updates_changed) (GsPluginLoader *plugin_loader);
void (*reload) (GsPluginLoader *plugin_loader);
+ void (*basic_auth_start) (GsPluginLoader *plugin_loader,
+ const gchar *remote,
+ const gchar *realm,
+ GCallback callback,
+ gpointer user_data);
};
GsPluginLoader *gs_plugin_loader_new (void);
diff --git a/lib/gs-plugin.c b/lib/gs-plugin.c
index 5aed1058..3f63fa97 100644
--- a/lib/gs-plugin.c
+++ b/lib/gs-plugin.c
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2013-2016 Richard Hughes <richard hughsie com>
- * Copyright (C) 2014-2018 Kalev Lember <klember redhat com>
+ * Copyright (C) 2014-2020 Kalev Lember <klember redhat com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -87,6 +87,7 @@ enum {
SIGNAL_RELOAD,
SIGNAL_REPORT_EVENT,
SIGNAL_ALLOW_UPDATES,
+ SIGNAL_BASIC_AUTH_START,
SIGNAL_LAST
};
@@ -851,6 +852,64 @@ gs_plugin_status_update (GsPlugin *plugin, GsApp *app, GsPluginStatus status)
g_source_attach (idle_source, NULL);
}
+typedef struct {
+ GsPlugin *plugin;
+ gchar *remote;
+ gchar *realm;
+ GCallback callback;
+ gpointer user_data;
+} GsPluginBasicAuthHelper;
+
+static gboolean
+gs_plugin_basic_auth_start_cb (gpointer user_data)
+{
+ GsPluginBasicAuthHelper *helper = user_data;
+ g_signal_emit (helper->plugin,
+ signals[SIGNAL_BASIC_AUTH_START], 0,
+ helper->remote,
+ helper->realm,
+ helper->callback,
+ helper->user_data);
+ g_free (helper->remote);
+ g_free (helper->realm);
+ g_slice_free (GsPluginBasicAuthHelper, helper);
+ return FALSE;
+}
+
+/**
+ * gs_plugin_basic_auth_start:
+ * @plugin: a #GsPlugin
+ * @remote: a string
+ * @realm: a string
+ * @callback: callback to invoke to submit the user/password
+ * @user_data: callback data to pass to the callback
+ *
+ * Emit the basic-auth-start signal in the main thread.
+ *
+ * Since: 3.38
+ **/
+void
+gs_plugin_basic_auth_start (GsPlugin *plugin,
+ const gchar *remote,
+ const gchar *realm,
+ GCallback callback,
+ gpointer user_data)
+{
+ GsPluginBasicAuthHelper *helper;
+ g_autoptr(GSource) idle_source = NULL;
+
+ helper = g_slice_new0 (GsPluginBasicAuthHelper);
+ helper->plugin = plugin;
+ helper->remote = g_strdup (remote);
+ helper->realm = g_strdup (realm);
+ helper->callback = callback;
+ helper->user_data = user_data;
+
+ idle_source = g_idle_source_new ();
+ g_source_set_callback (idle_source, gs_plugin_basic_auth_start_cb, helper, NULL);
+ g_source_attach (idle_source, NULL);
+}
+
static gboolean
gs_plugin_app_launch_cb (gpointer user_data)
{
@@ -1959,6 +2018,13 @@ gs_plugin_class_init (GsPluginClass *klass)
G_STRUCT_OFFSET (GsPluginClass, allow_updates),
NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+ signals [SIGNAL_BASIC_AUTH_START] =
+ g_signal_new ("basic-auth-start",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsPluginClass, basic_auth_start),
+ NULL, NULL, g_cclosure_marshal_generic,
+ G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER);
}
static void
diff --git a/lib/gs-plugin.h b/lib/gs-plugin.h
index 7dd2d864..d07afd3b 100644
--- a/lib/gs-plugin.h
+++ b/lib/gs-plugin.h
@@ -1,6 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2012-2016 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2020 Kalev Lember <klember redhat com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -37,7 +38,12 @@ struct _GsPluginClass
GsPluginEvent *event);
void (*allow_updates) (GsPlugin *plugin,
gboolean allow_updates);
- gpointer padding[26];
+ void (*basic_auth_start) (GsPlugin *plugin,
+ const gchar *remote,
+ const gchar *realm,
+ GCallback callback,
+ gpointer user_data);
+ gpointer padding[25];
};
typedef struct GsPluginData GsPluginData;
@@ -116,5 +122,10 @@ void gs_plugin_report_event (GsPlugin *plugin,
void gs_plugin_set_allow_updates (GsPlugin *plugin,
gboolean allow_updates);
gboolean gs_plugin_get_network_available (GsPlugin *plugin);
+void gs_plugin_basic_auth_start (GsPlugin *plugin,
+ const gchar *remote,
+ const gchar *realm,
+ GCallback callback,
+ gpointer user_data);
G_END_DECLS
diff --git a/plugins/flatpak/gs-plugin-flatpak.c b/plugins/flatpak/gs-plugin-flatpak.c
index ae026d5d..56a3367b 100644
--- a/plugins/flatpak/gs-plugin-flatpak.c
+++ b/plugins/flatpak/gs-plugin-flatpak.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2016 Joaquim Rocha <jrocha endlessm com>
* Copyright (C) 2016-2018 Richard Hughes <richard hughsie com>
- * Copyright (C) 2017-2018 Kalev Lember <klember redhat com>
+ * Copyright (C) 2017-2020 Kalev Lember <klember redhat com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -456,6 +456,55 @@ _group_apps_by_installation (GsPlugin *plugin,
return g_steal_pointer (&applist_by_flatpaks);
}
+#if FLATPAK_CHECK_VERSION(1,6,0)
+typedef struct {
+ FlatpakTransaction *transaction;
+ guint id;
+} BasicAuthData;
+
+static void
+basic_auth_data_free (BasicAuthData *data)
+{
+ g_object_unref (data->transaction);
+ g_slice_free (BasicAuthData, data);
+}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(BasicAuthData, basic_auth_data_free)
+
+static void
+_basic_auth_cb (const gchar *user, const gchar *password, gpointer user_data)
+{
+ g_autoptr(BasicAuthData) data = user_data;
+
+ g_debug ("Submitting basic auth data");
+
+ /* NULL user aborts the basic auth request */
+ flatpak_transaction_complete_basic_auth (data->transaction, data->id, user, password, NULL /* options
*/);
+}
+
+static gboolean
+_basic_auth_start (FlatpakTransaction *transaction,
+ const char *remote,
+ const char *realm,
+ GVariant *options,
+ guint id,
+ GsPlugin *plugin)
+{
+ BasicAuthData *data;
+
+ if (!gs_plugin_has_flags (plugin, GS_PLUGIN_FLAGS_INTERACTIVE))
+ return FALSE;
+
+ data = g_slice_new0 (BasicAuthData);
+ data->transaction = g_object_ref (transaction);
+ data->id = id;
+
+ g_debug ("Login required remote %s (realm %s)\n", remote, realm);
+ gs_plugin_basic_auth_start (plugin, remote, realm, G_CALLBACK (_basic_auth_cb), data);
+ return TRUE;
+}
+#endif
+
static FlatpakTransaction *
_build_transaction (GsPlugin *plugin, GsFlatpak *flatpak,
GCancellable *cancellable, GError **error)
@@ -503,6 +552,10 @@ _build_transaction (GsPlugin *plugin, GsFlatpak *flatpak,
/* connect up signals */
g_signal_connect (transaction, "ref-to-app",
G_CALLBACK (_ref_to_app), plugin);
+#if FLATPAK_CHECK_VERSION(1,6,0)
+ g_signal_connect (transaction, "basic-auth-start",
+ G_CALLBACK (_basic_auth_start), plugin);
+#endif
/* use system installations as dependency sources for user installations */
flatpak_transaction_add_default_dependency_sources (transaction);
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 20721c4a..a44a6ad3 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -10,6 +10,8 @@ src/gs-app-row.c
src/gs-app-row.ui
src/gs-app-tile.c
src/gs-app-tile.ui
+src/gs-basic-auth-dialog.c
+src/gs-basic-auth-dialog.ui
lib/gs-category.c
src/gs-category-page.c
src/gs-category-page.ui
diff --git a/src/gnome-software.gresource.xml b/src/gnome-software.gresource.xml
index 3eaabca2..459ecf82 100644
--- a/src/gnome-software.gresource.xml
+++ b/src/gnome-software.gresource.xml
@@ -4,6 +4,7 @@
<file preprocess="xml-stripblanks">gnome-software.ui</file>
<file preprocess="xml-stripblanks">gs-app-addon-row.ui</file>
<file preprocess="xml-stripblanks">gs-app-row.ui</file>
+ <file preprocess="xml-stripblanks">gs-basic-auth-dialog.ui</file>
<file preprocess="xml-stripblanks">gs-category-page.ui</file>
<file preprocess="xml-stripblanks">gs-category-tile.ui</file>
<file preprocess="xml-stripblanks">gs-details-page.ui</file>
diff --git a/src/gs-basic-auth-dialog.c b/src/gs-basic-auth-dialog.c
new file mode 100644
index 00000000..c690a327
--- /dev/null
+++ b/src/gs-basic-auth-dialog.c
@@ -0,0 +1,130 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2020 Kalev Lember <klember redhat com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "config.h"
+
+#include "gs-basic-auth-dialog.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+struct _GsBasicAuthDialog
+{
+ GtkDialog parent_instance;
+
+ GsBasicAuthCallback callback;
+ gpointer callback_data;
+
+ /* template widgets */
+ GtkButton *login_button;
+ GtkLabel *description_label;
+ GtkEntry *user_entry;
+ GtkEntry *password_entry;
+};
+
+G_DEFINE_TYPE (GsBasicAuthDialog, gs_basic_auth_dialog, GTK_TYPE_DIALOG)
+
+static void
+cancel_button_clicked_cb (GsBasicAuthDialog *dialog)
+{
+ /* abort the basic auth request */
+ dialog->callback (NULL, NULL, dialog->callback_data);
+
+ gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
+}
+
+static void
+login_button_clicked_cb (GsBasicAuthDialog *dialog)
+{
+ const gchar *user;
+ const gchar *password;
+
+ user = gtk_entry_get_text (dialog->user_entry);
+ password = gtk_entry_get_text (dialog->password_entry);
+
+ /* submit the user/password to basic auth */
+ dialog->callback (user, password, dialog->callback_data);
+
+ gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+}
+
+static void
+dialog_validate (GsBasicAuthDialog *dialog)
+{
+ const gchar *user;
+ const gchar *password;
+ gboolean valid_user;
+ gboolean valid_password;
+
+ /* require user */
+ user = gtk_entry_get_text (dialog->user_entry);
+ valid_user = user != NULL && strlen (user) != 0;
+
+ /* require password */
+ password = gtk_entry_get_text (dialog->password_entry);
+ valid_password = password != NULL && strlen (password) != 0;
+
+ gtk_widget_set_sensitive (GTK_WIDGET (dialog->login_button), valid_user && valid_password);
+}
+
+static void
+update_description (GsBasicAuthDialog *dialog, const gchar *remote, const gchar *realm)
+{
+ g_autofree gchar *description = NULL;
+
+ /* TRANSLATORS: This is a description for entering user/password */
+ description = g_strdup_printf (_("Login required remote %s (realm %s)"),
+ remote, realm);
+ gtk_label_set_text (dialog->description_label, description);
+}
+
+static void
+gs_basic_auth_dialog_init (GsBasicAuthDialog *dialog)
+{
+ gtk_widget_init_template (GTK_WIDGET (dialog));
+}
+
+static void
+gs_basic_auth_dialog_class_init (GsBasicAuthDialogClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/Software/gs-basic-auth-dialog.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, GsBasicAuthDialog, login_button);
+ gtk_widget_class_bind_template_child (widget_class, GsBasicAuthDialog, description_label);
+ gtk_widget_class_bind_template_child (widget_class, GsBasicAuthDialog, user_entry);
+ gtk_widget_class_bind_template_child (widget_class, GsBasicAuthDialog, password_entry);
+
+ gtk_widget_class_bind_template_callback (widget_class, dialog_validate);
+ gtk_widget_class_bind_template_callback (widget_class, cancel_button_clicked_cb);
+ gtk_widget_class_bind_template_callback (widget_class, login_button_clicked_cb);
+}
+
+GtkWidget *
+gs_basic_auth_dialog_new (GtkWindow *parent,
+ const gchar *remote,
+ const gchar *realm,
+ GsBasicAuthCallback callback,
+ gpointer callback_data)
+{
+ GsBasicAuthDialog *dialog;
+
+ dialog = g_object_new (GS_TYPE_BASIC_AUTH_DIALOG,
+ "use-header-bar", TRUE,
+ "transient-for", parent,
+ "modal", TRUE,
+ NULL);
+ dialog->callback = callback;
+ dialog->callback_data = callback_data;
+
+ update_description (dialog, remote, realm);
+ dialog_validate (dialog);
+
+ return GTK_WIDGET (dialog);
+}
diff --git a/src/gs-basic-auth-dialog.h b/src/gs-basic-auth-dialog.h
new file mode 100644
index 00000000..ec5f1d03
--- /dev/null
+++ b/src/gs-basic-auth-dialog.h
@@ -0,0 +1,28 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2020 Kalev Lember <klember redhat com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+#include "gnome-software-private.h"
+
+G_BEGIN_DECLS
+
+typedef void (*GsBasicAuthCallback) (const gchar *user, const gchar *password, gpointer callback_data);
+
+#define GS_TYPE_BASIC_AUTH_DIALOG (gs_basic_auth_dialog_get_type ())
+
+G_DECLARE_FINAL_TYPE (GsBasicAuthDialog, gs_basic_auth_dialog, GS, BASIC_AUTH_DIALOG, GtkDialog)
+
+GtkWidget *gs_basic_auth_dialog_new (GtkWindow *parent,
+ const gchar *remote,
+ const gchar *realm,
+ GsBasicAuthCallback callback,
+ gpointer callback_data);
+
+G_END_DECLS
diff --git a/src/gs-basic-auth-dialog.ui b/src/gs-basic-auth-dialog.ui
new file mode 100644
index 00000000..339e831d
--- /dev/null
+++ b/src/gs-basic-auth-dialog.ui
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="GsBasicAuthDialog" parent="GtkDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">5</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="title" translatable="yes">Login Required</property>
+ <property name="use_header_bar">1</property>
+ <child internal-child="headerbar">
+ <object class="GtkHeaderBar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="show_close_button">False</property>
+ <child>
+ <object class="GtkButton" id="cancel_button">
+ <property name="label" translatable="yes">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="valign">center</property>
+ <signal name="clicked" handler="cancel_button_clicked_cb" object="GsBasicAuthDialog"
swapped="yes"/>
+ <style>
+ <class name="text-button"/>
+ </style>
+ </object>
+ <packing>
+ <property name="pack_type">start</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="login_button">
+ <property name="label" translatable="yes">_Login</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="valign">center</property>
+ <signal name="clicked" handler="login_button_clicked_cb" object="GsBasicAuthDialog"
swapped="yes"/>
+ <style>
+ <class name="text-button"/>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">8</property>
+ <property name="column_spacing">6</property>
+ <property name="border_width">20</property>
+ <property name="margin_end">20</property>
+ <child>
+ <object class="GtkLabel" id="description_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="wrap">True</property>
+ <property name="wrap_mode">word-char</property>
+ <property name="margin_bottom">20</property>
+ <property name="max_width_chars">55</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="user_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_User</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">user_entry</property>
+ <property name="margin_start">20</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="password_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Password</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">password_entry</property>
+ <property name="margin_start">20</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="user_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ <property name="invisible_char_set">True</property>
+ <property name="input_purpose">password</property>
+ <signal name="changed" handler="dialog_validate" object="GsBasicAuthDialog" swapped="yes"/>
+ <signal name="activate" handler="dialog_validate" object="GsBasicAuthDialog" swapped="yes"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="password_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="visibility">False</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ <property name="invisible_char_set">True</property>
+ <property name="input_purpose">password</property>
+ <signal name="changed" handler="dialog_validate" object="GsBasicAuthDialog" swapped="yes"/>
+ <signal name="activate" handler="dialog_validate" object="GsBasicAuthDialog" swapped="yes"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="GtkSizeGroup">
+ <widgets>
+ <widget name="user_label"/>
+ <widget name="password_label"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup">
+ <widgets>
+ <widget name="user_entry"/>
+ <widget name="password_entry"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup">
+ <property name="mode">horizontal</property>
+ <widgets>
+ <widget name="login_button"/>
+ <widget name="cancel_button"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/src/gs-shell.c b/src/gs-shell.c
index 009776ad..41503cf8 100644
--- a/src/gs-shell.c
+++ b/src/gs-shell.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2013-2017 Richard Hughes <richard hughsie com>
* Copyright (C) 2013 Matthias Clasen <mclasen redhat com>
- * Copyright (C) 2014-2018 Kalev Lember <klember redhat com>
+ * Copyright (C) 2014-2020 Kalev Lember <klember redhat com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -18,6 +18,7 @@
#include "gs-common.h"
#include "gs-shell.h"
+#include "gs-basic-auth-dialog.h"
#include "gs-details-page.h"
#include "gs-installed-page.h"
#include "gs-metered-data-dialog.h"
@@ -362,6 +363,25 @@ scheduler_ready_cb (GObject *source_object,
}
#endif /* HAVE_MOGWAI */
+static void
+gs_shell_basic_auth_start_cb (GsPluginLoader *plugin_loader,
+ const gchar *remote,
+ const gchar *realm,
+ GsBasicAuthCallback callback,
+ gpointer callback_data,
+ GsShell *shell)
+{
+ GsShellPrivate *priv = gs_shell_get_instance_private (shell);
+ GtkWidget *dialog;
+
+ dialog = gs_basic_auth_dialog_new (priv->main_window, remote, realm, callback, callback_data);
+ gs_shell_modal_dialog_present (shell, GTK_DIALOG (dialog));
+
+ /* just destroy */
+ g_signal_connect_swapped (dialog, "response",
+ G_CALLBACK (gtk_widget_destroy), dialog);
+}
+
static void
free_back_entry (BackEntry *entry)
{
@@ -2126,6 +2146,9 @@ gs_shell_setup (GsShell *shell, GsPluginLoader *plugin_loader, GCancellable *can
g_signal_connect_object (priv->plugin_loader, "notify::network-metered",
G_CALLBACK (gs_shell_network_metered_notify_cb),
shell, 0);
+ g_signal_connect_object (priv->plugin_loader, "basic-auth-start",
+ G_CALLBACK (gs_shell_basic_auth_start_cb),
+ shell, 0);
priv->cancellable = g_object_ref (cancellable);
priv->settings = g_settings_new ("org.gnome.software");
diff --git a/src/meson.build b/src/meson.build
index cbd0a511..6581e77c 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -20,6 +20,7 @@ gnome_software_sources = [
'gs-application.c',
'gs-app-row.c',
'gs-app-tile.c',
+ 'gs-basic-auth-dialog.c',
'gs-category-page.c',
'gs-category-tile.c',
'gs-common.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]