Add new ESource classes.
[platform/upstream/evolution-data-server.git] / libedataserver / e-source-webdav.c
1 /*
2  * e-source-webdav.c
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) version 3.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with the program; if not, see <http://www.gnu.org/licenses/>
16  *
17  */
18
19 /**
20  * SECTION: e-source-webdav
21  * @include: libedataserver/e-source-webdav.h
22  * @short_description: #ESource extension for WebDAV settings
23  *
24  * The #ESourceWebdav extension tracks settings for accessing resources
25  * on a remote WebDAV server.
26  *
27  * This class exists in libedataserver because we have several
28  * WebDAV-based backends.  Each of these backends is free to use
29  * this class directly or subclass it with additional settings.
30  * Subclasses should override the extension name.
31  *
32  * The #SoupURI is parsed into components and distributed across
33  * several other built-in extensions such as #ESourceAuthentication
34  * and #ESourceSecurity.
35  *
36  * Access the extension as follows:
37  *
38  * |[
39  *   #include <libedataserver/e-source-webdav.h>
40  *
41  *   ESourceWebdav *extension;
42  *
43  *   extension = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
44  * ]|
45  **/
46
47 #include "e-source-webdav.h"
48
49 #include <libedataserver/e-data-server-util.h>
50 #include <libedataserver/e-source-authentication.h>
51 #include <libedataserver/e-source-security.h>
52
53 #define E_SOURCE_WEBDAV_GET_PRIVATE(obj) \
54         (G_TYPE_INSTANCE_GET_PRIVATE \
55         ((obj), E_TYPE_SOURCE_WEBDAV, ESourceWebdavPrivate))
56
57 struct _ESourceWebdavPrivate {
58         GMutex *property_lock;
59         gchar *display_name;
60         gchar *email_address;
61         gchar *resource_path;
62         gboolean avoid_ifmatch;
63         gboolean calendar_auto_schedule;
64         gboolean ignore_invalid_cert;
65         SoupURI *uri;
66 };
67
68 enum {
69         PROP_0,
70         PROP_AVOID_IFMATCH,
71         PROP_CALENDAR_AUTO_SCHEDULE,
72         PROP_DISPLAY_NAME,
73         PROP_EMAIL_ADDRESS,
74         PROP_IGNORE_INVALID_CERT,
75         PROP_RESOURCE_PATH,
76         PROP_SOUP_URI
77 };
78
79 G_DEFINE_TYPE (
80         ESourceWebdav,
81         e_source_webdav,
82         E_TYPE_SOURCE_EXTENSION)
83
84 static gboolean
85 source_webdav_host_to_soup_uri (GBinding *binding,
86                                 const GValue *source_value,
87                                 GValue *target_value,
88                                 gpointer user_data)
89 {
90         GObject *target;
91         SoupURI *soup_uri;
92         const gchar *host;
93
94         host = g_value_get_string (source_value);
95
96         target = g_binding_get_target (binding);
97         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
98
99         soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
100         soup_uri_set_host (soup_uri, host);
101         g_value_take_boxed (target_value, soup_uri);
102
103         return TRUE;
104 }
105
106 static gboolean
107 source_webdav_soup_uri_to_host (GBinding *binding,
108                                 const GValue *source_value,
109                                 GValue *target_value,
110                                 gpointer user_data)
111 {
112         SoupURI *soup_uri;
113
114         soup_uri = g_value_get_boxed (source_value);
115         g_value_set_string (target_value, soup_uri->host);
116
117         return TRUE;
118 }
119
120 static gboolean
121 source_webdav_path_to_soup_uri (GBinding *binding,
122                                 const GValue *source_value,
123                                 GValue *target_value,
124                                 gpointer user_data)
125 {
126         GObject *target;
127         SoupURI *soup_uri;
128         const gchar *path;
129
130         path = g_value_get_string (source_value);
131
132         /* soup_uri_set_path() warns on NULL. */
133         if (path == NULL)
134                 path = "";
135
136         target = g_binding_get_target (binding);
137         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
138
139         soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
140         soup_uri_set_path (soup_uri, path);
141         g_value_take_boxed (target_value, soup_uri);
142
143         return TRUE;
144 }
145
146 static gboolean
147 source_webdav_soup_uri_to_path (GBinding *binding,
148                                 const GValue *source_value,
149                                 GValue *target_value,
150                                 gpointer user_data)
151 {
152         SoupURI *soup_uri;
153
154         soup_uri = g_value_get_boxed (source_value);
155         g_value_set_string (target_value, soup_uri->path);
156
157         return TRUE;
158 }
159
160 static gboolean
161 source_webdav_port_to_soup_uri (GBinding *binding,
162                                 const GValue *source_value,
163                                 GValue *target_value,
164                                 gpointer user_data)
165 {
166         GObject *target;
167         SoupURI *soup_uri;
168         guint port;
169
170         port = g_value_get_uint (source_value);
171
172         target = g_binding_get_target (binding);
173         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
174
175         soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
176         soup_uri_set_port (soup_uri, port);
177         g_value_take_boxed (target_value, soup_uri);
178
179         return TRUE;
180 }
181
182 static gboolean
183 source_webdav_soup_uri_to_port (GBinding *binding,
184                                 const GValue *source_value,
185                                 GValue *target_value,
186                                 gpointer user_data)
187 {
188         SoupURI *soup_uri;
189
190         soup_uri = g_value_get_boxed (source_value);
191         g_value_set_uint (target_value, soup_uri->port);
192
193         return TRUE;
194 }
195
196 static gboolean
197 source_webdav_secure_to_soup_uri (GBinding *binding,
198                                   const GValue *source_value,
199                                   GValue *target_value,
200                                   gpointer user_data)
201 {
202         GObject *target;
203         SoupURI *soup_uri;
204         gboolean secure;
205
206         secure = g_value_get_boolean (source_value);
207
208         target = g_binding_get_target (binding);
209         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
210
211         soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
212         if (secure)
213                 soup_uri_set_scheme (soup_uri, SOUP_URI_SCHEME_HTTPS);
214         else
215                 soup_uri_set_scheme (soup_uri, SOUP_URI_SCHEME_HTTP);
216         g_value_take_boxed (target_value, soup_uri);
217
218         return TRUE;
219 }
220
221 static gboolean
222 source_webdav_soup_uri_to_secure (GBinding *binding,
223                                   const GValue *source_value,
224                                   GValue *target_value,
225                                   gpointer user_data)
226 {
227         SoupURI *soup_uri;
228         gboolean secure;
229
230         soup_uri = g_value_get_boxed (source_value);
231         secure = (soup_uri->scheme == SOUP_URI_SCHEME_HTTPS);
232         g_value_set_boolean (target_value, secure);
233
234         return TRUE;
235 }
236
237 static gboolean
238 source_webdav_user_to_soup_uri (GBinding *binding,
239                                 const GValue *source_value,
240                                 GValue *target_value,
241                                 gpointer user_data)
242 {
243         GObject *target;
244         SoupURI *soup_uri;
245         const gchar *user;
246
247         user = g_value_get_string (source_value);
248
249         target = g_binding_get_target (binding);
250         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (target), FALSE);
251
252         soup_uri = e_source_webdav_dup_soup_uri (E_SOURCE_WEBDAV (target));
253         soup_uri_set_user (soup_uri, user);
254         g_value_take_boxed (target_value, soup_uri);
255
256         return TRUE;
257 }
258
259 static gboolean
260 source_webdav_soup_uri_to_user (GBinding *binding,
261                                 const GValue *source_value,
262                                 GValue *target_value,
263                                 gpointer user_data)
264 {
265         SoupURI *soup_uri;
266
267         soup_uri = g_value_get_boxed (source_value);
268         g_value_set_string (target_value, soup_uri->user);
269
270         return TRUE;
271 }
272
273 static gboolean
274 source_webdav_user_to_method (GBinding *binding,
275                               const GValue *source_value,
276                               GValue *target_value,
277                               gpointer user_data)
278 {
279         const gchar *user;
280
281         user = g_value_get_string (source_value);
282         if (user == NULL || *user == '\0')
283                 g_value_set_string (target_value, "none");
284         else
285                 g_value_set_string (target_value, "plain/password");
286
287         return TRUE;
288 }
289
290 static void
291 source_webdav_set_property (GObject *object,
292                             guint property_id,
293                             const GValue *value,
294                             GParamSpec *pspec)
295 {
296         switch (property_id) {
297                 case PROP_AVOID_IFMATCH:
298                         e_source_webdav_set_avoid_ifmatch (
299                                 E_SOURCE_WEBDAV (object),
300                                 g_value_get_boolean (value));
301                         return;
302
303                 case PROP_CALENDAR_AUTO_SCHEDULE:
304                         e_source_webdav_set_calendar_auto_schedule (
305                                 E_SOURCE_WEBDAV (object),
306                                 g_value_get_boolean (value));
307                         return;
308
309                 case PROP_DISPLAY_NAME:
310                         e_source_webdav_set_display_name (
311                                 E_SOURCE_WEBDAV (object),
312                                 g_value_get_string (value));
313                         return;
314
315                 case PROP_EMAIL_ADDRESS:
316                         e_source_webdav_set_email_address (
317                                 E_SOURCE_WEBDAV (object),
318                                 g_value_get_string (value));
319                         return;
320
321                 case PROP_IGNORE_INVALID_CERT:
322                         e_source_webdav_set_ignore_invalid_cert (
323                                 E_SOURCE_WEBDAV (object),
324                                 g_value_get_boolean (value));
325                         return;
326
327                 case PROP_RESOURCE_PATH:
328                         e_source_webdav_set_resource_path (
329                                 E_SOURCE_WEBDAV (object),
330                                 g_value_get_string (value));
331                         return;
332
333                 case PROP_SOUP_URI:
334                         e_source_webdav_set_soup_uri (
335                                 E_SOURCE_WEBDAV (object),
336                                 g_value_get_boxed (value));
337                         return;
338         }
339
340         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
341 }
342
343 static void
344 source_webdav_get_property (GObject *object,
345                             guint property_id,
346                             GValue *value,
347                             GParamSpec *pspec)
348 {
349         switch (property_id) {
350                 case PROP_AVOID_IFMATCH:
351                         g_value_set_boolean (
352                                 value,
353                                 e_source_webdav_get_avoid_ifmatch (
354                                 E_SOURCE_WEBDAV (object)));
355                         return;
356
357                 case PROP_CALENDAR_AUTO_SCHEDULE:
358                         g_value_set_boolean (
359                                 value,
360                                 e_source_webdav_get_calendar_auto_schedule (
361                                 E_SOURCE_WEBDAV (object)));
362                         return;
363
364                 case PROP_DISPLAY_NAME:
365                         g_value_take_string (
366                                 value,
367                                 e_source_webdav_dup_display_name (
368                                 E_SOURCE_WEBDAV (object)));
369                         return;
370
371                 case PROP_EMAIL_ADDRESS:
372                         g_value_take_string (
373                                 value,
374                                 e_source_webdav_dup_email_address (
375                                 E_SOURCE_WEBDAV (object)));
376                         return;
377
378                 case PROP_IGNORE_INVALID_CERT:
379                         g_value_set_boolean (
380                                 value,
381                                 e_source_webdav_get_ignore_invalid_cert (
382                                 E_SOURCE_WEBDAV (object)));
383                         return;
384
385                 case PROP_RESOURCE_PATH:
386                         g_value_take_string (
387                                 value,
388                                 e_source_webdav_dup_resource_path (
389                                 E_SOURCE_WEBDAV (object)));
390                         return;
391
392                 case PROP_SOUP_URI:
393                         g_value_take_boxed (
394                                 value,
395                                 e_source_webdav_dup_soup_uri (
396                                 E_SOURCE_WEBDAV (object)));
397                         return;
398         }
399
400         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
401 }
402
403 static void
404 source_webdav_finalize (GObject *object)
405 {
406         ESourceWebdavPrivate *priv;
407
408         priv = E_SOURCE_WEBDAV_GET_PRIVATE (object);
409
410         g_mutex_free (priv->property_lock);
411
412         g_free (priv->display_name);
413         g_free (priv->email_address);
414         g_free (priv->resource_path);
415
416         soup_uri_free (priv->uri);
417
418         /* Chain up to parent's finalize() method. */
419         G_OBJECT_CLASS (e_source_webdav_parent_class)->finalize (object);
420 }
421
422 static void
423 source_webdav_constructed (GObject *object)
424 {
425         ESource *source;
426         ESourceExtension *this_extension;
427         ESourceExtension *other_extension;
428         const gchar *extension_name;
429
430         /* Chain up to parent's constructed() method. */
431         G_OBJECT_CLASS (e_source_webdav_parent_class)->constructed (object);
432
433         this_extension = E_SOURCE_EXTENSION (object);
434         source = e_source_extension_get_source (this_extension);
435
436         g_object_bind_property_full (
437                 this_extension, "resource-path",
438                 this_extension, "soup-uri",
439                 G_BINDING_BIDIRECTIONAL |
440                 G_BINDING_SYNC_CREATE,
441                 source_webdav_path_to_soup_uri,
442                 source_webdav_soup_uri_to_path,
443                 NULL, (GDestroyNotify) NULL);
444
445         /* Bind to properties of other extensions for convenience. */
446
447         extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
448         other_extension = e_source_get_extension (source, extension_name);
449
450         g_object_bind_property_full (
451                 other_extension, "host",
452                 this_extension, "soup-uri",
453                 G_BINDING_BIDIRECTIONAL |
454                 G_BINDING_SYNC_CREATE,
455                 source_webdav_host_to_soup_uri,
456                 source_webdav_soup_uri_to_host,
457                 NULL, (GDestroyNotify) NULL);
458
459         g_object_bind_property_full (
460                 other_extension, "port",
461                 this_extension, "soup-uri",
462                 G_BINDING_BIDIRECTIONAL |
463                 G_BINDING_SYNC_CREATE,
464                 source_webdav_port_to_soup_uri,
465                 source_webdav_soup_uri_to_port,
466                 NULL, (GDestroyNotify) NULL);
467
468         g_object_bind_property_full (
469                 other_extension, "user",
470                 this_extension, "soup-uri",
471                 G_BINDING_BIDIRECTIONAL |
472                 G_BINDING_SYNC_CREATE,
473                 source_webdav_user_to_soup_uri,
474                 source_webdav_soup_uri_to_user,
475                 NULL, (GDestroyNotify) NULL);
476
477         g_object_bind_property_full (
478                 other_extension, "user",
479                 other_extension, "method",
480                 G_BINDING_SYNC_CREATE,
481                 source_webdav_user_to_method,
482                 NULL,
483                 NULL, (GDestroyNotify) NULL);
484
485         extension_name = E_SOURCE_EXTENSION_SECURITY;
486         other_extension = e_source_get_extension (source, extension_name);
487
488         g_object_bind_property_full (
489                 other_extension, "secure",
490                 this_extension, "soup-uri",
491                 G_BINDING_BIDIRECTIONAL |
492                 G_BINDING_SYNC_CREATE,
493                 source_webdav_secure_to_soup_uri,
494                 source_webdav_soup_uri_to_secure,
495                 NULL, (GDestroyNotify) NULL);
496 }
497
498 static void
499 e_source_webdav_class_init (ESourceWebdavClass *class)
500 {
501         GObjectClass *object_class;
502         ESourceExtensionClass *extension_class;
503
504         g_type_class_add_private (class, sizeof (ESourceWebdavPrivate));
505
506         object_class = G_OBJECT_CLASS (class);
507         object_class->set_property = source_webdav_set_property;
508         object_class->get_property = source_webdav_get_property;
509         object_class->finalize = source_webdav_finalize;
510         object_class->constructed = source_webdav_constructed;
511
512         extension_class = E_SOURCE_EXTENSION_CLASS (class);
513         extension_class->name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
514
515         g_object_class_install_property (
516                 object_class,
517                 PROP_AVOID_IFMATCH,
518                 g_param_spec_boolean (
519                         "avoid-ifmatch",
520                         "Avoid If-Match",
521                         "Work around a bug in old Apache servers",
522                         FALSE,
523                         G_PARAM_READWRITE |
524                         G_PARAM_CONSTRUCT |
525                         E_SOURCE_PARAM_SETTING));
526
527         g_object_class_install_property (
528                 object_class,
529                 PROP_CALENDAR_AUTO_SCHEDULE,
530                 g_param_spec_boolean (
531                         "calendar-auto-schedule",
532                         "Calendar Auto-Schedule",
533                         "Whether the server handles meeting "
534                         "invitations (CalDAV-only)",
535                         FALSE,
536                         G_PARAM_READWRITE |
537                         G_PARAM_CONSTRUCT |
538                         E_SOURCE_PARAM_SETTING));
539
540         g_object_class_install_property (
541                 object_class,
542                 PROP_DISPLAY_NAME,
543                 g_param_spec_string (
544                         "display-name",
545                         "Display Name",
546                         "Display name of the WebDAV resource",
547                         "",
548                         G_PARAM_READWRITE |
549                         G_PARAM_CONSTRUCT |
550                         E_SOURCE_PARAM_SETTING));
551
552         g_object_class_install_property (
553                 object_class,
554                 PROP_EMAIL_ADDRESS,
555                 g_param_spec_string (
556                         "email-address",
557                         "Email Address",
558                         "The user's email address",
559                         "",
560                         G_PARAM_READWRITE |
561                         G_PARAM_CONSTRUCT |
562                         E_SOURCE_PARAM_SETTING));
563
564         g_object_class_install_property (
565                 object_class,
566                 PROP_IGNORE_INVALID_CERT,
567                 g_param_spec_boolean (
568                         "ignore-invalid-cert",
569                         "Ignore Invalid Cert",
570                         "Ignore invalid SSL certificates",
571                         FALSE,
572                         G_PARAM_READWRITE |
573                         G_PARAM_CONSTRUCT |
574                         E_SOURCE_PARAM_SETTING));
575
576         g_object_class_install_property (
577                 object_class,
578                 PROP_RESOURCE_PATH,
579                 g_param_spec_string (
580                         "resource-path",
581                         "Resource Path",
582                         "Absolute path to a WebDAV resource",
583                         NULL,
584                         G_PARAM_READWRITE |
585                         G_PARAM_CONSTRUCT |
586                         E_SOURCE_PARAM_SETTING));
587
588         g_object_class_install_property (
589                 object_class,
590                 PROP_SOUP_URI,
591                 g_param_spec_boxed (
592                         "soup-uri",
593                         "SoupURI",
594                         "WebDAV service as a SoupURI",
595                         SOUP_TYPE_URI,
596                         G_PARAM_READWRITE));
597 }
598
599 static void
600 e_source_webdav_init (ESourceWebdav *extension)
601 {
602         extension->priv = E_SOURCE_WEBDAV_GET_PRIVATE (extension);
603         extension->priv->property_lock = g_mutex_new ();
604
605         /* Initialize this enough for SOUP_URI_IS_VALID() to pass. */
606         extension->priv->uri = soup_uri_new (NULL);
607         extension->priv->uri->scheme = SOUP_URI_SCHEME_HTTP;
608         extension->priv->uri->path = g_strdup ("");
609 }
610
611 /**
612  * e_source_webdav_get_avoid_ifmatch:
613  * @extension: an #ESourceWebdav
614  *
615  * This setting works around a
616  * <ulink url="https://issues.apache.org/bugzilla/show_bug.cgi?id=38034">
617  * bug</ulink> in older Apache mod_dav versions.
618  *
619  * <note>
620  *   <para>
621  *     We may deprecate this once Apache 2.2.8 or newer becomes
622  *     sufficiently ubiquitous, or we figure out a way to detect
623  *     and work around the bug automatically.
624  *   </para>
625  * </note>
626  *
627  * Returns: whether the WebDAV server is known to exhibit the bug
628  *
629  * Since: 3.6
630  **/
631 gboolean
632 e_source_webdav_get_avoid_ifmatch (ESourceWebdav *extension)
633 {
634         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), FALSE);
635
636         return extension->priv->avoid_ifmatch;
637 }
638
639 /**
640  * e_source_webdav_set_avoid_ifmatch:
641  * @extension: an #ESourceWebdav
642  * @avoid_ifmatch: whether the WebDAV server is known to exhibit the bug
643  *
644  * This setting works around a
645  * <ulink url="https://issues.apache.org/bugzilla/show_bug.cgi?id=38034">
646  * bug</ulink> in older Apache mod_dav versions.
647  *
648  * <note>
649  *   <para>
650  *     We may deprecate this once Apache 2.2.8 or newer becomes
651  *     sufficiently ubiquitous, or we figure out a way to detect
652  *     and work around the bug automatically.
653  *   </para>
654  * </note>
655  *
656  * Since: 3.6
657  **/
658 void
659 e_source_webdav_set_avoid_ifmatch (ESourceWebdav *extension,
660                                    gboolean avoid_ifmatch)
661 {
662         g_return_if_fail (E_IS_SOURCE_WEBDAV (extension));
663
664         extension->priv->avoid_ifmatch = avoid_ifmatch;
665
666         g_object_notify (G_OBJECT (extension), "avoid-ifmatch");
667 }
668
669 /**
670  * e_source_webdav_get_calendar_auto_schedule:
671  * @extension: an #ESourceWebdav
672  *
673  * FIXME Document me!
674  *
675  * Since: 3.6
676  **/
677 gboolean
678 e_source_webdav_get_calendar_auto_schedule (ESourceWebdav *extension)
679 {
680         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), FALSE);
681
682         return extension->priv->calendar_auto_schedule;
683 }
684
685 /**
686  * e_source_webdav_set_calendar_auto_schedule:
687  * @extension: an #ESourceWebdav
688  * @calendar_auto_schedule: whether the server supports the
689  * "calendar-auto-schedule" feature of CalDAV
690  *
691  * FIXME Document me!
692  *
693  * Since: 3.6
694  **/
695 void
696 e_source_webdav_set_calendar_auto_schedule (ESourceWebdav *extension,
697                                             gboolean calendar_auto_schedule)
698 {
699         g_return_if_fail (E_IS_SOURCE_WEBDAV (extension));
700
701         extension->priv->calendar_auto_schedule = calendar_auto_schedule;
702
703         g_object_notify (G_OBJECT (extension), "calendar-auto-schedule");
704 }
705
706 /**
707  * e_source_webdav_get_display_name:
708  * @extension: an #ESourceWebdav
709  *
710  * Returns the last known display name of a WebDAV resource, which may
711  * differ from the #ESource:display-name property of the #ESource to which
712  * @extension belongs.
713  *
714  * Returns: the display name of the WebDAV resource
715  *
716  * Since: 3.6
717  **/
718 const gchar *
719 e_source_webdav_get_display_name (ESourceWebdav *extension)
720 {
721         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), NULL);
722
723         return extension->priv->display_name;
724 }
725
726 /**
727  * e_source_webdav_dup_display_name:
728  * @extension: an #ESourceWebdav
729  *
730  * Thread-safe variation of e_source_webdav_get_display_name().
731  * Use this function when accessing @extension from multiple threads.
732  *
733  * The returned string should be freed with g_free() when no longer needed.
734  *
735  * Returns: a newly-allocated copy of #ESourceWebdav:display-name
736  *
737  * Since: 3.6
738  **/
739 gchar *
740 e_source_webdav_dup_display_name (ESourceWebdav *extension)
741 {
742         const gchar *protected;
743         gchar *duplicate;
744
745         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), NULL);
746
747         g_mutex_lock (extension->priv->property_lock);
748
749         protected = e_source_webdav_get_display_name (extension);
750         duplicate = g_strdup (protected);
751
752         g_mutex_unlock (extension->priv->property_lock);
753
754         return duplicate;
755 }
756
757 /**
758  * e_source_webdav_set_display_name:
759  * @extension: an #ESourceWebdav
760  * @display_name: (allow-none): the display name of the WebDAV resource,
761  *                or %NULL
762  *
763  * Updates the last known display name of a WebDAV resource, which may
764  * differ from the #ESource:display-name property of the #ESource to which
765  * @extension belongs.
766  *
767  * The internal copy of @display_name is automatically stripped of leading
768  * and trailing whitespace.  If the resulting string is empty, %NULL is set
769  * instead.
770  *
771  * Since: 3.6
772  **/
773 void
774 e_source_webdav_set_display_name (ESourceWebdav *extension,
775                                   const gchar *display_name)
776 {
777         g_return_if_fail (E_IS_SOURCE_WEBDAV (extension));
778
779         g_mutex_lock (extension->priv->property_lock);
780
781         g_free (extension->priv->display_name);
782         extension->priv->display_name = e_util_strdup_strip (display_name);
783
784         g_mutex_unlock (extension->priv->property_lock);
785
786         g_object_notify (G_OBJECT (extension), "display-name");
787 }
788
789 /**
790  * e_source_webdav_get_email_address:
791  * @extension: an #ESourceWebdav
792  *
793  * Returns the user's email address which can be passed to a CalDAV server
794  * if the user wishes to receive scheduling messages.
795  *
796  * Returns: the user's email address
797  *
798  * Since: 3.6
799  **/
800 const gchar *
801 e_source_webdav_get_email_address (ESourceWebdav *extension)
802 {
803         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), NULL);
804
805         return extension->priv->email_address;
806 }
807
808 /**
809  * e_source_webdav_dup_email_address:
810  * @extension: an #ESourceWebdav
811  *
812  * Thread-safe variation of e_source_webdav_get_email_address().
813  * Use this function when accessing @extension from multiple threads.
814  *
815  * The returned string should be freed with g_free() when no longer needed.
816  *
817  * Returns: the newly-allocated copy of #ESourceWebdav:email-address
818  *
819  * Since: 3.6
820  **/
821 gchar *
822 e_source_webdav_dup_email_address (ESourceWebdav *extension)
823 {
824         const gchar *protected;
825         gchar *duplicate;
826
827         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), NULL);
828
829         g_mutex_lock (extension->priv->property_lock);
830
831         protected = e_source_webdav_get_email_address (extension);
832         duplicate = g_strdup (protected);
833
834         g_mutex_unlock (extension->priv->property_lock);
835
836         return duplicate;
837 }
838
839 /**
840  * e_source_webdav_set_email_address:
841  * @extension: an #ESourceWebdav
842  * @email_address: (allow-none): the user's email address, or %NULL
843  *
844  * Sets the user's email address which can be passed to a CalDAV server if
845  * the user wishes to receive scheduling messages.
846  *
847  * The internal copy of @email_address is automatically stripped of leading
848  * and trailing whitespace.  If the resulting string is empty, %NULL is set
849  * instead.
850  *
851  * Since: 3.6
852  **/
853 void
854 e_source_webdav_set_email_address (ESourceWebdav *extension,
855                                    const gchar *email_address)
856 {
857         g_return_if_fail (E_IS_SOURCE_WEBDAV (extension));
858
859         g_mutex_lock (extension->priv->property_lock);
860
861         g_free (extension->priv->email_address);
862         extension->priv->email_address = e_util_strdup_strip (email_address);
863
864         g_mutex_unlock (extension->priv->property_lock);
865
866         g_object_notify (G_OBJECT (extension), "email-address");
867 }
868
869 /**
870  * e_source_webdav_get_ignore_invalid_cert:
871  * @extension: an #ESourceWebdav
872  *
873  * Returns %TRUE if invalid SSL certificates should be ignored.
874  *
875  * This option allows SSL certificates to be accepted even if they have
876  * signed by an unrecognized Certificate Authority.
877  *
878  * Returns: whether invalid SSL certificates should be ignored
879  *
880  * Since: 3.6
881  **/
882 gboolean
883 e_source_webdav_get_ignore_invalid_cert (ESourceWebdav *extension)
884 {
885         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), FALSE);
886
887         return extension->priv->ignore_invalid_cert;
888 }
889
890 /**
891  * e_source_webdav_set_ignore_invalid_cert:
892  * @extension: an #ESourceWebdav
893  * @ignore_invalid_cert: whether invalid SSL certificates should be ignored
894  *
895  * Sets whether invalid SSL certificates should be ignored.
896  *
897  * This option allows SSL certificates to be accepted even if they have
898  * signed by an unrecognized Certificate Authority.
899  *
900  * Since: 3.6
901  **/
902 void
903 e_source_webdav_set_ignore_invalid_cert (ESourceWebdav *extension,
904                                          gboolean ignore_invalid_cert)
905 {
906         g_return_if_fail (E_IS_SOURCE_WEBDAV (extension));
907
908         extension->priv->ignore_invalid_cert = ignore_invalid_cert;
909
910         g_object_notify (G_OBJECT (extension), "ignore-invalid-cert");
911 }
912
913 /**
914  * e_source_webdav_get_resource_path:
915  * @extension: an #ESourceWebdav
916  *
917  * Returns the absolute path to a resource on a WebDAV server.
918  *
919  * Returns: the absolute path to a WebDAV resource
920  *
921  * Since: 3.6
922  **/
923 const gchar *
924 e_source_webdav_get_resource_path (ESourceWebdav *extension)
925 {
926         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), NULL);
927
928         return extension->priv->resource_path;
929 }
930
931 /**
932  * e_source_webdav_dup_resource_path:
933  * @extension: an #ESourceWebdav
934  *
935  * Thread-safe variation of e_source_webdav_get_resource_path().
936  * Use this function when accessing @extension from multiple threads.
937  *
938  * The returned string should be freed with g_free() when no longer needed.
939  *
940  * Returns: the newly-allocated copy of #ESourceWebdav:resource-path
941  *
942  * Since: 3.6
943  **/
944 gchar *
945 e_source_webdav_dup_resource_path (ESourceWebdav *extension)
946 {
947         const gchar *protected;
948         gchar *duplicate;
949
950         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), NULL);
951
952         g_mutex_lock (extension->priv->property_lock);
953
954         protected = e_source_webdav_get_resource_path (extension);
955         duplicate = g_strdup (protected);
956
957         g_mutex_unlock (extension->priv->property_lock);
958
959         return duplicate;
960 }
961
962 /**
963  * e_source_webdav_set_resource_path:
964  * @extension: an #ESourceWebdav
965  * @resource_path: (allow-none): the absolute path to a WebDAV resource,
966  *                 or %NULL
967  *
968  * Sets the absolute path to a resource on a WebDAV server.
969  *
970  * The internal copy of @resource_path is automatically stripped of leading
971  * and trailing whitespace.  If the resulting string is empty, %NULL is set
972  * instead.
973  *
974  * Since: 3.6
975  **/
976 void
977 e_source_webdav_set_resource_path (ESourceWebdav *extension,
978                                    const gchar *resource_path)
979 {
980         g_return_if_fail (E_IS_SOURCE_WEBDAV (extension));
981
982         g_mutex_lock (extension->priv->property_lock);
983
984         g_free (extension->priv->resource_path);
985         extension->priv->resource_path = e_util_strdup_strip (resource_path);
986
987         g_mutex_unlock (extension->priv->property_lock);
988
989         g_object_notify (G_OBJECT (extension), "resource-path");
990 }
991
992 /**
993  * e_source_webdav_dup_soup_uri:
994  * @extension: an #ESourceWebdav
995  *
996  * This is a convenience function which returns a newly-allocated
997  * #SoupURI, its contents assembled from the #ESourceAuthentication
998  * extension, the #ESourceSecurity extension, and @extension itself.
999  * Free the returned #SoupURI with soup_uri_free().
1000  *
1001  * Returns: (transfer full): a newly-allocated #SoupURI
1002  *
1003  * Since: 3.6
1004  **/
1005 SoupURI *
1006 e_source_webdav_dup_soup_uri (ESourceWebdav *extension)
1007 {
1008         SoupURI *duplicate;
1009
1010         g_return_val_if_fail (E_IS_SOURCE_WEBDAV (extension), NULL);
1011
1012         g_mutex_lock (extension->priv->property_lock);
1013
1014         duplicate = soup_uri_copy (extension->priv->uri);
1015
1016         g_mutex_unlock (extension->priv->property_lock);
1017
1018         return duplicate;
1019 }
1020
1021 /**
1022  * e_source_webdav_set_soup_uri:
1023  * @extension: an #ESourceWebdav
1024  * @uri: a #SoupURI
1025  *
1026  * This is a convenience function which propagates the components of
1027  * @uri to the #ESourceAuthentication extension, the #ESourceSecurity
1028  * extension, and @extension itself.  (The "query" and "fragment"
1029  * components of @uri are ignored.)
1030  *
1031  * Since: 3.6
1032  **/
1033 void
1034 e_source_webdav_set_soup_uri (ESourceWebdav *extension,
1035                               SoupURI *uri)
1036 {
1037         g_return_if_fail (E_IS_SOURCE_WEBDAV (extension));
1038         g_return_if_fail (SOUP_URI_IS_VALID (uri));
1039
1040         g_mutex_lock (extension->priv->property_lock);
1041
1042         soup_uri_free (extension->priv->uri);
1043         extension->priv->uri = soup_uri_copy (uri);
1044
1045         g_mutex_unlock (extension->priv->property_lock);
1046
1047         g_object_notify (G_OBJECT (extension), "soup-uri");
1048 }
1049