~ubuntu-branches/ubuntu/wily/evolution-data-server/wily

« back to all changes in this revision

Viewing changes to libebackend/e-server-side-source.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2015-07-20 13:34:59 UTC
  • mfrom: (1.1.126) (1.2.48 sid)
  • Revision ID: package-import@ubuntu.com-20150720133459-g6y46hnu5ewtoz08
Tags: 3.16.4-0ubuntu2
debian/patches/0001-Bug-752373-Monthly-events-do-not-recur-correctly.patch:
Cherry-pick patch from upstream to fix events not recurring correctly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * e-server-side-source.c
3
3
 *
4
 
 * This library is free software you can redistribute it and/or modify it
 
4
 * This library is free software: you can redistribute it and/or modify it
5
5
 * under the terms of the GNU Lesser General Public License as published by
6
6
 * the Free Software Foundation.
7
7
 *
8
8
 * This library is distributed in the hope that it will be useful, but
9
9
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
 
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 
10
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
11
 * for more details.
12
12
 *
13
13
 * You should have received a copy of the GNU Lesser General Public License
14
 
 * along with this library; if not, see <http://www.gnu.org/licenses/>.
 
14
 * along with this library. If not, see <http://www.gnu.org/licenses/>.
15
15
 *
16
16
 */
17
17
 
27
27
#include "e-server-side-source.h"
28
28
 
29
29
#include <config.h>
 
30
#include <stdio.h>
30
31
#include <glib/gi18n-lib.h>
31
32
 
32
33
/* Private D-Bus classes. */
52
53
        /* For comparison. */
53
54
        gchar *file_contents;
54
55
 
55
 
        gboolean allow_auth_prompt;
56
 
        GType auth_session_type;
57
56
        gchar *write_directory;
 
57
 
 
58
        GMutex last_values_lock;
 
59
        gchar *last_reason;
 
60
        gchar *last_certificate_pem;
 
61
        gchar *last_certificate_errors;
 
62
        gchar *last_dbus_error_name;
 
63
        gchar *last_dbus_error_message;
 
64
        ENamedParameters *last_credentials;
 
65
 
 
66
        GMutex pending_credentials_lookup_lock;
 
67
        GCancellable *pending_credentials_lookup;
58
68
};
59
69
 
60
70
struct _AsyncContext {
66
76
 
67
77
enum {
68
78
        PROP_0,
69
 
        PROP_ALLOW_AUTH_PROMPT,
70
 
