Add new ESource classes.
[platform/upstream/evolution-data-server.git] / libedataserver / e-source-security.c
1 /*
2  * e-source-security.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-security
21  * @include: libedataserver/e-source-security.h
22  * @short_description: #ESource extension for security settings
23  *
24  * The #ESourceSecurity extension tracks settings for establishing a
25  * secure connection with a remote server.
26  *
27  * Access the extension as follows:
28  *
29  * |[
30  *   #include <libedataserver/e-source-security.h>
31  *
32  *   ESourceSecurity *extension;
33  *
34  *   extension = e_source_get_extension (source, E_SOURCE_EXTENSION_SECURITY);
35  * ]|
36  **/
37
38 #include "e-source-security.h"
39
40 #include <libedataserver/e-data-server-util.h>
41
42 #define E_SOURCE_SECURITY_GET_PRIVATE(obj) \
43         (G_TYPE_INSTANCE_GET_PRIVATE \
44         ((obj), E_TYPE_SOURCE_SECURITY, ESourceSecurityPrivate))
45
46 #define SECURE_METHOD "tls"
47
48 struct _ESourceSecurityPrivate {
49         GMutex *property_lock;
50         gchar *method;
51 };
52
53 enum {
54         PROP_0,
55         PROP_METHOD,
56         PROP_SECURE
57 };
58
59 G_DEFINE_TYPE (
60         ESourceSecurity,
61         e_source_security,
62         E_TYPE_SOURCE_EXTENSION)
63
64 static void
65 source_security_set_property (GObject *object,
66                               guint property_id,
67                               const GValue *value,
68                               GParamSpec *pspec)
69 {
70         switch (property_id) {
71                 case PROP_METHOD:
72                         e_source_security_set_method (
73                                 E_SOURCE_SECURITY (object),
74                                 g_value_get_string (value));
75                         return;
76
77                 case PROP_SECURE:
78                         e_source_security_set_secure (
79                                 E_SOURCE_SECURITY (object),
80                                 g_value_get_boolean (value));
81                         return;
82         }
83
84         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
85 }
86
87 static void
88 source_security_get_property (GObject *object,
89                               guint property_id,
90                               GValue *value,
91                               GParamSpec *pspec)
92 {
93         switch (property_id) {
94                 case PROP_METHOD:
95                         g_value_take_string (
96                                 value,
97                                 e_source_security_dup_method (
98                                 E_SOURCE_SECURITY (object)));
99                         return;
100
101                 case PROP_SECURE:
102                         g_value_set_boolean (
103                                 value,
104                                 e_source_security_get_secure (
105                                 E_SOURCE_SECURITY (object)));
106                         return;
107         }
108
109         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
110 }
111
112 static void
113 source_security_finalize (GObject *object)
114 {
115         ESourceSecurityPrivate *priv;
116
117         priv = E_SOURCE_SECURITY_GET_PRIVATE (object);
118
119         g_mutex_free (priv->property_lock);
120
121         g_free (priv->method);
122
123         /* Chain up to parent's finalize() method. */
124         G_OBJECT_CLASS (e_source_security_parent_class)->finalize (object);
125 }
126
127 static void
128 e_source_security_class_init (ESourceSecurityClass *class)
129 {
130         GObjectClass *object_class;
131         ESourceExtensionClass *extension_class;
132
133         g_type_class_add_private (class, sizeof (ESourceSecurityPrivate));
134
135         object_class = G_OBJECT_CLASS (class);
136         object_class->set_property = source_security_set_property;
137         object_class->get_property = source_security_get_property;
138         object_class->finalize = source_security_finalize;
139
140         extension_class = E_SOURCE_EXTENSION_CLASS (class);
141         extension_class->name = E_SOURCE_EXTENSION_SECURITY;
142
143         g_object_class_install_property (
144                 object_class,
145                 PROP_METHOD,
146                 g_param_spec_string (
147                         "method",
148                         "Method",
149                         "Security method",
150                         "none",
151                         G_PARAM_READWRITE |
152                         G_PARAM_CONSTRUCT |
153                         G_PARAM_STATIC_STRINGS |
154                         E_SOURCE_PARAM_SETTING));
155
156         g_object_class_install_property (
157                 object_class,
158                 PROP_SECURE,
159                 g_param_spec_boolean (
160                         "secure",
161                         "Secure",
162                         "Secure the network connection",
163                         FALSE,
164                         G_PARAM_READWRITE |
165                         G_PARAM_STATIC_STRINGS));
166 }
167
168 static void
169 e_source_security_init (ESourceSecurity *extension)
170 {
171         extension->priv = E_SOURCE_SECURITY_GET_PRIVATE (extension);
172         extension->priv->property_lock = g_mutex_new ();
173 }
174
175 /**
176  * e_source_security_get_method:
177  * @extension: an #ESourceSecurity
178  *
179  * Returns the method used to establish a secure network connection to a
180  * remote account.  There are no pre-defined method names; backends are
181  * free to set this however they wish.  If a secure connection is not
182  * desired, the convention is to set #ESourceSecurity:method to "none".
183  *
184  * Returns: the method used to establish a secure network connection
185  *
186  * Since: 3.6
187  **/
188 const gchar *
189 e_source_security_get_method (ESourceSecurity *extension)
190 {
191         g_return_val_if_fail (E_IS_SOURCE_SECURITY (extension), NULL);
192
193         return extension->priv->method;
194 }
195
196 /**
197  * e_source_security_dup_method:
198  * @extension: an #ESourceSecurity
199  *
200  * Thread-safe variation of e_source_security_get_method().
201  * Use this function when accessing @extension from multiple threads.
202  *
203  * The returned string should be freed with g_free() when no longer needed.
204  *
205  * Returns: a newly-allocated copy of #ESourceSecurity:method
206  *
207  * Since: 3.6
208  **/
209 gchar *
210 e_source_security_dup_method (ESourceSecurity *extension)
211 {
212         const gchar *protected;
213         gchar *duplicate;
214
215         g_return_val_if_fail (E_IS_SOURCE_SECURITY (extension), NULL);
216
217         g_mutex_lock (extension->priv->property_lock);
218
219         protected = e_source_security_get_method (extension);
220         duplicate = g_strdup (protected);
221
222         g_mutex_unlock (extension->priv->property_lock);
223
224         return duplicate;
225 }
226
227 /**
228  * e_source_security_set_method:
229  * @extension: an #ESourceSecurity
230  * @method: (allow-none): security method, or %NULL
231  *
232  * Sets the method used to establish a secure network connection to a
233  * remote account.  There are no pre-defined method names; backends are
234  * free to set this however they wish.  If a secure connection is not
235  * desired, the convention is to set #ESourceSecurity:method to "none".
236  * In keeping with that convention, #ESourceSecurity:method will be set
237  * to "none" if @method is %NULL or an empty string.
238  *
239  * Since: 3.6
240  **/
241 void
242 e_source_security_set_method (ESourceSecurity *extension,
243                               const gchar *method)
244 {
245         GObject *object;
246
247         g_return_if_fail (E_IS_SOURCE_SECURITY (extension));
248
249         g_mutex_lock (extension->priv->property_lock);
250
251         g_free (extension->priv->method);
252         extension->priv->method = e_util_strdup_strip (method);
253
254         if (extension->priv->method == NULL)
255                 extension->priv->method = g_strdup ("none");
256
257         g_mutex_unlock (extension->priv->property_lock);
258
259         object = G_OBJECT (extension);
260         g_object_freeze_notify (object);
261         g_object_notify (object, "method");
262         g_object_notify (object, "secure");
263         g_object_thaw_notify (object);
264 }
265
266 /**
267  * e_source_security_get_secure:
268  * @extension: an #ESourceSecurity
269  *
270  * This is a convenience function which returns whether a secure network
271  * connection is desired, regardless of the method used.  This relies on
272  * the convention of setting #ESourceSecurity:method to "none" when a
273  * secure network connection is <emphasis>not</emphasis> desired.
274  *
275  * Returns: whether a secure network connection is desired
276  *
277  * Since: 3.6
278  **/
279 gboolean
280 e_source_security_get_secure (ESourceSecurity *extension)
281 {
282         const gchar *method;
283
284         g_return_val_if_fail (E_IS_SOURCE_SECURITY (extension), FALSE);
285
286         method = e_source_security_get_method (extension);
287         g_return_val_if_fail (method != NULL, FALSE);
288
289         return (g_strcmp0 (method, "none") != 0);
290 }
291
292 /**
293  * e_source_security_set_secure:
294  * @extension: an #ESourceSecurity
295  * @secure: whether a secure network connection is desired
296  *
297  * This function provides a simpler way to set #ESourceSecurity:method
298  * when using a secure network connection is a yes or no option and the
299  * exact method name is unimportant.  If @secure is %FALSE, the
300  * #ESourceSecurity:method property is set to "none".  If @secure is
301  * %TRUE, the function assumes the backend will use Transport Layer
302  * Security and sets the #ESourceSecurity:method property to "tls".
303  *
304  * Since: 3.6
305  **/
306 void
307 e_source_security_set_secure (ESourceSecurity *extension,
308                               gboolean secure)
309 {
310         const gchar *method;
311
312         g_return_if_fail (E_IS_SOURCE_SECURITY (extension));
313
314         method = secure ? SECURE_METHOD : "none";
315         e_source_security_set_method (extension, method);
316 }