1 /*
2  * e-source-authentication.c
3  *
4  * This library is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation.
7  *
8  * This library is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11  * for more details.
12  *
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/>.
15  *
16  */
17 
18 /**
19  * SECTION: e-source-authentication
20  * @include: libedataserver/libedataserver.h
21  * @short_description: #ESource extension for authentication settings
22  *
23  * The #ESourceAuthentication extension tracks authentication settings
24  * for a user account on a remote server.
25  *
26  * Access the extension as follows:
27  *
28  * |[
29  *   #include <libedataserver/libedataserver.h>
30  *
31  *   ESourceAuthentication *extension;
32  *
33  *   extension = e_source_get_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION);
34  * ]|
35  **/
36 
37 #include "e-source-authentication.h"
38 
39 #include <libedataserver/e-data-server-util.h>
40 
41 struct _ESourceAuthenticationPrivate {
42 	gchar *host;
43 	gchar *method;
44 	guint16 port;
45 	gchar *proxy_uid;
46 	gboolean remember_password;
47 	gchar *user;
48 	gchar *credential_name;
49 	gboolean is_external;
50 
51 	/* GNetworkAddress caches data internally, so we maintain the
52 	 * instance to preserve the cache as opposed to just creating
53 	 * a new GNetworkAddress instance each time it's requested. */
54 	GSocketConnectable *connectable;
55 };
56 
57 enum {
58 	PROP_0,
59 	PROP_CONNECTABLE,
60 	PROP_HOST,
61 	PROP_METHOD,
62 	PROP_PORT,
63 	PROP_PROXY_UID,
64 	PROP_REMEMBER_PASSWORD,
65 	PROP_USER,
66 	PROP_CREDENTIAL_NAME,
67 	PROP_IS_EXTERNAL
68 };
69 
G_DEFINE_TYPE_WITH_PRIVATE(ESourceAuthentication,e_source_authentication,E_TYPE_SOURCE_EXTENSION)70 G_DEFINE_TYPE_WITH_PRIVATE (
71 	ESourceAuthentication,
72 	e_source_authentication,
73 	E_TYPE_SOURCE_EXTENSION)
74 
75 static void
76 source_authentication_update_connectable (ESourceAuthentication *extension)
77 {
78 	const gchar *host;
79 	guint16 port;
80 
81 	/* This MUST be called with the property_lock acquired. */
82 
83 	g_clear_object (&extension->priv->connectable);
84 
85 	host = e_source_authentication_get_host (extension);
86 	port = e_source_authentication_get_port (extension);
87 
88 	if (host != NULL) {
89 		GSocketConnectable *connectable;
90 		connectable = g_network_address_new (host, port);
91 		extension->priv->connectable = connectable;
92 	}
93 }
94 
95 static void
source_authentication_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)96 source_authentication_set_property (GObject *object,
97                                     guint property_id,
98                                     const GValue *value,
99                                     GParamSpec *pspec)
100 {
101 	switch (property_id) {
102 		case PROP_HOST:
103 			e_source_authentication_set_host (
104 				E_SOURCE_AUTHENTICATION (object),
105 				g_value_get_string (value));
106 			return;
107 
108 		case PROP_METHOD:
109 			e_source_authentication_set_method (
110 				E_SOURCE_AUTHENTICATION (object),
111 				g_value_get_string (value));
112 			return;
113 
114 		case PROP_PORT:
115 			e_source_authentication_set_port (
116 				E_SOURCE_AUTHENTICATION (object),
117 				g_value_get_uint (value));
118 			return;
119 
120 		case PROP_PROXY_UID:
121 			e_source_authentication_set_proxy_uid (
122 				E_SOURCE_AUTHENTICATION (object),
123 				g_value_get_string (value));
124 			return;
125 
126 		case PROP_REMEMBER_PASSWORD:
127 			e_source_authentication_set_remember_password (
128 				E_SOURCE_AUTHENTICATION (object),
129 				g_value_get_boolean (value));
130 			return;
131 
132 		case PROP_USER:
133 			e_source_authentication_set_user (
134 				E_SOURCE_AUTHENTICATION (object),
135 				g_value_get_string (value));
136 			return;
137 
138 		case PROP_CREDENTIAL_NAME:
139 			e_source_authentication_set_credential_name (
140 				E_SOURCE_AUTHENTICATION (object),
141 				g_value_get_string (value));
142 			return;
143 
144 		case PROP_IS_EXTERNAL:
145 			e_source_authentication_set_is_external (
146 				E_SOURCE_AUTHENTICATION (object),
147 				g_value_get_boolean (value));
148 			return;
149 	}
150 
151 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
152 }
153 
154 static void
source_authentication_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)155 source_authentication_get_property (GObject *object,
156                                     guint property_id,
157                                     GValue *value,
158                                     GParamSpec *pspec)
159 {
160 	switch (property_id) {
161 		case PROP_CONNECTABLE:
162 			g_value_take_object (
163 				value,
164 				e_source_authentication_ref_connectable (
165 				E_SOURCE_AUTHENTICATION (object)));
166 			return;
167 
168 		case PROP_HOST:
169 			g_value_take_string (
170 				value,
171 				e_source_authentication_dup_host (
172 				E_SOURCE_AUTHENTICATION (object)));
173 			return;
174 
175 		case PROP_METHOD:
176 			g_value_take_string (
177 				value,
178 				e_source_authentication_dup_method (
179 				E_SOURCE_AUTHENTICATION (object)));
180 			return;
181 
182 		case PROP_PORT:
183 			g_value_set_uint (
184 				value,
185 				e_source_authentication_get_port (
186 				E_SOURCE_AUTHENTICATION (object)));
187 			return;
188 
189 		case PROP_PROXY_UID:
190 			g_value_take_string (
191 				value,
192 				e_source_authentication_dup_proxy_uid (
193 				E_SOURCE_AUTHENTICATION (object)));
194 			return;
195 
196 		case PROP_REMEMBER_PASSWORD:
197 			g_value_set_boolean (
198 				value,
199 				e_source_authentication_get_remember_password (
200 				E_SOURCE_AUTHENTICATION (object)));
201 			return;
202 
203 		case PROP_USER:
204 			g_value_take_string (
205 				value,
206 				e_source_authentication_dup_user (
207 				E_SOURCE_AUTHENTICATION (object)));
208 			return;
209 
210 		case PROP_CREDENTIAL_NAME:
211 			g_value_take_string (
212 				value,
213 				e_source_authentication_dup_credential_name (
214 				E_SOURCE_AUTHENTICATION (object)));
215 			return;
216 
217 		case PROP_IS_EXTERNAL:
218 			g_value_set_boolean (
219 				value,
220 				e_source_authentication_get_is_external (
221 				E_SOURCE_AUTHENTICATION (object)));
222 			return;
223 	}
224 
225 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
226 }
227 
228 static void
source_authentication_dispose(GObject * object)229 source_authentication_dispose (GObject *object)
230 {
231 	ESourceAuthenticationPrivate *priv;
232 
233 	priv = E_SOURCE_AUTHENTICATION (object)->priv;
234 
235 	g_clear_object (&priv->connectable);
236 
237 	/* Chain up to parent's dispose() method. */
238 	G_OBJECT_CLASS (e_source_authentication_parent_class)->dispose (object);
239 }
240 
241 static void
source_authentication_finalize(GObject * object)242 source_authentication_finalize (GObject *object)
243 {
244 	ESourceAuthenticationPrivate *priv;
245 
246 	priv = E_SOURCE_AUTHENTICATION (object)->priv;
247 
248 	g_free (priv->host);
249 	g_free (priv->method);
250 	g_free (priv->proxy_uid);
251 	g_free (priv->user);
252 
253 	/* Chain up to parent's finalize() method. */
254 	G_OBJECT_CLASS (e_source_authentication_parent_class)->finalize (object);
255 }
256 
257 static void
e_source_authentication_class_init(ESourceAuthenticationClass * class)258 e_source_authentication_class_init (ESourceAuthenticationClass *class)
259 {
260 	GObjectClass *object_class;
261 	ESourceExtensionClass *extension_class;
262 
263 	object_class = G_OBJECT_CLASS (class);
264 	object_class->set_property = source_authentication_set_property;
265 	object_class->get_property = source_authentication_get_property;
266 	object_class->dispose = source_authentication_dispose;
267 	object_class->finalize = source_authentication_finalize;
268 
269 	extension_class = E_SOURCE_EXTENSION_CLASS (class);
270 	extension_class->name = E_SOURCE_EXTENSION_AUTHENTICATION;
271 
272 	g_object_class_install_property (
273 		object_class,
274 		PROP_CONNECTABLE,
275 		g_param_spec_object (
276 			"connectable",
277 			"Connectable",
278 			"A GSocketConnectable constructed "
279 			"from the host and port properties",
280 			G_TYPE_SOCKET_CONNECTABLE,
281 			G_PARAM_READABLE |
282 			G_PARAM_STATIC_STRINGS));
283 
284 	g_object_class_install_property (
285 		object_class,
286 		PROP_HOST,
287 		g_param_spec_string (
288 			"host",
289 			"Host",
290 			"Host name for the remote account",
291 			"",
292 			G_PARAM_READWRITE |
293 			G_PARAM_CONSTRUCT |
294 			G_PARAM_EXPLICIT_NOTIFY |
295 			G_PARAM_STATIC_STRINGS |
296 			E_SOURCE_PARAM_SETTING));
297 
298 	g_object_class_install_property (
299 		object_class,
300 		PROP_METHOD,
301 		g_param_spec_string (
302 			"method",
303 			"Method",
304 			"Authentication method",
305 			"none",
306 			G_PARAM_READWRITE |
307 			G_PARAM_CONSTRUCT |
308 			G_PARAM_EXPLICIT_NOTIFY |
309 			G_PARAM_STATIC_STRINGS |
310 			E_SOURCE_PARAM_SETTING));
311 
312 	g_object_class_install_property (
313 		object_class,
314 		PROP_PORT,
315 		g_param_spec_uint (
316 			"port",
317 			"Port",
318 			"Port number for the remote account",
319 			0, G_MAXUINT16, 0,
320 			G_PARAM_READWRITE |
321 			G_PARAM_CONSTRUCT |
322 			G_PARAM_EXPLICIT_NOTIFY |
323 			G_PARAM_STATIC_STRINGS |
324 			E_SOURCE_PARAM_SETTING));
325 
326 	g_object_class_install_property (
327 		object_class,
328 		PROP_PROXY_UID,
329 		g_param_spec_string (
330 			"proxy-uid",
331 			"Proxy UID",
332 			"ESource UID of a proxy profile",
333 			"system-proxy",
334 			G_PARAM_READWRITE |
335 			G_PARAM_CONSTRUCT |
336 			G_PARAM_EXPLICIT_NOTIFY |
337 			G_PARAM_STATIC_STRINGS |
338 			E_SOURCE_PARAM_SETTING));
339 
340 	g_object_class_install_property (
341 		object_class,
342 		PROP_REMEMBER_PASSWORD,
343 		g_param_spec_boolean (
344 			"remember-password",
345 			"Remember Password",
346 			"Whether to offer to remember the "
347 			"password by default when prompted",
348 			TRUE,
349 			G_PARAM_READWRITE |
350 			G_PARAM_CONSTRUCT |
351 			G_PARAM_EXPLICIT_NOTIFY |
352 			G_PARAM_STATIC_STRINGS |
353 			E_SOURCE_PARAM_SETTING));
354 
355 	g_object_class_install_property (
356 		object_class,
357 		PROP_USER,
358 		g_param_spec_string (
359 			"user",
360 			"User",
361 			"User name for the remote account",
362 			NULL,
363 			G_PARAM_READWRITE |
364 			G_PARAM_CONSTRUCT |
365 			G_PARAM_EXPLICIT_NOTIFY |
366 			G_PARAM_STATIC_STRINGS |
367 			E_SOURCE_PARAM_SETTING));
368 
369 	/* An empty string or NULL means to use E_SOURCE_CREDENTIAL_PASSWORD to pass
370 	   the stored "password" into the backend with e_source_invoke_authenticate()/_sync() */
371 	g_object_class_install_property (
372 		object_class,
373 		PROP_CREDENTIAL_NAME,
374 		g_param_spec_string (
375 			"credential-name",
376 			"Credential Name",
377 			"What name to use for the authentication method in credentials for authentication",
378 			NULL,
379 			G_PARAM_READWRITE |
380 			G_PARAM_CONSTRUCT |
381 			G_PARAM_EXPLICIT_NOTIFY |
382 			G_PARAM_STATIC_STRINGS |
383 			E_SOURCE_PARAM_SETTING));
384 
385 	g_object_class_install_property (
386 		object_class,
387 		PROP_IS_EXTERNAL,
388 		g_param_spec_boolean (
389 			"is-external",
390 			"Is External",
391 			"Whether the authentication is done by another authentication manager (like any Single Sign On daemon)",
392 			FALSE,
393 			G_PARAM_READWRITE |
394 			G_PARAM_CONSTRUCT |
395 			G_PARAM_EXPLICIT_NOTIFY |
396 			G_PARAM_STATIC_STRINGS |
397 			E_SOURCE_PARAM_SETTING));
398 }
399 
400 static void
e_source_authentication_init(ESourceAuthentication * extension)401 e_source_authentication_init (ESourceAuthentication *extension)
402 {
403 	extension->priv = e_source_authentication_get_instance_private (extension);
404 }
405 
406 /**
407  * e_source_authentication_required:
408  * @extension: an #ESourceAuthentication
409  *
410  * This is a convenience function which returns whether authentication
411  * is required at all, regardless of the method used.  This relies on
412  * the convention of setting #ESourceAuthentication:method to "none"
413  * when authentication is <emphasis>not</emphasis> required.
414  *
415  * Returns: whether authentication is required at all
416  *
417  * Since: 3.6
418  **/
419 gboolean
e_source_authentication_required(ESourceAuthentication * extension)420 e_source_authentication_required (ESourceAuthentication *extension)
421 {
422 	const gchar *method;
423 
424 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), FALSE);
425 
426 	method = e_source_authentication_get_method (extension);
427 	g_return_val_if_fail (method != NULL && *method != '\0', FALSE);
428 
429 	return (g_strcmp0 (method, "none") != 0);
430 }
431 
432 /**
433  * e_source_authentication_ref_connectable:
434  * @extension: an #ESourceAuthentication
435  *
436  * Returns a #GSocketConnectable instance constructed from @extension's
437  * #ESourceAuthentication:host and #ESourceAuthentication:port properties,
438  * or %NULL if the #ESourceAuthentication:host is not set.
439  *
440  * The returned #GSocketConnectable is referenced for thread-safety and must
441  * be unreferenced with g_object_unref() when finished with it.
442  *
443  * Returns: (transfer full) (nullable): a #GSocketConnectable, or %NULL
444  *
445  * Since: 3.8
446  **/
447 GSocketConnectable *
e_source_authentication_ref_connectable(ESourceAuthentication * extension)448 e_source_authentication_ref_connectable (ESourceAuthentication *extension)
449 {
450 	GSocketConnectable *connectable = NULL;
451 
452 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), NULL);
453 
454 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
455 
456 	if (extension->priv->connectable != NULL)
457 		connectable = g_object_ref (extension->priv->connectable);
458 
459 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
460 
461 	return connectable;
462 }
463 
464 /**
465  * e_source_authentication_get_host:
466  * @extension: an #ESourceAuthentication
467  *
468  * Returns the host name used to authenticate to a remote account.
469  *
470  * Returns: (nullable): the host name of a remote account
471  *
472  * Since: 3.6
473  **/
474 const gchar *
e_source_authentication_get_host(ESourceAuthentication * extension)475 e_source_authentication_get_host (ESourceAuthentication *extension)
476 {
477 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), NULL);
478 
479 	return extension->priv->host;
480 }
481 
482 /**
483  * e_source_authentication_dup_host:
484  * @extension: an #ESourceAuthentication
485  *
486  * Thread-safe variation of e_source_authentication_get_host().
487  * Use this function when accessing @extension from multiple threads.
488  *
489  * The returned string should be freed with g_free() when no longer needed.
490  *
491  * Returns: (nullable): a newly-allocated copy of #ESourceAuthentication:host
492  *
493  * Since: 3.6
494  **/
495 gchar *
e_source_authentication_dup_host(ESourceAuthentication * extension)496 e_source_authentication_dup_host (ESourceAuthentication *extension)
497 {
498 	const gchar *protected;
499 	gchar *duplicate;
500 
501 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), NULL);
502 
503 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
504 
505 	protected = e_source_authentication_get_host (extension);
506 	duplicate = g_strdup (protected);
507 
508 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
509 
510 	return duplicate;
511 }
512 
513 /**
514  * e_source_authentication_set_host:
515  * @extension: an #ESourceAuthentication
516  * @host: (nullable): a host name, or %NULL
517  *
518  * Sets the host name used to authenticate to a remote account.
519  *
520  * The internal copy of @host is automatically stripped of leading and
521  * trailing whitespace.  If the resulting string is empty, %NULL is set
522  * instead.
523  *
524  * Since: 3.6
525  **/
526 void
e_source_authentication_set_host(ESourceAuthentication * extension,const gchar * host)527 e_source_authentication_set_host (ESourceAuthentication *extension,
528                                   const gchar *host)
529 {
530 	g_return_if_fail (E_IS_SOURCE_AUTHENTICATION (extension));
531 
532 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
533 
534 	if (e_util_strcmp0 (extension->priv->host, host) == 0) {
535 		e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
536 		return;
537 	}
538 
539 	g_free (extension->priv->host);
540 	extension->priv->host = e_util_strdup_strip (host);
541 
542 	source_authentication_update_connectable (extension);
543 
544 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
545 
546 	g_object_notify (G_OBJECT (extension), "host");
547 
548 	/* Changing the host also changes the connectable. */
549 	g_object_notify (G_OBJECT (extension), "connectable");
550 }
551 
552 /**
553  * e_source_authentication_get_method:
554  * @extension: an #ESourceAuthentication
555  *
556  * Returns the authentication method for a remote account.  There are
557  * no pre-defined method names; backends are free to set this however
558  * they wish.  If authentication is not required for a remote account,
559  * the convention is to set #ESourceAuthentication:method to "none".
560  *
561  * Returns: (nullable): the authentication method for a remote account
562  *
563  * Since: 3.6
564  **/
565 const gchar *
e_source_authentication_get_method(ESourceAuthentication * extension)566 e_source_authentication_get_method (ESourceAuthentication *extension)
567 {
568 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), NULL);
569 
570 	return extension->priv->method;
571 }
572 
573 /**
574  * e_source_authentication_dup_method:
575  * @extension: an #ESourceAuthentication
576  *
577  * Thread-safe variation of e_source_authentication_get_method().
578  * Use this function when accessing @extension from multiple threads.
579  *
580  * The returned string should be freed with g_free() when no longer needed.
581  *
582  * Returns: (nullable): a newly-allocated copy of #ESourceAuthentication:method
583  *
584  * Since: 3.6
585  **/
586 gchar *
e_source_authentication_dup_method(ESourceAuthentication * extension)587 e_source_authentication_dup_method (ESourceAuthentication *extension)
588 {
589 	const gchar *protected;
590 	gchar *duplicate;
591 
592 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), NULL);
593 
594 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
595 
596 	protected = e_source_authentication_get_method (extension);
597 	duplicate = g_strdup (protected);
598 
599 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
600 
601 	return duplicate;
602 }
603 
604 /**
605  * e_source_authentication_set_method:
606  * @extension: an #ESourceAuthentication
607  * @method: (nullable): authentication method, or %NULL
608  *
609  * Sets the authentication method for a remote account.  There are no
610  * pre-defined method names; backends are free to set this however they
611  * wish.  If authentication is not required for a remote account, the
612  * convention is to set the method to "none".  In keeping with that
613  * convention, #ESourceAuthentication:method will be set to "none" if
614  * @method is %NULL or an empty string.
615  *
616  * Since: 3.6
617  **/
618 void
e_source_authentication_set_method(ESourceAuthentication * extension,const gchar * method)619 e_source_authentication_set_method (ESourceAuthentication *extension,
620                                     const gchar *method)
621 {
622 	g_return_if_fail (E_IS_SOURCE_AUTHENTICATION (extension));
623 
624 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
625 
626 	if (e_util_strcmp0 (extension->priv->method, method) == 0) {
627 		e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
628 		return;
629 	}
630 
631 	g_free (extension->priv->method);
632 	extension->priv->method = e_util_strdup_strip (method);
633 
634 	if (extension->priv->method == NULL)
635 		extension->priv->method = g_strdup ("none");
636 
637 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
638 
639 	g_object_notify (G_OBJECT (extension), "method");
640 }
641 
642 /**
643  * e_source_authentication_get_port:
644  * @extension: an #ESourceAuthentication
645  *
646  * Returns the port number used to authenticate to a remote account.
647  *
648  * Returns: the port number of a remote account
649  *
650  * Since: 3.6
651  **/
652 guint16
e_source_authentication_get_port(ESourceAuthentication * extension)653 e_source_authentication_get_port (ESourceAuthentication *extension)
654 {
655 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), 0);
656 
657 	return extension->priv->port;
658 }
659 
660 /**
661  * e_source_authentication_set_port:
662  * @extension: an #ESourceAuthentication
663  * @port: a port number
664  *
665  * Sets the port number used to authenticate to a remote account.
666  *
667  * Since: 3.6
668  **/
669 void
e_source_authentication_set_port(ESourceAuthentication * extension,guint16 port)670 e_source_authentication_set_port (ESourceAuthentication *extension,
671                                   guint16 port)
672 {
673 	g_return_if_fail (E_SOURCE_AUTHENTICATION (extension));
674 
675 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
676 
677 	if (extension->priv->port == port) {
678 		e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
679 		return;
680 	}
681 
682 	extension->priv->port = port;
683 
684 	source_authentication_update_connectable (extension);
685 
686 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
687 
688 	g_object_notify (G_OBJECT (extension), "port");
689 
690 	/* Changing the port also changes the connectable. */
691 	g_object_notify (G_OBJECT (extension), "connectable");
692 }
693 
694 /**
695  * e_source_authentication_get_proxy_uid:
696  * @extension: an #ESourceAuthentication
697  *
698  * Returns the #ESource:uid of the #ESource that holds network proxy
699  * settings for use when connecting to a remote account.
700  *
701  * Returns: the proxy profile #ESource:uid
702  *
703  * Since: 3.12
704  **/
705 const gchar *
e_source_authentication_get_proxy_uid(ESourceAuthentication * extension)706 e_source_authentication_get_proxy_uid (ESourceAuthentication *extension)
707 {
708 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), NULL);
709 
710 	return extension->priv->proxy_uid;
711 }
712 
713 /**
714  * e_source_authentication_dup_proxy_uid:
715  * @extension: an #ESourceAuthentication
716  *
717  * Thread-safe variation of e_source_authentication_get_proxy_uid().
718  * Use this function when accessing @extension from multiple threads.
719  *
720  * The returned string should be freed with g_free() when no longer needed.
721  *
722  * Returns: a newly-allocated copy of #ESourceAuthentication:proxy-uid
723  *
724  * Since: 3.12
725  **/
726 gchar *
e_source_authentication_dup_proxy_uid(ESourceAuthentication * extension)727 e_source_authentication_dup_proxy_uid (ESourceAuthentication *extension)
728 {
729 	const gchar *protected;
730 	gchar *duplicate;
731 
732 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), NULL);
733 
734 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
735 
736 	protected = e_source_authentication_get_proxy_uid (extension);
737 	duplicate = g_strdup (protected);
738 
739 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
740 
741 	return duplicate;
742 }
743 
744 /**
745  * e_source_authentication_set_proxy_uid:
746  * @extension: an #ESourceAuthentication
747  * @proxy_uid: the proxy profile #ESource:uid
748  *
749  * Sets the #ESource:uid of the #ESource that holds network proxy settings
750  * for use when connecting to a remote account.
751  *
752  * Since: 3.12
753  **/
754 void
e_source_authentication_set_proxy_uid(ESourceAuthentication * extension,const gchar * proxy_uid)755 e_source_authentication_set_proxy_uid (ESourceAuthentication *extension,
756                                        const gchar *proxy_uid)
757 {
758 	g_return_if_fail (E_IS_SOURCE_AUTHENTICATION (extension));
759 	g_return_if_fail (proxy_uid != NULL);
760 
761 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
762 
763 	if (g_strcmp0 (proxy_uid, extension->priv->proxy_uid) == 0) {
764 		e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
765 		return;
766 	}
767 
768 	g_free (extension->priv->proxy_uid);
769 	extension->priv->proxy_uid = g_strdup (proxy_uid);
770 
771 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
772 
773 	g_object_notify (G_OBJECT (extension), "proxy-uid");
774 }
775 
776 /**
777  * e_source_authentication_get_remember_password:
778  * @extension: an #ESourceAuthentication
779  *
780  * Returns whether to offer to remember the provided password by default
781  * in password prompts.  This way, if the user unchecks the option it will
782  * be unchecked by default in future password prompts.
783  *
784  * Returns: whether to offer to remember the password by default
785  *
786  * Since: 3.10
787  **/
788 gboolean
e_source_authentication_get_remember_password(ESourceAuthentication * extension)789 e_source_authentication_get_remember_password (ESourceAuthentication *extension)
790 {
791 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), FALSE);
792 
793 	return extension->priv->remember_password;
794 }
795 
796 /**
797  * e_source_authentication_set_remember_password:
798  * @extension: an #ESourceAuthentication
799  * @remember_password: whether to offer to remember the password by default
800  *
801  * Sets whether to offer to remember the provided password by default in
802  * password prompts.  This way, if the user unchecks the option it will be
803  * unchecked by default in future password prompts.
804  *
805  * Since: 3.10
806  **/
807 void
e_source_authentication_set_remember_password(ESourceAuthentication * extension,gboolean remember_password)808 e_source_authentication_set_remember_password (ESourceAuthentication *extension,
809                                                gboolean remember_password)
810 {
811 	g_return_if_fail (E_IS_SOURCE_AUTHENTICATION (extension));
812 
813 	if (extension->priv->remember_password == remember_password)
814 		return;
815 
816 	extension->priv->remember_password = remember_password;
817 
818 	g_object_notify (G_OBJECT (extension), "remember-password");
819 }
820 
821 /**
822  * e_source_authentication_get_user:
823  * @extension: an #ESourceAuthentication
824  *
825  * Returns the user name used to authenticate to a remote account.
826  *
827  * Returns: (nullable): the user name of a remote account
828  *
829  * Since: 3.6
830  **/
831 const gchar *
e_source_authentication_get_user(ESourceAuthentication * extension)832 e_source_authentication_get_user (ESourceAuthentication *extension)
833 {
834 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), NULL);
835 
836 	return extension->priv->user;
837 }
838 
839 /**
840  * e_source_authentication_dup_user:
841  * @extension: an #ESourceAuthentication
842  *
843  * Thread-safe variation of e_source_authentication_get_user().
844  * Use this function when accessing @extension from multiple threads.
845  *
846  * The returned string should be freed with g_free() when no longer needed.
847  *
848  * Returns: (nullable): a newly-allocated copy of #ESourceAuthentication:user
849  *
850  * Since: 3.6
851  **/
852 gchar *
e_source_authentication_dup_user(ESourceAuthentication * extension)853 e_source_authentication_dup_user (ESourceAuthentication *extension)
854 {
855 	const gchar *protected;
856 	gchar *duplicate;
857 
858 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), NULL);
859 
860 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
861 
862 	protected = e_source_authentication_get_user (extension);
863 	duplicate = g_strdup (protected);
864 
865 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
866 
867 	return duplicate;
868 }
869 
870 /**
871  * e_source_authentication_set_user:
872  * @extension: an #ESourceAuthentication
873  * @user: (nullable): a user name, or %NULL
874  *
875  * Sets the user name used to authenticate to a remote account.
876  *
877  * The internal copy of @user is automatically stripped of leading and
878  * trailing whitespace.  If the resulting string is empty, %NULL is set
879  * instead.
880  *
881  * Since: 3.6
882  **/
883 void
e_source_authentication_set_user(ESourceAuthentication * extension,const gchar * user)884 e_source_authentication_set_user (ESourceAuthentication *extension,
885                                   const gchar *user)
886 {
887 	g_return_if_fail (E_IS_SOURCE_AUTHENTICATION (extension));
888 
889 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
890 
891 	if (e_util_strcmp0 (extension->priv->user, user) == 0) {
892 		e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
893 		return;
894 	}
895 
896 	g_free (extension->priv->user);
897 	extension->priv->user = e_util_strdup_strip (user);
898 
899 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
900 
901 	g_object_notify (G_OBJECT (extension), "user");
902 }
903 
904 /**
905  * e_source_authentication_get_credential_name:
906  * @extension: an #ESourceAuthentication
907  *
908  * Returns the credential name used to pass the stored or gathered credential
909  * (like password) into the e_source_invoke_authenticate(). This is
910  * a counterpart of the authentication method. The %NULL means to use
911  * the default name, which is #E_SOURCE_CREDENTIAL_PASSWORD.
912  *
913  * Returns: (nullable): the credential name to use for authentication, or %NULL
914  *
915  * Since: 3.16
916  **/
917 const gchar *
e_source_authentication_get_credential_name(ESourceAuthentication * extension)918 e_source_authentication_get_credential_name (ESourceAuthentication *extension)
919 {
920 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), NULL);
921 
922 	return extension->priv->credential_name;
923 }
924 
925 /**
926  * e_source_authentication_dup_credential_name:
927  * @extension: an #ESourceAuthentication
928  *
929  * Thread-safe variation of e_source_authentication_get_credential_name().
930  * Use this function when accessing @extension from multiple threads.
931  *
932  * The returned string should be freed with g_free() when no longer needed.
933  *
934  * Returns: (nullable): a newly-allocated copy of #ESourceAuthentication:credential-name
935  *
936  * Since: 3.16
937  **/
938 gchar *
e_source_authentication_dup_credential_name(ESourceAuthentication * extension)939 e_source_authentication_dup_credential_name (ESourceAuthentication *extension)
940 {
941 	const gchar *protected;
942 	gchar *duplicate;
943 
944 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), NULL);
945 
946 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
947 
948 	protected = e_source_authentication_get_credential_name (extension);
949 	duplicate = g_strdup (protected);
950 
951 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
952 
953 	return duplicate;
954 }
955 
956 /**
957  * e_source_authentication_set_credential_name:
958  * @extension: an #ESourceAuthentication
959  * @credential_name: (nullable): a credential name, or %NULL
960  *
961  * Sets the credential name used to pass the stored or gathered credential
962  * (like password) into the e_source_invoke_authenticate(). This is
963  * a counterpart of the authentication method. The %NULL means to use
964  * the default name, which is #E_SOURCE_CREDENTIAL_PASSWORD.
965  *
966  * The internal copy of @credential_name is automatically stripped
967  * of leading and trailing whitespace. If the resulting string is
968  * empty, %NULL is set instead.
969  *
970  * Since: 3.16
971  **/
972 void
e_source_authentication_set_credential_name(ESourceAuthentication * extension,const gchar * credential_name)973 e_source_authentication_set_credential_name (ESourceAuthentication *extension,
974 					     const gchar *credential_name)
975 {
976 	g_return_if_fail (E_IS_SOURCE_AUTHENTICATION (extension));
977 
978 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
979 
980 	if (e_util_strcmp0 (extension->priv->credential_name, credential_name) == 0) {
981 		e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
982 		return;
983 	}
984 
985 	g_free (extension->priv->credential_name);
986 	extension->priv->credential_name = e_util_strdup_strip (credential_name);
987 
988 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
989 
990 	g_object_notify (G_OBJECT (extension), "credential-name");
991 }
992 
993 /**
994  * e_source_authentication_get_is_external:
995  * @extension: an #ESourceAuthentication
996  *
997  * Get if the authentication is done by an external application such as a
998  * Single Sign On application (e.g. GNOME Online Accounts)
999  *
1000  * Returns: %TRUE if the authentication is done by an external application,
1001  * %FALSE otherwise
1002  *
1003  * Since: 3.36
1004  **/
1005 gboolean
e_source_authentication_get_is_external(ESourceAuthentication * extension)1006 e_source_authentication_get_is_external (ESourceAuthentication *extension)
1007 {
1008 	g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), FALSE);
1009 
1010 	return extension->priv->is_external;
1011 }
1012 
1013 /**
1014  * e_source_authentication_set_is_external:
1015  * @extension: an #ESourceAuthentication
1016  * @is_external: %TRUE if the authentication is done using an external
1017  * application, %FALSE otherwise
1018  *
1019  * Set if the authentication is done by an external application such as a
1020  * Single Sign On application (e.g. GNOME Online Accounts)
1021  *
1022  * Since: 3.36
1023  **/
1024 void
e_source_authentication_set_is_external(ESourceAuthentication * extension,gboolean is_external)1025 e_source_authentication_set_is_external (ESourceAuthentication *extension,
1026                                          gboolean is_external)
1027 {
1028 	g_return_if_fail (E_IS_SOURCE_AUTHENTICATION (extension));
1029 
1030 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
1031 
1032 	if (extension->priv->is_external == is_external) {
1033 		e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1034 		return;
1035 	}
1036 
1037 	extension->priv->is_external = is_external;
1038 
1039 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1040 
1041 	g_object_notify (G_OBJECT (extension), "is-external");
1042 }
1043