        PROP_AUTH_SESSION_TYPE,
71
79
        PROP_EXPORTED,
72
80
        PROP_FILE,
73
81
        PROP_OAUTH2_SUPPORT,
192
200
        return FALSE;
193
201
}
194
202
 
195
 
static gboolean
196
 
server_side_source_allow_auth_prompt_cb (EDBusSource *dbus_interface,
197
 
                                         GDBusMethodInvocation *invocation,
198
 
                                         EServerSideSource *source)
199
 
{
200
 
        e_server_side_source_set_allow_auth_prompt (source, TRUE);
201
 
 
202
 
        e_dbus_source_complete_allow_auth_prompt (dbus_interface, invocation);
 
203
static ESourceCredentialsReason
 
204
server_side_source_credentials_reason_from_text (const gchar *arg_reason)
 
205
{
 
206
        ESourceCredentialsReason reason = E_SOURCE_CREDENTIALS_REASON_UNKNOWN;
 
207
 
 
208
        if (arg_reason && *arg_reason) {
 
209
                GEnumClass *enum_class;
 
210
                GEnumValue *enum_value;
 
211
 
 
212
                enum_class = g_type_class_ref (E_TYPE_SOURCE_CREDENTIALS_REASON);
 
213
                enum_value = g_enum_get_value_by_nick (enum_class, arg_reason);
 
214
 
 
215
                if (enum_value) {
 
216
                        reason = enum_value->value;
 
217
                } else {
 
218
                        g_warning ("%s: Unknown reason enum: '%s'", G_STRFUNC, arg_reason);
 
219
                }
 
220
 
 
221
                g_type_class_unref (enum_class);
 
222
        }
 
223
 
 
224
        return reason;
 
225
}
 
226
 
 
227
typedef struct _ReinvokeCredentialsRequiredData {
 
228
        EServerSideSource *source;
 
229
        gchar *arg_reason;
 
230
        gchar *arg_certificate_pem;
 
231
        gchar *arg_certificate_errors;
 
232
        gchar *arg_dbus_error_name;
 
233
        gchar *arg_dbus_error_message;
 
234
} ReinvokeCredentialsRequiredData;
 
235
 
 
236
static void
 
237
reinvoke_credentials_required_data_free (gpointer ptr)
 
238
{
 
239
        ReinvokeCredentialsRequiredData *data = ptr;
 
240
 
 
241
        if (data) {
 
242
                g_clear_object (&data->source);
 
243
                g_free (data->arg_reason);
 
244
                g_free (data->arg_certificate_pem);
 
245
                g_free (data->arg_certificate_errors);
 
246
                g_free (data->arg_dbus_error_name);
 
247
                g_free (data->arg_dbus_error_message);
 
248
                g_free (data);
 
249
        }
 
250
}
 
251
 
 
252
static void server_side_source_credentials_lookup_cb (GObject *source_object, GAsyncResult *result, gpointer user_data);
 
253
 
 
254
static gboolean
 
255
server_side_source_invoke_credentials_required_cb (EDBusSource *dbus_interface,
 
256
                                                   GDBusMethodInvocation *invocation,
 
257
                                                   const gchar *arg_reason,
 
258
                                                   const gchar *arg_certificate_pem,
 
259
                                                   const gchar *arg_certificate_errors,
 
260
                                                   const gchar *arg_dbus_error_name,
 
261
                                                   const gchar *arg_dbus_error_message,
 
262
                                                   EServerSideSource *source)
 
263
{
 
264
        gboolean skip_emit = FALSE;
 
265
 
 
266
        if (invocation)
 
267
                e_dbus_source_complete_invoke_credentials_required (dbus_interface, invocation);
 
268
 
 
269
        g_mutex_lock (&source->priv->pending_credentials_lookup_lock);
 
270
        if (source->priv->pending_credentials_lookup) {
 
271
                g_cancellable_cancel (source->priv->pending_credentials_lookup);
 
272
                g_clear_object (&source->priv->pending_credentials_lookup);
 
273
        }
 
274
        g_mutex_unlock (&source->priv->pending_credentials_lookup_lock);
 
275
 
 
276
        g_mutex_lock (&source->priv->last_values_lock);
 
277
 
 
278
        g_free (source->priv->last_reason);
 
279
        g_free (source->priv->last_certificate_pem);
 
280
        g_free (source->priv->last_certificate_errors);
 
281
        g_free (source->priv->last_dbus_error_name);
 
282
        g_free (source->priv->last_dbus_error_message);
 
283
        source->priv->last_reason = g_strdup (arg_reason);
 
284
        source->priv->last_certificate_pem = g_strdup (arg_certificate_pem);
 
285
        source->priv->last_certificate_errors = g_strdup (arg_certificate_errors);
 
286
        source->priv->last_dbus_error_name = g_strdup (arg_dbus_error_name);
 
287
        source->priv->last_dbus_error_message = g_strdup (arg_dbus_error_message);
 
288
 
 
289
        g_mutex_unlock (&source->priv->last_values_lock);
 
290
 
 
291
        /* Do not bother clients, when the password is stored. */
 
292
        if (server_side_source_credentials_reason_from_text (arg_reason) == E_SOURCE_CREDENTIALS_REASON_REQUIRED) {
 
293
                ESourceRegistryServer *server;
 
294
                ESourceCredentialsProvider *credentials_provider;
 
295
 
 
296
                server = e_server_side_source_get_server (source);
 
297
                credentials_provider = server ? e_source_registry_server_ref_credentials_provider (server) : NULL;
 
298
 
 
299
                if (credentials_provider) {
 
300
                        ReinvokeCredentialsRequiredData *data;
 
301
                        GCancellable *cancellable;
 
302
 
 
303
                        g_mutex_lock (&source->priv->pending_credentials_lookup_lock);
 
304
                        if (source->priv->pending_credentials_lookup) {
 
305
                                g_cancellable_cancel (source->priv->pending_credentials_lookup);
 
306
                                g_clear_object (&source->priv->pending_credentials_lookup);
 
307
                        }
 
308
                        cancellable = g_cancellable_new ();
 
309
                        source->priv->pending_credentials_lookup = g_object_ref (cancellable);
 
310
                        g_mutex_unlock (&source->priv->pending_credentials_lookup_lock);
 
311
 
 
312
                        data = g_new0 (ReinvokeCredentialsRequiredData, 1);
 
313
                        data->source = g_object_ref (source);
 
314
                        data->arg_reason = g_strdup (arg_reason);
 
315
                        data->arg_certificate_pem = g_strdup (arg_certificate_pem);
 
316
                        data->arg_certificate_errors = g_strdup (arg_certificate_errors);
 
317
                        data->arg_dbus_error_name = g_strdup (arg_dbus_error_name);
 
318
                        data->arg_dbus_error_message = g_strdup (arg_dbus_error_message);
 
319
 
 
320
                        skip_emit = TRUE;
 
321
 
 
322
                        e_source_credentials_provider_lookup (credentials_provider, E_SOURCE (source),
 
323
                                cancellable, server_side_source_credentials_lookup_cb, data);
 
324
 
 
325
                        g_object_unref (cancellable);
 
326
                }
 
327
 
 
328
                g_clear_object (&credentials_provider);
 
329
        }
 
330
 
 
331
        if (!skip_emit) {
 
332
                e_dbus_source_emit_credentials_required (dbus_interface, arg_reason, arg_certificate_pem, arg_certificate_errors, arg_dbus_error_name, arg_dbus_error_message);
 
333
        }
 
334
 
 
335
        return TRUE;
 
336
}
 
337
 
 
338
static gboolean
 
339
server_side_source_invoke_authenticate_cb (EDBusSource *dbus_interface,
 
340
                                           GDBusMethodInvocation *invocation,
 
341
                                           const gchar * const *arg_credentials,
 
342
                                           EServerSideSource *source)
 
343
{
 
344
        gchar **last_credentials_strv = NULL;
 
345
 
 
346
        g_return_val_if_fail (E_IS_SERVER_SIDE_SOURCE (source), TRUE);
 
347
 
 
348
        g_mutex_lock (&source->priv->pending_credentials_lookup_lock);
 
349
        if (source->priv->pending_credentials_lookup) {
 
350
                g_cancellable_cancel (source->priv->pending_credentials_lookup);
 
351
                g_clear_object (&source->priv->pending_credentials_lookup);
 
352
        }
 
353
        g_mutex_unlock (&source->priv->pending_credentials_lookup_lock);
 
354
 
 
355
        g_mutex_lock (&source->priv->last_values_lock);
 
356
 
 
357
        /* Empty credentials are used to use the last credentials instead */
 
358
        if (source->priv->last_credentials && arg_credentials && !arg_credentials[0]) {
 
359
                last_credentials_strv = e_named_parameters_to_strv (source->priv->last_credentials);
 
360
                arg_credentials = (const gchar * const *) last_credentials_strv;
 
361
        } else if (arg_credentials && arg_credentials[0]) {
 
362
                ENamedParameters *credentials = e_named_parameters_new_strv (arg_credentials);
 
363
 
 
364
                /* If only one credential value is passed in, and it's the SSL Trust,
 
365
                   and there was any credentials already tried, then merge the previous
 
366
                   credentials with the SSL Trust, to inherit the password, if any. */
 
367
                if (source->priv->last_credentials &&
 
368
                    e_named_parameters_count (credentials) == 1 &&
 
369
                    e_named_parameters_exists (credentials, E_SOURCE_CREDENTIAL_SSL_TRUST)) {
 
370
                        gint ii, count;
 
371
 
 
372
                        count = e_named_parameters_count (source->priv->last_credentials);
 
373
                        for (ii = 0; ii < count; ii++) {
 
374
                                gchar *name;
 
375
 
 
376
                                name = e_named_parameters_get_name (source->priv->last_credentials, ii);
 
377
                                if (!name)
 
378
                                        continue;
 
379
 
 
380
                                if (*name && !e_named_parameters_exists (credentials, name)) {
 
381
                                        e_named_parameters_set (credentials, name,
 
382
                                                e_named_parameters_get (source->priv->last_credentials, name));
 
383
                                }
 
384
 
 
385
                                g_free (name);
 
386
                        }
 
387
 
 
388
                        last_credentials_strv = e_named_parameters_to_strv (credentials);
 
389
                        arg_credentials = (const gchar * const *) last_credentials_strv;
 
390
                }
 
391
 
 
392
                e_named_parameters_free (source->priv->last_credentials);
 
393
                source->priv->last_credentials = credentials;
 
394
        }
 
395
 
 
396
        g_free (source->priv->last_reason);
 
397
        g_free (source->priv->last_certificate_pem);
 
398
        g_free (source->priv->last_certificate_errors);
 
399
        g_free (source->priv->last_dbus_error_name);
 
400
        g_free (source->priv->last_dbus_error_message);
 
401
        source->priv->last_reason = NULL;
 
402
        source->priv->last_certificate_pem = NULL;
 
403
        source->priv->last_certificate_errors = NULL;
 
404
        source->priv->last_dbus_error_name = NULL;
 
405
        source->priv->last_dbus_error_message = NULL;
 
406
 
 
407
        g_mutex_unlock (&source->priv->last_values_lock);
 
408
 
 
409
        if (invocation)
 
410
                e_dbus_source_complete_invoke_authenticate (dbus_interface, invocation);
 
411
 
 
412
        e_dbus_source_emit_authenticate (dbus_interface, arg_credentials);
 
413
 
 
414
        g_strfreev (last_credentials_strv);
 
415
 
 
416
        return TRUE;
 
417
}
 
418
 
 
419
static void
 
420
server_side_source_credentials_lookup_cb (GObject *source_object,
 
421
                                          GAsyncResult *result,
 
422
                                          gpointer user_data)
 
423
{
 
424
        GDBusObject *dbus_object;
 
425
        EDBusSource *dbus_source;
 
426
        ReinvokeCredentialsRequiredData *data = user_data;
 
427
        ENamedParameters *credentials = NULL;
 
428
        gboolean success;
 
429
        GError *error = NULL;
 
430
 
 
431
        g_return_if_fail (E_IS_SOURCE_CREDENTIALS_PROVIDER (source_object));
 
432
        g_return_if_fail (data != NULL);
 
433
 
 
434
        success = e_source_credentials_provider_lookup_finish (E_SOURCE_CREDENTIALS_PROVIDER (source_object), result, &credentials, &error);
 
435
 
 
436
        dbus_object = e_source_ref_dbus_object (E_SOURCE (data->source));
 
437
        if (!dbus_object) {
 
438
                e_named_parameters_free (credentials);
 
439
                reinvoke_credentials_required_data_free (data);
 
440
                return;
 
441
        }
 
442
 
 
443
        dbus_source = e_dbus_object_get_source (E_DBUS_OBJECT (dbus_object));
 
444
        if (!dbus_source) {
 
445
                e_named_parameters_free (credentials);
 
446
                g_clear_object (&dbus_object);
 
447
                reinvoke_credentials_required_data_free (data);
 
448
                return;
 
449
        }
 
450
 
 
451
        if (success && credentials) {
 
452
                gchar **arg_credentials;
 
453
 
 
454
                arg_credentials = e_named_parameters_to_strv (credentials);
 
455
 
 
456
                server_side_source_invoke_authenticate_cb (dbus_source, NULL,
 
457
                        (const gchar * const *) arg_credentials, data->source);
 
458
 
 
459
                g_strfreev (arg_credentials);
 
460
        } else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
 
461
                if (error) {
 
462
                        printf ("%s: Failed to lookup password: %s\n", G_STRFUNC, error ? error->message : "Unknown error");
 
463
                        fflush (stdout);
 
464
                }
 
465
 
 
466
                if (server_side_source_credentials_reason_from_text (data->arg_reason) == E_SOURCE_CREDENTIALS_REASON_REQUIRED &&
 
467
                    error && !e_source_credentials_provider_can_prompt (E_SOURCE_CREDENTIALS_PROVIDER (source_object), E_SOURCE (data->source))) {
 
468
                        GEnumClass *enum_class;
 
469
                        GEnumValue *enum_value;
 
470
                        gchar *dbus_error_name;
 
471
 
 
472
                        enum_class = g_type_class_ref (E_TYPE_SOURCE_CREDENTIALS_REASON);
 
473
                        enum_value = g_enum_get_value (enum_class, E_SOURCE_CREDENTIALS_REASON_ERROR);
 
474
 
 
475
                        g_return_if_fail (enum_value != NULL);
 
476
 
 
477
                        dbus_error_name = g_dbus_error_encode_gerror (error);
 
478
 
 
479
                        /* Use error reason when the source cannot be prompted for credentials */
 
480
                        e_dbus_source_emit_credentials_required (dbus_source, enum_value->value_nick,
 
481
                                data->arg_certificate_pem, data->arg_certificate_errors, dbus_error_name, error->message);
 
482
 
 
483
                        g_type_class_unref (enum_class);
 
484
                        g_free (dbus_error_name);
 
485
                } else {
 
486
                        /* Reinvoke for clients only, if not cancelled */
 
487
                        const gchar *arg_dbus_error_name, *arg_dbus_error_message;
 
488
                        gchar *dbus_error_name = NULL;
 
489
 
 
490
                        arg_dbus_error_name = data->arg_dbus_error_name;
 
491
                        arg_dbus_error_message = data->arg_dbus_error_message;
 
492
 
 
493
                        if (!arg_dbus_error_name || !*arg_dbus_error_name) {
 
494
                                if (!error)
 
495
                                        error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED, _("Unknown error"));
 
496
 
 
497
                                dbus_error_name = g_dbus_error_encode_gerror (error);
 
498
                                arg_dbus_error_name = dbus_error_name;
 
499
                                arg_dbus_error_message = error->message;
 
500
                        }
 
501
 
 
502
                        e_dbus_source_emit_credentials_required (dbus_source, data->arg_reason,
 
503
                                data->arg_certificate_pem, data->arg_certificate_errors,
 
504
                                arg_dbus_error_name, arg_dbus_error_message);
 
505
 
 
506
                        g_free (dbus_error_name);
 
507
                }
 
508
        }
 
509
 
 
510
        e_named_parameters_free (credentials);
 
511
        reinvoke_credentials_required_data_free (data);
 
512
        g_object_unref (dbus_source);
 
513
        g_object_unref (dbus_object);
 
514
        g_clear_error (&error);
 
515
}
 
