1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 /* e-book-auth-util.c - Lame helper to load addressbooks with authentication.
5 * Copyright (C) 2005 Novell, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU Lesser General Public
9 * License as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
21 * Authors: Hans Petter Jansson <hpj@novell.com>
23 * Mostly taken from Evolution's addressbook/gui/component/addressbook.c
28 #include <gtk/gtkmessagedialog.h>
29 #include <glib/gi18n-lib.h>
30 #include <libebook/e-book.h>
31 #include <libedataserverui/e-passwords.h>
32 #include "libedataserver/e-url.h"
33 #include "e-book-auth-util.h"
35 static void addressbook_authenticate (EBook *book, gboolean previous_failure,
36 ESource *source, EBookCallback cb, gpointer closure);
37 static void auth_required_cb (EBook *book, gpointer data);
42 EBookCallback open_func;
43 gpointer open_func_data;
47 free_load_source_data (LoadSourceData *data)
50 g_object_unref (data->source);
52 g_signal_handlers_disconnect_by_func (data->book, auth_required_cb, NULL);
53 g_object_unref (data->book);
59 remove_parameters_from_uri (const gchar *uri)
64 euri = e_uri_new (uri);
65 euri_str = e_uri_to_string (euri, FALSE);
71 load_source_auth_cb (EBook *book, EBookStatus status, gpointer closure)
73 LoadSourceData *data = closure;
75 if (status != E_BOOK_ERROR_OK) {
76 /* the user clicked cancel in the password dialog */
77 if (status == E_BOOK_ERROR_CANCELLED) {
78 if (e_book_check_static_capability (book, "anon-access")) {
81 /* XXX "LDAP" has to be removed from the folowing message
82 so that it wil valid for other servers which provide
85 dialog = gtk_message_dialog_new (NULL,
89 _("Accessing LDAP Server anonymously"));
90 g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
91 gtk_widget_show (dialog);
93 data->open_func (book, E_BOOK_ERROR_OK, data->open_func_data);
94 free_load_source_data (data);
97 } else if (status == E_BOOK_ERROR_INVALID_SERVER_VERSION) {
99 e_error_run (NULL, "addressbook:server-version", NULL);
101 status = E_BOOK_ERROR_OK;
103 data->open_func (book, status, data->open_func_data);
104 free_load_source_data (data);
107 const gchar *uri = e_book_get_uri (book);
108 gchar *stripped_uri = remove_parameters_from_uri (uri);
109 const gchar *auth_domain = e_source_get_property (data->source, "auth-domain");
110 const gchar *component_name;
112 component_name = auth_domain ? auth_domain : "Addressbook";
114 e_passwords_forget_password (component_name, stripped_uri);
115 addressbook_authenticate (book, TRUE, data->source, load_source_auth_cb, closure);
117 g_free (stripped_uri);
124 data->open_func (book, status, data->open_func_data);
126 free_load_source_data (data);
130 get_remember_password (ESource *source)
134 value = e_source_get_property (source, "remember_password");
135 if (value && !g_ascii_strcasecmp (value, "true"))
142 set_remember_password (ESource *source, gboolean value)
144 e_source_set_property (source, "remember_password",
145 value ? "true" : "false");
149 addressbook_authenticate (EBook *book, gboolean previous_failure, ESource *source,
150 EBookCallback cb, gpointer closure)
154 const gchar *component_name;
155 const char *password = NULL;
156 char *pass_dup = NULL;
157 const gchar *uri = e_book_get_uri (book);
158 gchar *stripped_uri = remove_parameters_from_uri (uri);
159 const gchar *auth_domain = e_source_get_property (source, "auth-domain");
161 component_name = auth_domain ? auth_domain : "Addressbook";
164 password = e_passwords_get_password (component_name, uri);
166 auth = e_source_get_property (source, "auth");
168 if (auth && !strcmp ("ldap/simple-binddn", auth)) {
169 user = e_source_get_property (source, "binddn");
171 else if (auth && !strcmp ("plain/password", auth)) {
172 user = e_source_get_property (source, "user");
174 user = e_source_get_property (source, "username");
178 user = e_source_get_property (source, "email_addr");
185 char *password_prompt;
188 guint32 flags = E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET|E_PASSWORDS_ONLINE;
190 if (previous_failure) {
191 failed_auth = _("Failed to authenticate.\n");
192 flags |= E_PASSWORDS_REPROMPT;
198 password_prompt = g_strdup_printf (_("Enter password for %s (user %s)"),
199 e_source_peek_name (source), user);
201 prompt = g_strconcat (failed_auth, password_prompt, NULL);
202 g_free (password_prompt);
204 remember = get_remember_password (source);
205 pass_dup = e_passwords_ask_password (prompt, component_name, uri, prompt,
208 if (remember != get_remember_password (source))
209 set_remember_password (source, remember);
214 if (password || pass_dup) {
215 e_book_async_authenticate_user (book, user, password ? password : pass_dup,
216 e_source_get_property (source, "auth"),
221 /* they hit cancel */
222 cb (book, E_BOOK_ERROR_CANCELLED, closure);
225 g_free (stripped_uri);
229 auth_required_cb (EBook *book, gpointer data)
231 LoadSourceData *load_source_data = g_new0 (LoadSourceData, 1);
233 load_source_data->source = g_object_ref (g_object_ref (e_book_get_source (book)));
235 addressbook_authenticate (book, FALSE, load_source_data->source,
236 load_source_auth_cb, load_source_data);
240 load_source_cb (EBook *book, EBookStatus status, gpointer closure)
242 LoadSourceData *load_source_data = closure;
244 if (status == E_BOOK_ERROR_OK && book != NULL) {
247 auth = e_source_get_property (load_source_data->source, "auth");
248 if (auth && strcmp (auth, "none")) {
249 g_signal_connect (book, "auth_required", (GCallback) auth_required_cb, NULL);
251 if (e_book_is_online (book)) {
252 addressbook_authenticate (book, FALSE, load_source_data->source,
253 load_source_auth_cb, closure);
259 if (load_source_data->open_func)
260 load_source_data->open_func (book, status, load_source_data->open_func_data);
262 free_load_source_data (load_source_data);
266 * e_load_book_source:
267 * @source: an #ESource
268 * @open_func: a function to call when the operation finishes, or %NULL
269 * @user_data: data to pass to callback function
271 * Creates a new #EBook specified by @source, and starts a non-blocking
272 * open operation on it. If the book requires authorization, presents
273 * a window asking the user for such.
275 * When the operation finishes, calls the callback function indicating
276 * if it succeeded or not. If you don't care, you can pass %NULL for
277 * @open_func, and no action will be taken on completion.
279 * Return value: A new #EBook that is being opened.
282 e_load_book_source (ESource *source, EBookCallback open_func, gpointer user_data)
285 LoadSourceData *load_source_data = g_new0 (LoadSourceData, 1);
287 load_source_data->source = g_object_ref (source);
288 load_source_data->open_func = open_func;
289 load_source_data->open_func_data = user_data;
291 book = e_book_new (source, NULL);
295 load_source_data->book = book;
297 e_book_async_open (book, FALSE, load_source_cb, load_source_data);