* fix the issues with account-store and account-mgr:
[modest] / src / modest-account-mgr.c
1 /* modest-account-mgr.c */
2
3 /* insert (c)/licensing information) */
4
5 #include <string.h>
6 #include "modest-account-mgr.h"
7
8 /* 'private'/'protected' functions */
9 static void    modest_account_mgr_class_init    (ModestAccountMgrClass *klass);
10 static void    modest_account_mgr_init          (ModestAccountMgr *obj);
11 static void    modest_account_mgr_finalize      (GObject *obj);
12
13 static gchar*   get_account_keyname (const gchar *accname, const gchar *name);
14 static gchar*   get_server_account_keyname (const gchar *accname, const gchar *name);
15
16 /* list my signals */
17 enum {
18         /* MY_SIGNAL_1, */
19         /* MY_SIGNAL_2, */
20         LAST_SIGNAL
21 };
22
23 typedef struct _ModestAccountMgrPrivate ModestAccountMgrPrivate;
24 struct _ModestAccountMgrPrivate {
25         ModestConf *modest_conf;
26 };
27 #define MODEST_ACCOUNT_MGR_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
28                                                 MODEST_TYPE_ACCOUNT_MGR, \
29                                                 ModestAccountMgrPrivate))
30 /* globals */
31 static GObjectClass *parent_class = NULL;
32
33 /* uncomment the following if you have defined any signals */
34 /* static guint signals[LAST_SIGNAL] = {0}; */
35
36 GType
37 modest_account_mgr_get_type (void)
38 {
39         static GType my_type = 0;
40         if (!my_type) {
41                 static const GTypeInfo my_info = {
42                         sizeof(ModestAccountMgrClass),
43                         NULL,           /* base init */
44                         NULL,           /* base finalize */
45                         (GClassInitFunc) modest_account_mgr_class_init,
46                         NULL,           /* class finalize */
47                         NULL,           /* class data */
48                         sizeof(ModestAccountMgr),
49                         1,              /* n_preallocs */
50                         (GInstanceInitFunc) modest_account_mgr_init,
51                 };
52
53                 my_type = g_type_register_static (G_TYPE_OBJECT,
54                                                   "ModestAccountMgr",
55                                                   &my_info, 0);
56         }
57         return my_type;
58 }
59
60 static void
61 modest_account_mgr_class_init (ModestAccountMgrClass *klass)
62 {
63         GObjectClass *gobject_class;
64         gobject_class = (GObjectClass*) klass;
65
66         parent_class            = g_type_class_peek_parent (klass);
67         gobject_class->finalize = modest_account_mgr_finalize;
68
69         g_type_class_add_private (gobject_class, sizeof(ModestAccountMgrPrivate));
70
71         /* signal definitions go here, e.g.: */
72 /*      signals[MY_SIGNAL_1] = */
73 /*              g_signal_new ("my_signal_1",....); */
74 /*      signals[MY_SIGNAL_2] = */
75 /*              g_signal_new ("my_signal_2",....); */
76 /*      etc. */
77 }
78
79
80 static void
81 modest_account_mgr_init (ModestAccountMgr *obj)
82 {
83         ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(obj);
84         priv->modest_conf = NULL;
85 }
86
87 static void
88 modest_account_mgr_finalize (GObject *obj)
89 {
90         ModestAccountMgr *self = MODEST_ACCOUNT_MGR(obj);
91         ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
92
93         g_object_unref (G_OBJECT(priv->modest_conf));
94         priv->modest_conf = NULL;
95 }
96
97 GObject*
98 modest_account_mgr_new (ModestConf *conf)
99 {
100         GObject *obj;
101         ModestAccountMgrPrivate *priv;
102
103         g_return_val_if_fail (conf, NULL);
104
105         obj  = G_OBJECT(g_object_new(MODEST_TYPE_ACCOUNT_MGR, NULL));
106         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(obj);
107
108         /*
109          * increase the ref count on the modest_conf. Normally, the
110          * ModestConf should outlive the ModestAccountMgr though
111          */
112         g_object_ref(G_OBJECT(priv->modest_conf = conf));
113         return obj;
114 }
115
116
117
118 gboolean
119 modest_account_mgr_add_account (ModestAccountMgr *self, const gchar* name,
120                                 const gchar *store_account,
121                                 const gchar *transport_account,
122                                 GError **err)
123 {
124         ModestAccountMgrPrivate *priv;
125         gchar *key;
126         gboolean retval;
127
128         g_return_val_if_fail (self, FALSE);
129         g_return_val_if_fail (name, FALSE);
130
131         if (modest_account_mgr_account_exists (self, name, err)) {
132                 g_warning ("account already exists");
133                 //return FALSE;
134         }
135         /*
136          * we create the account by adding an account 'dir', with the name <name>,
137          * and in that the 'display_name' string key
138          */
139         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
140
141         key = get_account_keyname (name, MODEST_ACCOUNT_DISPLAY_NAME);
142         modest_conf_set_string (priv->modest_conf, key, name, err);
143         g_free (key);
144
145         if (store_account) {
146                 key = get_account_keyname (name, MODEST_ACCOUNT_STORE_ACCOUNT);
147                 modest_conf_set_string (priv->modest_conf, key, store_account, err);
148                 g_free (key);
149         }
150
151         if (transport_account) {
152                 key = get_account_keyname (name, MODEST_ACCOUNT_TRANSPORT_ACCOUNT);
153                 modest_conf_set_string (priv->modest_conf, key, transport_account, err);
154                 g_free (key);
155         }
156
157         return TRUE; /* TODO: error handling */
158 }
159
160
161 gboolean
162 modest_account_mgr_remove_account (ModestAccountMgr *self, const gchar* name,
163                            GError **err)
164 {
165         ModestAccountMgrPrivate *priv;
166         gchar *key;
167         gboolean retval;
168
169         g_return_val_if_fail (self, FALSE);
170         g_return_val_if_fail (name, FALSE);
171
172         if (!modest_account_mgr_account_exists (self, name, err)) {
173                 g_warning ("account doest not exist");
174                 return FALSE;
175         }
176
177         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
178         key = get_account_keyname (name, NULL);
179
180         retval = modest_conf_remove_key (priv->modest_conf, key, NULL);
181
182         g_free (key);
183         return retval;
184 }
185
186
187 static const gchar*
188 null_means_empty(const gchar* str)
189 {
190         return str ? str : "";
191 }
192
193
194 gboolean
195 modest_account_mgr_add_server_account    (ModestAccountMgr *self,
196                                           const gchar *name,
197                                           const gchar *hostname,
198                                           const gchar *username,
199                                           const gchar *password,
200                                           const gchar *proto)
201 {
202         ModestAccountMgrPrivate *priv;
203         gchar *acckey, *key;
204
205         g_return_val_if_fail (self, FALSE);
206         g_return_val_if_fail (name, FALSE);
207
208         /* TODO: check already exists */
209
210         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
211         acckey = g_strconcat (MODEST_SERVER_ACCOUNT_NAMESPACE, "/",
212                               name, NULL);
213
214         if (modest_conf_key_exists(priv->modest_conf, acckey, NULL)) {
215                 g_warning ("server account %s already exists", name);
216                 g_free (acckey);
217                 return FALSE;
218         }
219
220         /* hostname */
221         key = g_strconcat (acckey, "/", MODEST_ACCOUNT_HOSTNAME, NULL);
222         modest_conf_set_string (priv->modest_conf, key,
223                                 null_means_empty(hostname), NULL);
224         g_free (key);
225
226         /* username */
227         key = g_strconcat (acckey, "/", MODEST_ACCOUNT_USERNAME, NULL);
228         modest_conf_set_string (priv->modest_conf, key,
229                                 null_means_empty(username), NULL);
230         g_free (key);
231
232         /* password */
233         key = g_strconcat (acckey, "/", MODEST_ACCOUNT_PASSWORD, NULL);
234         modest_conf_set_string (priv->modest_conf, key,
235                                 null_means_empty(password), NULL);
236         g_free (key);
237
238         /* proto */
239         key = g_strconcat (acckey, "/", MODEST_ACCOUNT_PROTO, NULL);
240         modest_conf_set_string (priv->modest_conf, key,
241                                 null_means_empty(proto),
242                                 NULL);
243         g_free (key);
244
245         return TRUE; /* FIXME: better error checking */
246 }
247
248 gboolean
249 modest_account_mgr_remove_server_account    (ModestAccountMgr *self,
250                                              const gchar *name,
251                                              GError **err)
252 {
253         ModestAccountMgrPrivate *priv;
254         gchar *acckey, *key;
255         gboolean retval;
256
257         g_return_val_if_fail (self, FALSE);
258         g_return_val_if_fail (name, FALSE);
259
260         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
261
262         acckey = g_strconcat (MODEST_SERVER_ACCOUNT_NAMESPACE, "/",
263                               name, NULL);
264
265         if (!modest_conf_key_exists(priv->modest_conf, acckey, NULL)) {
266                 g_warning ("server account %s does not exist exist", name);
267                 g_free (acckey);
268                 return FALSE;
269         }
270
271         retval = modest_conf_remove_key (priv->modest_conf, acckey, NULL);
272         g_free (acckey);
273
274         return retval;
275 }
276
277
278 /* strip the first /n/ character from each element */
279 /* caller must make sure all elements are strings with
280  * length >= n, and also that data can be freed.
281  */
282 static GSList*
283 strip_prefix_from_elements (GSList *lst, guint n)
284 {
285         GSList *cursor = lst;
286         while (cursor) {
287                 gchar *str = (gchar*)cursor->data;
288                 cursor->data = g_strdup (str + n);
289                 g_free (str);
290                 cursor = cursor->next;
291         }
292         return lst;
293 }
294
295
296
297 GSList*
298 modest_account_mgr_server_account_names   (ModestAccountMgr *self,
299                                            const gchar*    account_name,
300                                            ModestProtoType type,
301                                            const gchar*    proto,
302                                            gboolean only_enabled)
303 {
304         GSList *accounts;
305         GSList *cursor;
306         ModestAccountMgrPrivate *priv;
307         const size_t prefix_len =
308                 strlen (MODEST_SERVER_ACCOUNT_NAMESPACE "/");
309         
310         g_return_val_if_fail (self, NULL);
311
312         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
313         accounts = modest_conf_list_subkeys (priv->modest_conf,
314                                              MODEST_SERVER_ACCOUNT_NAMESPACE,
315                                              NULL);
316
317         /* no restrictions, return everything */
318         if (type == MODEST_PROTO_TYPE_ANY && !proto)
319                 return strip_prefix_from_elements (accounts,prefix_len);
320         
321         /* otherwise, filter out the none-matching ones */
322         cursor = accounts;
323         while (cursor) {
324                 gchar *keyspace, *proto_key, *acc_proto;
325
326                 keyspace  = (gchar*) cursor->data;
327                 proto_key = g_strconcat (keyspace, "/", MODEST_ACCOUNT_PROTO, NULL);
328                 acc_proto = modest_conf_get_string (priv->modest_conf, proto_key,
329                                                     NULL);
330                 g_free (proto_key);
331
332                 if ((!acc_proto) ||                              /* proto not defined? */
333                     (type != MODEST_PROTO_TYPE_ANY &&            /* proto type ...     */
334                      modest_proto_type (acc_proto) != type) ||   /* ... matches?       */
335                     (proto && strcmp(proto,acc_proto) != 0)) {   /* proto matches?     */
336                         /* no match: remove from the list */
337                         GSList *nxt = cursor->next;
338                         g_free (acc_proto);
339                         accounts = g_slist_delete_link (accounts, cursor);
340                         cursor = nxt;
341                 } else
342                         cursor = cursor->next;
343         }
344
345         return strip_prefix_from_elements (accounts, prefix_len);
346 }
347
348
349
350 GSList*
351 modest_account_mgr_account_names  (ModestAccountMgr *self, GError **err)
352 {
353         GSList *accounts, *cursor;
354         ModestAccountMgrPrivate *priv;
355         const size_t prefix_len =
356                 strlen (MODEST_ACCOUNT_NAMESPACE "/");
357
358
359         g_return_val_if_fail (self, NULL);
360
361         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
362
363         accounts = modest_conf_list_subkeys (priv->modest_conf,
364                                              MODEST_ACCOUNT_NAMESPACE,
365                                              err);
366         return strip_prefix_from_elements (accounts, prefix_len);       
367 }
368
369
370
371 static gchar*
372 get_account_string (ModestAccountMgr *self, const gchar *name,
373                     const gchar *key, gboolean server_account,
374                     GError **err)
375 {
376         ModestAccountMgrPrivate *priv;
377         
378         gchar *keyname;
379         gchar * retval;
380         
381         g_return_val_if_fail (self, NULL);
382         g_return_val_if_fail (name, NULL);
383         g_return_val_if_fail (key, NULL);
384
385         if (server_account)
386                 keyname = get_server_account_keyname (name, key);
387         else
388                 keyname = get_account_keyname (name, key);
389         
390         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
391         retval = modest_conf_get_string (priv->modest_conf,keyname,err);
392         g_free (keyname);
393         
394         return retval;
395 }
396
397
398 gchar*
399 modest_account_mgr_get_server_account_string (ModestAccountMgr *self, const gchar *name,
400                                            const gchar *key, GError **err)
401 {
402         return get_account_string (self, name, key, TRUE, err);
403 }
404
405 gchar*
406 modest_account_mgr_get_account_string (ModestAccountMgr *self, const gchar *name,
407                                     const gchar *key, GError **err)
408 {
409         return get_account_string (self, name, key, FALSE, err);
410 }
411
412
413
414 static gint
415 get_account_int (ModestAccountMgr *self, const gchar *name,
416                  const gchar *key, gboolean server_account,
417                  GError **err)
418 {
419         ModestAccountMgrPrivate *priv;
420         
421         gchar *keyname;
422         gint retval;
423
424         g_return_val_if_fail (self, -1);
425         g_return_val_if_fail (name, -1);
426         g_return_val_if_fail (key, -1);
427
428         if (server_account)
429                 keyname = get_server_account_keyname (name, key);
430         else
431                 keyname = get_account_keyname (name, key);
432
433         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
434         retval = modest_conf_get_int (priv->modest_conf,keyname,err);
435         g_free (keyname);
436         
437         return retval;
438 }
439
440
441 gint
442 modest_account_mgr_get_server_account_int (ModestAccountMgr *self, const gchar *name,
443                                            const gchar *key, GError **err)
444 {
445         return get_account_int (self, name, key, TRUE, err);
446 }
447
448 gint
449 modest_account_mgr_get_account_int (ModestAccountMgr *self, const gchar *name,
450                                     const gchar *key, GError **err)
451 {
452         return get_account_int (self, name, key, FALSE, err);
453 }
454
455
456
457 static gboolean
458 get_account_bool (ModestAccountMgr *self, const gchar *name,
459                   const gchar *key, gboolean server_account,
460                   GError **err)
461 {
462         ModestAccountMgrPrivate *priv;
463         
464         gchar *keyname;
465         gboolean retval;
466
467         g_return_val_if_fail (self, -1);
468         g_return_val_if_fail (name, -1);
469         g_return_val_if_fail (key, -1);
470         
471         if (server_account)
472                 keyname = get_server_account_keyname (name, key);
473         else
474                 keyname = get_account_keyname (name, key);
475
476         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
477         retval = modest_conf_get_int (priv->modest_conf,keyname,err);
478         g_free (keyname);
479         
480         return retval;
481 }
482
483
484
485 gint
486 modest_account_mgr_get_server_account_bool (ModestAccountMgr *self, const gchar *name,
487                                            const gchar *key, GError **err)
488 {
489         return get_account_bool (self, name, key, TRUE, err);
490 }
491
492 gint
493 modest_account_mgr_get_account_bool (ModestAccountMgr *self, const gchar *name,
494                                     const gchar *key, GError **err)
495 {
496         return get_account_bool (self, name, key, FALSE, err);
497 }
498
499
500
501
502
503 static gboolean
504 set_account_string  (ModestAccountMgr *self, const gchar *name,
505                      const gchar *key, const gchar* val, gboolean server_account,
506                      GError **err)
507 {
508         ModestAccountMgrPrivate *priv;
509         
510         gchar *keyname;
511         gboolean retval;
512
513         g_return_val_if_fail (self, FALSE);
514         g_return_val_if_fail (name, FALSE);
515         g_return_val_if_fail (key, FALSE);
516
517         if (server_account)
518                 keyname = get_server_account_keyname (name, key);
519         else
520                 keyname = get_account_keyname (name, key);
521
522         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
523
524         retval = modest_conf_set_string (priv->modest_conf,keyname,val,err);
525
526         g_free (keyname);
527         return retval;
528 }
529
530
531
532
533
534 gboolean
535 modest_account_mgr_set_server_account_string  (ModestAccountMgr *self, const gchar *name,
536                                                const gchar *key, const gchar* val,
537                                                GError **err)
538 {
539         return set_account_string (self, name, key, val, TRUE, err);
540 }
541
542
543
544 gboolean
545 modest_account_mgr_set_account_string  (ModestAccountMgr *self, const gchar *name,
546                                         const gchar *key, const gchar* val,
547                                         GError **err)
548 {
549         return set_account_string (self, name, key, val, FALSE, err);
550 }
551
552
553 static gboolean
554 set_account_int  (ModestAccountMgr *self, const gchar *name,
555                   const gchar *key, gboolean server_account, int val,
556                   GError **err)
557 {
558         ModestAccountMgrPrivate *priv;
559         
560         gchar *keyname;
561         gboolean retval;
562         
563         g_return_val_if_fail (self, FALSE);
564         g_return_val_if_fail (name, FALSE);
565         g_return_val_if_fail (key, FALSE);
566
567         if (server_account)
568                 keyname = get_server_account_keyname (name, key);
569         else
570                 keyname = get_account_keyname (name, key);
571
572         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
573         
574         retval = modest_conf_set_int (priv->modest_conf,keyname,val,err);
575
576         g_free (keyname);
577         return retval;
578 }
579
580
581
582 gboolean
583 modest_account_mgr_set_server_account_int (ModestAccountMgr *self, const gchar *name,
584                                            const gchar *key, int val,
585                                            GError **err)
586 {
587         return set_account_int (self, name, key, val, TRUE, err);
588 }
589
590
591 gboolean
592 modest_account_mgr_set_account_int  (ModestAccountMgr *self, const gchar *name,
593                                      const gchar *key, int val,
594                                      GError **err)
595 {
596         return set_account_int (self, name, key, val, FALSE, err);
597 }
598
599
600
601
602 static gboolean
603 set_account_bool  (ModestAccountMgr *self, const gchar *name,
604                    const gchar *key, gboolean server_account, gboolean val,
605                    GError **err)
606 {
607         ModestAccountMgrPrivate *priv;
608         
609         gchar *keyname;
610         gboolean retval;
611         
612         g_return_val_if_fail (self, FALSE);
613         g_return_val_if_fail (name, FALSE);
614         g_return_val_if_fail (key, FALSE);
615         
616         if (server_account)
617                 keyname = get_server_account_keyname (name, key);
618         else
619                 keyname = get_account_keyname (name, key);
620         
621         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
622         
623         retval = modest_conf_set_bool (priv->modest_conf,keyname,val,err);
624
625         g_free (keyname);
626         return retval;
627 }
628
629
630 gboolean
631 modest_account_mgr_set_server_account_bool  (ModestAccountMgr *self, const gchar *name,
632                                              const gchar *key, gboolean val,
633                                              GError **err)
634 {
635         return set_account_bool (self, name, key, val, TRUE, err);
636 }
637
638
639
640 gboolean
641 modest_account_mgr_set_account_bool  (ModestAccountMgr *self, const gchar *name,
642                                         const gchar *key, gboolean val,
643                                         GError **err)
644 {
645         return set_account_bool (self, name, key, val, FALSE, err);
646 }
647
648
649
650
651
652 gboolean
653 account_exists (ModestAccountMgr *self, const gchar *name, gboolean server_account,
654                 GError **err)
655 {
656         ModestAccountMgrPrivate *priv;
657
658         gchar *keyname;
659         gboolean retval;
660
661         g_return_val_if_fail (self, FALSE);
662         g_return_val_if_fail (name, FALSE);
663
664         if (server_account) 
665                 keyname = get_account_keyname (name, NULL);
666         else
667                 keyname = get_server_account_keyname (name, NULL);
668
669         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
670         retval = modest_conf_key_exists (priv->modest_conf,keyname,err);
671         
672         g_free (keyname);
673         return retval;
674 }
675
676
677 gboolean
678 modest_account_mgr_server_account_exists (ModestAccountMgr *self, const gchar *name,
679                                    GError **err)
680 {
681         return account_exists (self, name, TRUE, err);
682 }
683
684
685
686 gboolean
687 modest_account_mgr_account_exists (ModestAccountMgr *self, const gchar *name,
688                                    GError **err)
689 {
690         return account_exists (self, name, FALSE, err);
691 }
692
693
694
695 /* must be freed by caller */
696 static gchar*
697 get_account_keyname (const gchar *accname, const gchar *name)
698 {
699         if (name)
700                 return g_strconcat
701                         (accname, "/", name, NULL);
702         else
703                 return g_strdup (accname);
704 }
705
706
707 /* must be freed by caller */
708 static gchar*
709 get_server_account_keyname (const gchar *accname, const gchar *name)
710 {
711         if (name)
712                 return g_strconcat
713                         (MODEST_SERVER_ACCOUNT_NAMESPACE, "/",
714                          accname, "/", name, NULL);
715         else
716                 return g_strconcat
717                         (MODEST_SERVER_ACCOUNT_NAMESPACE, "/",
718                          accname, NULL);
719 }