1563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/* 2563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Copyright (C) 2009 Igalia S.L. 3563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 4563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * This library is free software; you can redistribute it and/or 5563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * modify it under the terms of the GNU Library General Public 6563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * License as published by the Free Software Foundation; either 7563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * version 2 of the License, or (at your option) any later version. 8563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 9563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * This library is distributed in the hope that it will be useful, 10563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * but WITHOUT ANY WARRANTY; without even the implied warranty of 11563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Library General Public License for more details. 13563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 14563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * You should have received a copy of the GNU Library General Public License 15563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * along with this library; see the file COPYING.LIB. If not, write to 16563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Boston, MA 02110-1301, USA. 18563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */ 19563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 20563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include "config.h" 21563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 22231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#define LIBSOUP_I_HAVE_READ_BUG_594377_AND_KNOW_SOUP_PASSWORD_MANAGER_MIGHT_GO_AWAY 23231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <glib/gi18n-lib.h> 25563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include <gtk/gtk.h> 26563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include <libsoup/soup.h> 27563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 28ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "GtkVersioning.h" 29563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include "webkitmarshal.h" 30563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include "webkitsoupauthdialog.h" 31563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch/** 330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * SECTION:webkitsoupauthdialog 34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * @short_description: A #SoupSessionFeature to provide a simple 350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * authentication dialog for HTTP basic auth support. 360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 37231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * #WebKitSoupAuthDialog is a #SoupSessionFeature that you can attach to your 38231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * #SoupSession to provide a simple authentication dialog while 39231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * handling HTTP basic auth. It is built as a simple C-only module 40231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * to ease reuse. 410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch */ 420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 43563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic void webkit_soup_auth_dialog_session_feature_init(SoupSessionFeatureInterface* feature_interface, gpointer interface_data); 44563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic void attach(SoupSessionFeature* manager, SoupSession* session); 45563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic void detach(SoupSessionFeature* manager, SoupSession* session); 46563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 47563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkenum { 48563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark CURRENT_TOPLEVEL, 49563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark LAST_SIGNAL 50563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}; 51563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 52563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic guint signals[LAST_SIGNAL] = { 0 }; 53563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 54563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkG_DEFINE_TYPE_WITH_CODE(WebKitSoupAuthDialog, webkit_soup_auth_dialog, G_TYPE_OBJECT, 55563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark G_IMPLEMENT_INTERFACE(SOUP_TYPE_SESSION_FEATURE, 56563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark webkit_soup_auth_dialog_session_feature_init)) 57563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 58563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic void webkit_soup_auth_dialog_class_init(WebKitSoupAuthDialogClass* klass) 59563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 60563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GObjectClass* object_class = G_OBJECT_CLASS(klass); 61563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 62a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch /** 63a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * WebKitSoupAuthDialog::current-toplevel: 64a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * @authDialog: the object on which the signal is emitted 65a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * @message: the #SoupMessage being used in the authentication process 66a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * 67a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * This signal is emitted by the @authDialog when it needs to know 68a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * the current toplevel widget in order to correctly set the 69a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * transiency for the authentication dialog. 70a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * 71a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * Return value: (transfer none): the current toplevel #GtkWidget or %NULL if there's none 72a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * 73a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * Since: 1.1.1 74a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch */ 75563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark signals[CURRENT_TOPLEVEL] = 76563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark g_signal_new("current-toplevel", 77563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark G_OBJECT_CLASS_TYPE(object_class), 78563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark G_SIGNAL_RUN_LAST, 79563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark G_STRUCT_OFFSET(WebKitSoupAuthDialogClass, current_toplevel), 80563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NULL, NULL, 81563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark webkit_marshal_OBJECT__OBJECT, 82563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GTK_TYPE_WIDGET, 1, 83563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark SOUP_TYPE_MESSAGE); 84563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 85563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 86563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic void webkit_soup_auth_dialog_init(WebKitSoupAuthDialog* instance) 87563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 88563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 89563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 90563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic void webkit_soup_auth_dialog_session_feature_init(SoupSessionFeatureInterface *feature_interface, 91563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gpointer interface_data) 92563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 93563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark feature_interface->attach = attach; 94563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark feature_interface->detach = detach; 95563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 96563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 97563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarktypedef struct _WebKitAuthData { 98563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark SoupMessage* msg; 99563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark SoupAuth* auth; 100563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark SoupSession* session; 101563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark SoupSessionFeature* manager; 102563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* loginEntry; 103563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* passwordEntry; 104563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* checkButton; 1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch char *username; 1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch char *password; 107563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} WebKitAuthData; 108563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 109563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic void free_authData(WebKitAuthData* authData) 110563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 111563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark g_object_unref(authData->msg); 1120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch g_free(authData->username); 1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch g_free(authData->password); 114563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark g_slice_free(WebKitAuthData, authData); 115563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 116563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 117231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#ifdef SOUP_TYPE_PASSWORD_MANAGER 1180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void save_password_callback(SoupMessage* msg, WebKitAuthData* authData) 119563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 120231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block /* Anything but 401 and 5xx means the password was accepted */ 121231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (msg->status_code != 401 && msg->status_code < 500) 122231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block soup_auth_save_password(authData->auth, authData->username, authData->password); 123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block /* Disconnect the callback. If the authentication succeeded we are 125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * done, and if it failed we'll create a new authData and we'll 126231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * connect to 'got-headers' again in response_callback */ 127231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block g_signal_handlers_disconnect_by_func(msg, save_password_callback, authData); 128231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch free_authData(authData); 1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 131563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#endif 132563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void response_callback(GtkDialog* dialog, gint response_id, WebKitAuthData* authData) 1340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 135231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gboolean freeAuthData = TRUE; 136231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (response_id == GTK_RESPONSE_OK) { 1380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch authData->username = g_strdup(gtk_entry_get_text(GTK_ENTRY(authData->loginEntry))); 1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch authData->password = g_strdup(gtk_entry_get_text(GTK_ENTRY(authData->passwordEntry))); 140231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch soup_auth_authenticate(authData->auth, authData->username, authData->password); 142563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 143231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#ifdef SOUP_TYPE_PASSWORD_MANAGER 144231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (authData->checkButton && 145231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(authData->checkButton))) { 1460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch g_signal_connect(authData->msg, "got-headers", G_CALLBACK(save_password_callback), authData); 147231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block freeAuthData = FALSE; 148231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 149563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#endif 150563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 151563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 152563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark soup_session_unpause_message(authData->session, authData->msg); 153231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (freeAuthData) 154231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block free_authData(authData); 155563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_widget_destroy(GTK_WIDGET(dialog)); 156563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 157563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 158563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic GtkWidget * 159231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blocktable_add_entry(GtkWidget* table, 160231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block int row, 161231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block const char* label_text, 162231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block const char* value, 163231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gpointer user_data) 164563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 165563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* entry; 166563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* label; 167563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 168563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark label = gtk_label_new(label_text); 169563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); 170563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 171563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark entry = gtk_entry_new(); 172563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); 173563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 174563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (value) 175563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_entry_set_text(GTK_ENTRY(entry), value); 176563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 177563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_table_attach(GTK_TABLE(table), label, 178563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 0, 1, row, row + 1, 179563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); 180563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_table_attach_defaults(GTK_TABLE(table), entry, 181563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 1, 2, row, row + 1); 182563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 183563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return entry; 184563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 185563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 186231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic gboolean session_can_save_passwords(SoupSession* session) 187231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#ifdef SOUP_TYPE_PASSWORD_MANAGER 189231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return soup_session_get_feature(session, SOUP_TYPE_PASSWORD_MANAGER) != NULL; 190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#else 191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return FALSE; 192231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 193231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 195563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic void show_auth_dialog(WebKitAuthData* authData, const char* login, const char* password) 196563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 197563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* toplevel; 198563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* widget; 199563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkDialog* dialog; 200563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWindow* window; 201563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* entryContainer; 202563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* hbox; 203563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* mainVBox; 204563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* vbox; 205563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* icon; 206563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* table; 207dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GtkWidget* serverMessageDescriptionLabel; 208dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GtkWidget* serverMessageLabel; 209dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GtkWidget* descriptionLabel; 210dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block char* description; 211dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block const char* realm; 212dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gboolean hasRealm; 213563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark SoupURI* uri; 214563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* rememberBox; 215563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GtkWidget* checkButton; 216563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 217563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark /* From GTK+ gtkmountoperation.c, modified and simplified. LGPL 2 license */ 218563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 219563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark widget = gtk_dialog_new(); 220563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark window = GTK_WINDOW(widget); 221563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark dialog = GTK_DIALOG(widget); 222563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 223563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_dialog_add_buttons(dialog, 224563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 225563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GTK_STOCK_OK, GTK_RESPONSE_OK, 226563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NULL); 227563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 228563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark /* Set the dialog up with HIG properties */ 229231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gtk_container_set_border_width(GTK_CONTAINER(dialog), 5); 230ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(dialog)), 2); /* 2 * 5 + 2 = 12 */ 231ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_action_area(dialog)), 5); 232ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_action_area(dialog)), 6); 233563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 234563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_window_set_resizable(window, FALSE); 235563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_window_set_title(window, ""); 236563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_window_set_icon_name(window, GTK_STOCK_DIALOG_AUTHENTICATION); 237563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 238563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_dialog_set_default_response(dialog, GTK_RESPONSE_OK); 239563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 240563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark /* Get the current toplevel */ 241563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark g_signal_emit(authData->manager, signals[CURRENT_TOPLEVEL], 0, authData->msg, &toplevel); 242563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 243563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (toplevel) 244563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_window_set_transient_for(window, GTK_WINDOW(toplevel)); 245563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 246563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark /* Build contents */ 247563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark hbox = gtk_hbox_new(FALSE, 12); 248563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); 249ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(dialog)), hbox, TRUE, TRUE, 0); 250563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 251563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_AUTHENTICATION, 252563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark GTK_ICON_SIZE_DIALOG); 253563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 254563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_misc_set_alignment(GTK_MISC(icon), 0.5, 0.0); 255563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 0); 256563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 257563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark mainVBox = gtk_vbox_new(FALSE, 18); 258563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_box_pack_start(GTK_BOX(hbox), mainVBox, TRUE, TRUE, 0); 259563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 260563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark uri = soup_message_get_uri(authData->msg); 261dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block description = g_strdup_printf(_("A username and password are being requested by the site %s"), uri->host); 262dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block descriptionLabel = gtk_label_new(description); 263dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block g_free(description); 264dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_misc_set_alignment(GTK_MISC(descriptionLabel), 0.0, 0.5); 265dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_label_set_line_wrap(GTK_LABEL(descriptionLabel), TRUE); 266dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_box_pack_start(GTK_BOX(mainVBox), GTK_WIDGET(descriptionLabel), 267563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark FALSE, FALSE, 0); 268563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 269563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark vbox = gtk_vbox_new(FALSE, 6); 270231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gtk_box_pack_start(GTK_BOX(mainVBox), vbox, FALSE, FALSE, 0); 271563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 272563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark /* The table that holds the entries */ 273563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark entryContainer = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); 274563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 275563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_alignment_set_padding(GTK_ALIGNMENT(entryContainer), 276563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 0, 0, 0, 0); 277563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 278563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_box_pack_start(GTK_BOX(vbox), entryContainer, 279563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark FALSE, FALSE, 0); 280563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 281dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block realm = soup_auth_get_realm(authData->auth); 282dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Checking that realm is not an empty string 283dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block hasRealm = (realm && (strlen(realm) > 0)); 284dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 285dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block table = gtk_table_new(hasRealm ? 3 : 2, 2, FALSE); 286231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gtk_table_set_col_spacings(GTK_TABLE(table), 12); 287231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gtk_table_set_row_spacings(GTK_TABLE(table), 6); 288563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_container_add(GTK_CONTAINER(entryContainer), table); 289563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 290dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (hasRealm) { 291dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block serverMessageDescriptionLabel = gtk_label_new(_("Server message:")); 292dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block serverMessageLabel = gtk_label_new(realm); 293dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_misc_set_alignment(GTK_MISC(serverMessageDescriptionLabel), 0.0, 0.5); 294dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_label_set_line_wrap(GTK_LABEL(serverMessageDescriptionLabel), TRUE); 295dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_misc_set_alignment(GTK_MISC(serverMessageLabel), 0.0, 0.5); 296dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_label_set_line_wrap(GTK_LABEL(serverMessageLabel), TRUE); 297dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 298dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_table_attach_defaults(GTK_TABLE(table), serverMessageDescriptionLabel, 299dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 0, 1, 0, 1); 300dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_table_attach_defaults(GTK_TABLE(table), serverMessageLabel, 301dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1, 2, 0, 1); 302dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 303dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 304dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block authData->loginEntry = table_add_entry(table, hasRealm ? 1 : 0, _("Username:"), 305563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark login, NULL); 306dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block authData->passwordEntry = table_add_entry(table, hasRealm ? 2 : 1, _("Password:"), 307563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark password, NULL); 308563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 309563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_entry_set_visibility(GTK_ENTRY(authData->passwordEntry), FALSE); 310563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 311231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (session_can_save_passwords(authData->session)) { 312231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block rememberBox = gtk_vbox_new(FALSE, 6); 313231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gtk_box_pack_start(GTK_BOX(vbox), rememberBox, 314231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block FALSE, FALSE, 0); 315231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block checkButton = gtk_check_button_new_with_mnemonic(_("_Remember password")); 316231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (login && password) 317231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkButton), TRUE); 318231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gtk_label_set_line_wrap(GTK_LABEL(gtk_bin_get_child(GTK_BIN(checkButton))), TRUE); 319231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gtk_box_pack_start(GTK_BOX(rememberBox), checkButton, FALSE, FALSE, 0); 320231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block authData->checkButton = checkButton; 321231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 322563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 323563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark g_signal_connect(dialog, "response", G_CALLBACK(response_callback), authData); 324563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark gtk_widget_show_all(widget); 325563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 326563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 327563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic void session_authenticate(SoupSession* session, SoupMessage* msg, SoupAuth* auth, gboolean retrying, gpointer user_data) 328563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 329563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark SoupURI* uri; 330563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark WebKitAuthData* authData; 331563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark SoupSessionFeature* manager = (SoupSessionFeature*)user_data; 332231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#ifdef SOUP_TYPE_PASSWORD_MANAGER 333231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block GSList* users; 334231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 335231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block const char *login, *password; 336563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 337563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark soup_session_pause_message(session, msg); 338563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark /* We need to make sure the message sticks around when pausing it */ 339563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark g_object_ref(msg); 340563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 341563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark uri = soup_message_get_uri(msg); 342231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block authData = g_slice_new0(WebKitAuthData); 343563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark authData->msg = msg; 344563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark authData->auth = auth; 345563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark authData->session = session; 346563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark authData->manager = manager; 347563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 348231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block login = password = NULL; 349231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 350231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#ifdef SOUP_TYPE_PASSWORD_MANAGER 351231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block users = soup_auth_get_saved_users(auth); 352231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (users) { 353231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block login = users->data; 354231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block password = soup_auth_get_saved_password(auth, login); 355231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block g_slist_free(users); 356231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 357563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#endif 358231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 359231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block show_auth_dialog(authData, login, password); 360563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 361563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 362563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic void attach(SoupSessionFeature* manager, SoupSession* session) 363563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 364563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark g_signal_connect(session, "authenticate", G_CALLBACK(session_authenticate), manager); 365563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 366563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 367563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic void detach(SoupSessionFeature* manager, SoupSession* session) 368563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 369563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark g_signal_handlers_disconnect_by_func(session, session_authenticate, manager); 370563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 371563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 372563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 373