516
 
 
517
static gboolean
 
518
server_side_source_get_last_credentials_required_arguments_cb (EDBusSource *dbus_interface,
 
519
                                                               GDBusMethodInvocation *invocation,
 
520
                                                               EServerSideSource *source)
 
521
{
 
522
        g_mutex_lock (&source->priv->last_values_lock);
 
523
 
 
524
        e_dbus_source_complete_get_last_credentials_required_arguments (dbus_interface, invocation,
 
525
                source->priv->last_reason ? source->priv->last_reason : "",
 
526
                source->priv->last_certificate_pem ? source->priv->last_certificate_pem : "",
 
527
                source->priv->last_certificate_errors ? source->priv->last_certificate_errors : "",
 
528
                source->priv->last_dbus_error_name ? source->priv->last_dbus_error_name : "",
 
529
                source->priv->last_dbus_error_message ? source->priv->last_dbus_error_message : "");
 
530
 
 
531
        g_mutex_unlock (&source->priv->last_values_lock);
203
532
 
204
533
        return TRUE;
205
534
}
520
849
                                 GParamSpec *pspec)
521
850
{
522
851
        switch (property_id) {
523
 
                case PROP_ALLOW_AUTH_PROMPT:
524
 
                        e_server_side_source_set_allow_auth_prompt (
525
 
                                E_SERVER_SIDE_SOURCE (object),
526
 
                                g_value_get_boolean (value));
527
 
                        return;
528
 
 
529
 
                case PROP_AUTH_SESSION_TYPE:
530
 
                        e_server_side_source_set_auth_session_type (
531
 
                                E_SERVER_SIDE_SOURCE (object),
532
 
                                g_value_get_gtype (value));
533
 
                        return;
534
 
 
535
852
                case PROP_FILE:
536
853
                        server_side_source_set_file (
537
854
                                E_SERVER_SIDE_SOURCE (object),
591
908
                                 GParamSpec *pspec)
592
909
{
593
910
        switch (property_id) {
594
 
                case PROP_ALLOW_AUTH_PROMPT:
595
 
                        g_value_set_boolean (
596
 
                                value,
597
 
                                e_server_side_source_get_allow_auth_prompt (
598
 
                                E_SERVER_SIDE_SOURCE (object)));
599
 
                        return;
600
 
 
601
 
                case PROP_AUTH_SESSION_TYPE:
602
 
                        g_value_set_gtype (
603
 
                                value,
604
 
                                e_server_side_source_get_auth_session_type (
605
 
                                E_SERVER_SIDE_SOURCE (object)));
606
 
                        return;
607
 
 
608
911
                case PROP_EXPORTED:
609
912
                        g_value_set_boolean (
610
913
                                value,
679
982
 
680
983
        priv = E_SERVER_SIDE_SOURCE_GET_PRIVATE (object);
681
984
 
 
985
        g_mutex_lock (&priv->last_values_lock);
 
986
 
 
987
        g_free (priv->last_reason);
 
988
        g_free (priv->last_certificate_pem);
 
989
        g_free (priv->last_certificate_errors);
 
990
        g_free (priv->last_dbus_error_name);
 
991
        g_free (priv->last_dbus_error_message);
 
992
        priv->last_reason = NULL;
 
993
        priv->last_certificate_pem = NULL;
 
994
        priv->last_certificate_errors = NULL;
 
995
        priv->last_dbus_error_name = NULL;
 
996
        priv->last_dbus_error_message = NULL;
 
997
 
 
998
        e_named_parameters_free (priv->last_credentials);
 
999
        priv->last_credentials = NULL;
 
1000
 
 
1001
        g_mutex_unlock (&priv->last_values_lock);
 
1002
 
 
1003
        g_mutex_lock (&priv->pending_credentials_lookup_lock);
 
1004
        if (priv->pending_credentials_lookup) {
 
1005
                g_cancellable_cancel (priv->pending_credentials_lookup);
 
1006
                g_clear_object (&priv->pending_credentials_lookup);
 
1007
        }
 
1008
        g_mutex_unlock (&priv->pending_credentials_lookup_lock);
 
1009
 
682
1010
        if (priv->server != NULL) {
683
1011
                g_object_remove_weak_pointer (
684
1012
                        G_OBJECT (priv->server), &priv->server);
709
1037
        g_free (priv->write_directory);
710
1038
 
711
1039
        g_weak_ref_clear (&priv->oauth2_support);
 
1040
        g_mutex_clear (&priv->last_values_lock);
 
1041
        g_mutex_clear (&priv->pending_credentials_lookup_lock);
712
1042
 
713
1043
        /* Chain up to parent's finalize() method. */
714
1044
        G_OBJECT_CLASS (e_server_side_source_parent_class)->finalize (object);
1125
1455
}
1126
1456
 
1127
1457
static gboolean
 
1458
server_side_source_invoke_credentials_required_impl (ESource *source,
 
1459
                                                     gpointer dbus_source, /* EDBusSource * */
 
1460
                                                     const gchar *arg_reason,
 
1461
                                                     const gchar *arg_certificate_pem,
 
1462
                                                     const gchar *arg_certificate_errors,
 
1463
                                                     const gchar *arg_dbus_error_name,
 
1464
                                                     const gchar *arg_dbus_error_message,
 
1465
                                                     GCancellable *cancellable,
 
1466
                                                     GError **error)
 
1467
{
 
1468
        g_return_val_if_fail (E_DBUS_IS_SOURCE (dbus_source), FALSE);
 
1469
 
 
1470
        return server_side_source_invoke_credentials_required_cb (dbus_source, NULL,
 
1471
                arg_reason ? arg_reason : "",
 
1472
                arg_certificate_pem ? arg_certificate_pem : "",
 
1473
                arg_certificate_errors ? arg_certificate_errors : "",
 
1474
                arg_dbus_error_name ? arg_dbus_error_name : "",
 
1475
                arg_dbus_error_message ? arg_dbus_error_message : "",
 
1476
                E_SERVER_SIDE_SOURCE (source));
 
1477
}
 
1478
 
 
1479
static gboolean
 
1480
server_side_source_invoke_authenticate_impl (ESource *source,
 
1481
                                             gpointer dbus_source, /* EDBusSource * */
 
1482
                                             const gchar * const *arg_credentials,
 
1483
                                             GCancellable *cancellable,
 
1484
                                             GError **error)
 
1485
{
 
1486
        g_return_val_if_fail (E_DBUS_IS_SOURCE (dbus_source), FALSE);
 
1487
 
 
1488
        return server_side_source_invoke_authenticate_cb (dbus_source, NULL,
 
1489
                arg_credentials, E_SERVER_SIDE_SOURCE (source));
 
1490
}
 
1491
 
 
1492
static gboolean
1128
1493
server_side_source_initable_init (GInitable *initable,
1129
1494
                                  GCancellable *cancellable,
1130
1495
                                  GError **error)
1150
1515
        g_object_unref (dbus_object);
1151
1516
 
1152
1517
        g_signal_connect (
1153
 
                dbus_source, "handle-allow-auth-prompt",
1154
 
                G_CALLBACK (server_side_source_allow_auth_prompt_cb), source);
 
1518
                dbus_source, "handle-invoke-credentials-required",
 
1519
                G_CALLBACK (server_side_source_invoke_credentials_required_cb), source);
 
1520
        g_signal_connect (
 
1521
                dbus_source, "handle-invoke-authenticate",
 
1522
                G_CALLBACK (server_side_source_invoke_authenticate_cb), source);
 
1523
        g_signal_connect (
 
1524
                dbus_source, "handle-get-last-credentials-required-arguments",
 
1525
                G_CALLBACK (server_side_source_get_last_credentials_required_arguments_cb), source);
1155
1526
 
1156
1527
        g_object_unref (dbus_source);
1157
1528
 
1184
1555
        source_class->write_sync = server_side_source_write_sync;
1185
1556
        source_class->write = server_side_source_write;
1186
1557
        source_class->write_finish = server_side_source_write_finish;
1187
 
        source_class->remote_create_sync =
1188
 
                server_side_source_remote_create_sync;
1189
 
        source_class->remote_delete_sync =
1190
 
                server_side_source_remote_delete_sync;
1191
 
        source_class->get_oauth2_access_token_sync =
1192
 
                server_side_source_get_oauth2_access_token_sync;
1193
 
 
1194
 
        g_object_class_install_property (
1195
 
                object_class,
1196
 
                PROP_ALLOW_AUTH_PROMPT,
1197
 
                g_param_spec_boolean (
1198
 
                        "allow-auth-prompt",
1199
 
                        "Allow Auth Prompt",
1200
 
                        "Whether authentication sessions may "
1201
 
                        "interrupt the user for a password",
1202
 
                        TRUE,
1203
 
                        G_PARAM_READWRITE |
1204
 
                        G_PARAM_CONSTRUCT |
1205
 
                        G_PARAM_STATIC_STRINGS));
1206
 
 
1207
 
        g_object_class_install_property (
1208
 
                object_class,
1209
 
                PROP_AUTH_SESSION_TYPE,
1210
 
                g_param_spec_gtype (
1211
 
                        "auth-session-type",
1212
 
                        "Auth Session Type",
1213
 
                        "The type of authentication session "
1214
 
                        "to instantiate for this source",
1215
 
                        E_TYPE_AUTHENTICATION_SESSION,
1216
 
                        G_PARAM_READWRITE |
1217
 
                        G_PARAM_STATIC_STRINGS));
 
1558
        source_class->remote_create_sync = server_side_source_remote_create_sync;
 
1559
        source_class->remote_delete_sync = server_side_source_remote_delete_sync;
 
1560
        source_class->get_oauth2_access_token_sync = server_side_source_get_oauth2_access_token_sync;
 
1561
        source_class->invoke_credentials_required_impl = server_side_source_invoke_credentials_required_impl;
 
1562
        source_class->invoke_authenticate_impl = server_side_source_invoke_authenticate_impl;
1218
1563
 
1219
1564
        g_object_class_install_property (
1220
1565
                object_class,
1350
1695
        user_dir = e_server_side_source_get_user_dir ();
1351
1696
        source->priv->write_directory = g_strdup (user_dir);
1352
1697
 
1353
 
        source->priv->auth_session_type = E_TYPE_AUTHENTICATION_SESSION;
1354
 
 
1355
1698
        g_weak_ref_init (&source->priv->oauth2_support, NULL);
 
1699
        g_mutex_init (&source->priv->last_values_lock);
 
1700
        g_mutex_init (&source->priv->pending_credentials_lookup_lock);
1356
1701
}
1357
1702
 
1358
1703
/**
1710
2055
}
1711
2056
 
1712
2057
/**
1713
 
 * e_server_side_source_get_allow_auth_prompt:
1714
 
 * @source: an #EServerSideSource
1715
 
 *
1716
 
 * Returns whether an authentication prompt is allowed to be shown
1717
 
 * for @source.  #EAuthenticationSession will honor this setting by
1718
 
 * dismissing the session if it can't find a valid stored password.
1719
 
 *
1720
 
 * See e_server_side_source_set_allow_auth_prompt() for further
1721
 
 * discussion.
1722
 
 *
1723
 
 * Returns: whether auth prompts are allowed for @source
1724
 
 *
1725
 
 * Since: 3.6
1726
 
 **/
1727
 
gboolean
1728
 
e_server_side_source_get_allow_auth_prompt (EServerSideSource *source)
1729
 
{
1730
 
        g_return_val_if_fail (E_IS_SERVER_SIDE_SOURCE (source), FALSE);
1731
 
 
1732
 
        return source->priv->allow_auth_prompt;
1733
 
}
1734
 
 
1735
 
/**
1736
 
 * e_server_side_source_set_allow_auth_prompt:
1737
 
 * @source: an #EServerSideSource
1738
 
 * @allow_auth_prompt: whether auth prompts are allowed for @source
1739
 
 *
1740
 
 * Sets whether an authentication prompt is allowed to be shown for @source.
1741
 
 * #EAuthenticationSession will honor this setting by dismissing the session
1742
 
 * if it can't find a valid stored password.
1743
 
 *
1744
 
 * If the user declines to provide a password for @source when prompted
1745
 
 * by an #EAuthenticationSession, the #ESourceRegistryServer will set this
1746
 
 * property to %FALSE to suppress any further prompting, which would likely
1747
 
 * annoy the user.  However when an #ESourceRegistry instance is created by
1748
 
 * a client application, the first thing it does is reset this property to
1749
 
 * %TRUE for all registered data sources.  So suppressing authentication
1750
 
 * prompts is only ever temporary.
1751
 
 *
1752
 
 * Since: 3.6
1753
 
 **/
1754
 
void
1755
 
e_server_side_source_set_allow_auth_prompt (EServerSideSource *source,
1756
 
                                            gboolean allow_auth_prompt)
1757
 
{
1758
 
        g_return_if_fail (E_IS_SERVER_SIDE_SOURCE (source));
1759
 
 
1760
 
        if (source->priv->allow_auth_prompt == allow_auth_prompt)
1761
 
                return;
1762
 
 
1763
 
        source->priv->allow_auth_prompt = allow_auth_prompt;
1764
 
 
1765
 
        g_object_notify (G_OBJECT (source), "allow-auth-prompt");
1766
 
}
1767
 
 
1768
 
/**
1769
 
 * e_server_side_source_get_auth_session_type:
1770
 
 * @source: an #EServerSideSource
1771
 
 *
1772
 
 * Returns the type of authentication session to use for @source,
1773
 
 * which will get passed to e_source_registry_server_authenticate().
1774
 
 *
1775
 
 * This defaults to the #GType for #EAuthenticationSession.
1776
 
 *
1777
 
 * Returns: the type of authentication session to use for @source
1778
 
 *
1779
 
 * Since: 3.8
1780
 
 **/
1781
 
GType
1782
 
e_server_side_source_get_auth_session_type (EServerSideSource *source)
1783
 
{
1784
 
        g_return_val_if_fail (
1785
 
                E_IS_SERVER_SIDE_SOURCE (source),
1786
 
                E_TYPE_AUTHENTICATION_SESSION);
1787
 
 
1788
 
        return source->priv->auth_session_type;
1789
 
}
1790
 
 
1791
 
/**
1792
 
 * e_server_side_source_set_auth_session_type:
1793
 
 * @source: an #EServerSideSource
1794
 
 * @auth_session_type: the type of authentication session to use for @source
1795
 
 *
1796
 
 * Sets the type of authentication session to use for @source, which will
1797
 
 * get passed to e_source_registry_server_authenticate().
1798
 
 *
1799
 
 * @auth_session_type must be derived from #EAuthenticationSession, or else
1800
 
 * the function will reject the #GType with a runtime warning.
1801
 
 *
1802
 
 * This defaults to the #GType for #EAuthenticationSession.
1803
 
 *
1804
 
 * Since: 3.8
1805
 
 **/
1806
 
void
1807
 
e_server_side_source_set_auth_session_type (EServerSideSource *source,
1808
 
                                            GType auth_session_type)
1809
 
{
1810
 
        g_return_if_fail (E_IS_SERVER_SIDE_SOURCE (source));
1811
 
 
1812
 
        if (!g_type_is_a (auth_session_type, E_TYPE_AUTHENTICATION_SESSION)) {
1813
 
                g_warning (
1814
 
                        "Invalid auth session type '%s' for source '%s'",
1815
 
                        g_type_name (auth_session_type),
1816
 
                        e_source_get_display_name (E_SOURCE (source)));
1817
 
                return;
1818
 
        }
1819
 
 
1820
 
        if (auth_session_type == source->priv->auth_session_type)
1821
 
                return;
1822
 
 
1823
 
        source->priv->auth_session_type = auth_session_type;
1824
 
 
1825
 
        g_object_notify (G_OBJECT (source), "auth-session-type");
1826
 
}
1827
 
 
1828
 
/**
1829
2058
 * e_server_side_source_get_exported:
1830
2059
 * @source: an #EServerSideSource
1831
2060
 *
2205
2434
 
2206
2435
        g_object_notify (G_OBJECT (source), "oauth2-support");
2207
2436
}
2208