* modest-tny-account-store.c:
[modest] / src / modest-tny-account-store.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <string.h>
31 #include <glib/gi18n.h>
32
33 #include <tny-account.h>
34 #include <tny-account-store.h>
35 #include <tny-store-account.h>
36 #include <tny-transport-account.h>
37 #include <tny-device.h>
38 #include <tny-account-store.h>
39 #include <tny-camel-transport-account.h>
40 #include <tny-camel-imap-store-account.h>
41 #include <tny-camel-pop-store-account.h>
42 #include <modest-marshal.h>
43 #include <modest-protocol-info.h>
44 #include <modest-local-folder-info.h>
45 #include "modest-account-mgr.h"
46 #include "modest-tny-account-store.h"
47 #include "modest-tny-platform-factory.h"
48 #include <tny-gtk-lockable.h>
49 #include <camel/camel.h>
50
51 /* 'private'/'protected' functions */
52 static void modest_tny_account_store_class_init   (ModestTnyAccountStoreClass *klass);
53 //static void modest_tny_account_store_init         (ModestTnyAccountStore *obj);
54 static void modest_tny_account_store_finalize     (GObject *obj);
55
56 /* implementations for tny-account-store-iface */
57 static void    modest_tny_account_store_instance_init (ModestTnyAccountStore *obj);
58 static void    modest_tny_account_store_init                     (gpointer g, gpointer iface_data);
59
60
61 /* list my signals */
62 enum {
63         PASSWORD_REQUESTED_SIGNAL,
64         ACCOUNT_UPDATE_SIGNAL,
65         LAST_SIGNAL
66 };
67
68 typedef struct _ModestTnyAccountStorePrivate ModestTnyAccountStorePrivate;
69 struct _ModestTnyAccountStorePrivate {
70
71         gchar              *cache_dir;
72         
73         GHashTable         *password_hash;
74         TnyDevice          *device;
75         TnyPlatformFactory *platform_fact;
76         TnySessionCamel    *tny_session_camel;
77 };
78
79 #define MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
80                                                       MODEST_TYPE_TNY_ACCOUNT_STORE, \
81                                                       ModestTnyAccountStorePrivate))
82 /* globals */
83 static GObjectClass *parent_class = NULL;
84
85 static guint signals[LAST_SIGNAL] = {0};
86
87 GType
88 modest_tny_account_store_get_type (void)
89 {
90         static GType my_type = 0;
91
92         if (!my_type) {
93                 static const GTypeInfo my_info = {
94                         sizeof(ModestTnyAccountStoreClass),
95                         NULL,           /* base init */
96                         NULL,           /* base finalize */
97                         (GClassInitFunc) modest_tny_account_store_class_init,
98                         NULL,           /* class finalize */
99                         NULL,           /* class data */
100                         sizeof(ModestTnyAccountStore),
101                         0,              /* n_preallocs */
102                         (GInstanceInitFunc) modest_tny_account_store_instance_init,
103                         NULL
104                 };
105
106                 static const GInterfaceInfo iface_info = {
107                         (GInterfaceInitFunc) modest_tny_account_store_init,
108                         NULL,         /* interface_finalize */
109                         NULL          /* interface_data */
110                 };
111                 /* hack hack */
112                 my_type = g_type_register_static (G_TYPE_OBJECT,
113                                                   "ModestTnyAccountStore",
114                                                   &my_info, 0);
115                 g_type_add_interface_static (my_type, TNY_TYPE_ACCOUNT_STORE,
116                                              &iface_info);
117         }
118         return my_type;
119 }
120
121 static void
122 modest_tny_account_store_class_init (ModestTnyAccountStoreClass *klass)
123 {
124         GObjectClass *gobject_class;
125         gobject_class = (GObjectClass*) klass;
126
127         parent_class            = g_type_class_peek_parent (klass);
128         gobject_class->finalize = modest_tny_account_store_finalize;
129
130         g_type_class_add_private (gobject_class,
131                                   sizeof(ModestTnyAccountStorePrivate));
132
133         signals[PASSWORD_REQUESTED_SIGNAL] =
134                 g_signal_new ("password_requested",
135                               G_TYPE_FROM_CLASS (gobject_class),
136                               G_SIGNAL_RUN_FIRST,
137                               G_STRUCT_OFFSET(ModestTnyAccountStoreClass, password_requested),
138                               NULL, NULL,
139                               modest_marshal_VOID__STRING_POINTER_POINTER_POINTER,
140                               G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
141         
142         signals[ACCOUNT_UPDATE_SIGNAL] =
143                 g_signal_new ("account_update",
144                               G_TYPE_FROM_CLASS (gobject_class),
145                               G_SIGNAL_RUN_FIRST,
146                               G_STRUCT_OFFSET(ModestTnyAccountStoreClass, account_update),
147                               NULL, NULL,
148                               g_cclosure_marshal_VOID__STRING,
149                               G_TYPE_NONE, 1, G_TYPE_STRING);
150         
151 }
152
153 static void
154 modest_tny_account_store_instance_init (ModestTnyAccountStore *obj)
155 {
156         ModestTnyAccountStorePrivate *priv =
157                 MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(obj);
158
159         priv->cache_dir              = NULL;
160         
161         priv->platform_fact          = NULL;
162         priv->tny_session_camel      = NULL;
163         priv->device                 = NULL;
164         
165         priv->password_hash          = g_hash_table_new_full (g_str_hash, g_str_equal,
166                                                               g_free, g_free);
167 }
168
169
170 static void
171 on_account_removed (ModestAccountMgr *acc_mgr, const gchar *account, gboolean server_account,
172                     gpointer user_data)
173 {
174         ModestTnyAccountStore *self = MODEST_TNY_ACCOUNT_STORE(user_data);
175
176         g_signal_emit (G_OBJECT(self), signals[ACCOUNT_UPDATE_SIGNAL], 0,
177                        account);
178         
179 }
180
181
182 static void
183 on_account_changed (ModestAccountMgr *acc_mgr, const gchar *account, gboolean server_account,
184                     const gchar *key, gpointer user_data)
185 {
186         ModestTnyAccountStore *self = MODEST_TNY_ACCOUNT_STORE(user_data);
187         
188         g_signal_emit (G_OBJECT(self), signals[ACCOUNT_UPDATE_SIGNAL], 0,
189                        account);
190 }
191
192
193 static ModestTnyAccountStore*
194 get_account_store_for_account (TnyAccount *account)
195 {
196         return MODEST_TNY_ACCOUNT_STORE(g_object_get_data (G_OBJECT(account), "account_store"));
197 }
198
199
200
201 static void
202 set_account_store_for_account (TnyAccount *account, ModestTnyAccountStore *store)
203 {
204         g_object_set_data (G_OBJECT(account), "account_store", (gpointer)store);
205 }
206
207 static gchar*
208 get_password (TnyAccount *account, const gchar *prompt, gboolean *cancel)
209 {
210         const gchar *key;
211         ModestAccountMgr *account_mgr;
212         const TnyAccountStore *account_store;
213         ModestTnyAccountStore *self;
214         ModestTnyAccountStorePrivate *priv;
215         gchar *pwd = NULL;
216         gboolean already_asked;
217                 
218         key           = tny_account_get_id (account);
219         account_store = TNY_ACCOUNT_STORE(get_account_store_for_account (account));
220
221         self = MODEST_TNY_ACCOUNT_STORE (account_store);
222         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
223         
224         account_mgr = modest_tny_platform_factory_get_account_mgr_instance
225                 (MODEST_TNY_PLATFORM_FACTORY(priv->platform_fact));
226         
227         /* is it in the hash? if it's already there, it must be wrong... */
228         already_asked = g_hash_table_lookup_extended (priv->password_hash,
229                                                       key, NULL, (gpointer *) &pwd);
230
231         /* if the password is not already there, try ModestConf */
232         if (!already_asked) {
233                 pwd  = modest_account_mgr_get_string (account_mgr,
234                                                       key, MODEST_ACCOUNT_PASSWORD,
235                                                       TRUE, NULL);
236                 g_hash_table_insert (priv->password_hash, g_strdup (key), g_strdup (pwd));
237         }
238
239         /* if it was already asked, it must have been wrong, so ask again */
240         if (already_asked || !pwd || strlen(pwd) == 0) {
241
242                 /* we don't have it yet. we emit a signal to get the password somewhere */
243                 const gchar* name = tny_account_get_name (account);
244                 gboolean remember;
245                 pwd = NULL;
246
247                 g_signal_emit (G_OBJECT(self), signals[PASSWORD_REQUESTED_SIGNAL], 0,
248                                name, &pwd, cancel, &remember);
249
250                 if (!*cancel) {
251                         if (remember)
252                                 modest_account_mgr_set_string (account_mgr,
253                                                                key, MODEST_ACCOUNT_PASSWORD,
254                                                                pwd,
255                                                                TRUE, NULL);
256                         /* We need to dup the string even knowing that
257                            it's already a dup of the contents of an
258                            entry, because it if it's wrong, then camel
259                            will free it */
260                         g_hash_table_insert (priv->password_hash, g_strdup (key), g_strdup(pwd));
261                 } else {
262                         g_hash_table_remove (priv->password_hash, key);
263                         g_free (pwd);
264                         pwd = NULL;
265                 }
266         } else
267                 *cancel = FALSE;
268
269         return pwd;
270 }
271
272
273 static void
274 forget_password (TnyAccount *account) {
275
276         ModestTnyAccountStore *self;
277         ModestTnyAccountStorePrivate *priv;
278         const TnyAccountStore *account_store;
279         gchar *pwd;
280         const gchar *key;
281         ModestAccountMgr *account_mgr;
282         
283         account_store = TNY_ACCOUNT_STORE(get_account_store_for_account (account));
284         self = MODEST_TNY_ACCOUNT_STORE (account_store);
285         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
286         key  = tny_account_get_id (account);
287
288         /* Do not remove the key, this will allow us to detect that we
289            have already asked for it at least once */
290         pwd = g_hash_table_lookup (priv->password_hash, key);
291         if (pwd) {
292                 memset (pwd, 0, strlen (pwd));
293                 g_hash_table_insert (priv->password_hash, g_strdup (key), NULL);
294         }
295
296         account_mgr = modest_tny_platform_factory_get_account_mgr_instance
297                 (MODEST_TNY_PLATFORM_FACTORY(priv->platform_fact));
298
299         /* Remove from configuration system */
300         modest_account_mgr_unset (account_mgr,
301                                   key, MODEST_ACCOUNT_PASSWORD,
302                                   TRUE, NULL);
303 }
304
305
306
307 /* instantiate the correct tny account subclass */
308 static TnyAccount*
309 tny_account_for_proto (ModestProtocol proto) 
310 {
311         ModestProtocolType type;        
312         TnyAccount *tny_account = NULL;
313         
314         type  = modest_protocol_info_get_protocol_type (proto);
315
316         if (type == MODEST_PROTOCOL_TYPE_TRANSPORT) 
317                 tny_account = TNY_ACCOUNT(tny_camel_transport_account_new ());
318         else if (proto == MODEST_PROTOCOL_STORE_POP)
319                 tny_account = TNY_ACCOUNT(tny_camel_pop_store_account_new ());
320         else if (proto == MODEST_PROTOCOL_STORE_IMAP)
321                 tny_account = TNY_ACCOUNT(tny_camel_imap_store_account_new ());
322         else
323                 g_return_val_if_reached (NULL);
324         
325         if (tny_account)
326                 tny_account_set_proto (tny_account,
327                                        modest_protocol_info_get_protocol_name(proto));
328         else
329                 g_printerr ("modest: could not get tny account for %d\n",
330                             proto);    
331         return tny_account;
332 }
333
334
335 /* create a tnyaccount for the server account connected to the account with name 'key'
336  */
337 static TnyAccount*
338 get_tny_account_from_server_account (ModestTnyAccountStore *self,
339                                      ModestServerAccountData *account_data,
340                                      ModestProtocolType modest_type)
341 {
342         TnyAccount *tny_account;
343         ModestTnyAccountStorePrivate *priv;
344                 
345         g_return_val_if_fail (self, NULL);
346         g_return_val_if_fail (account_data, NULL);
347
348         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
349         
350         /* proto */
351         tny_account = tny_account_for_proto (account_data->proto);
352         if (!tny_account) {
353                 g_printerr ("modest: could not create tny account for '%s'\n",
354                             account_data->account_name);
355                 return NULL;
356         }
357         
358         set_account_store_for_account (TNY_ACCOUNT(tny_account), self);
359         tny_camel_account_set_session (TNY_CAMEL_ACCOUNT(tny_account),  /* session */
360                                        priv->tny_session_camel);        
361         tny_account_set_id            (tny_account, account_data->account_name); /* id */
362
363         if (account_data->hostname)
364                 tny_account_set_hostname (tny_account, account_data->hostname);
365
366         if (account_data->username) 
367                 tny_account_set_user (tny_account, account_data->username);
368
369         tny_account_set_pass_func (tny_account, get_password);
370         tny_account_set_forget_pass_func (tny_account, forget_password);
371
372         return tny_account;
373 }
374
375
376
377 static void
378 modest_tny_account_store_finalize (GObject *obj)
379 {
380         ModestTnyAccountStore *self        = MODEST_TNY_ACCOUNT_STORE(obj);
381         ModestTnyAccountStorePrivate *priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
382
383         if (priv->tny_session_camel) {
384                 camel_object_unref (CAMEL_OBJECT(priv->tny_session_camel));
385                 priv->tny_session_camel = NULL;
386         }
387
388         g_free (priv->cache_dir);
389         priv->cache_dir = NULL;
390
391         if (priv->device) {
392                 g_object_unref (priv->device);
393                 priv->device = NULL;
394         }
395         
396         if (priv->password_hash) {
397                 g_hash_table_destroy (priv->password_hash);
398                 priv->password_hash = NULL;
399         }
400         
401         G_OBJECT_CLASS(parent_class)->finalize (obj);
402 }
403
404
405 ModestTnyAccountStore*
406 modest_tny_account_store_new (ModestAccountMgr *account_mgr) {
407
408         GObject *obj;
409         ModestTnyAccountStorePrivate *priv;
410         TnyPlatformFactory *pfact;
411         
412         g_return_val_if_fail (account_mgr, NULL);
413
414         obj  = G_OBJECT(g_object_new(MODEST_TYPE_TNY_ACCOUNT_STORE, NULL));
415         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(obj);
416
417         g_signal_connect (G_OBJECT(account_mgr), "account_changed",
418                                        G_CALLBACK (on_account_changed), obj);
419         g_signal_connect (G_OBJECT(account_mgr), "account_removed",
420                                        G_CALLBACK (on_account_removed), obj);
421
422         pfact = TNY_PLATFORM_FACTORY (modest_tny_platform_factory_get_instance());
423         if (!pfact) {
424                 g_printerr ("modest: cannot get platform factory instance\n");
425                 g_object_unref (obj);
426                 return NULL;
427         } else
428                 priv->platform_fact = pfact;
429         
430         priv->tny_session_camel = tny_session_camel_new (TNY_ACCOUNT_STORE(obj));
431         if (!priv->tny_session_camel) {
432                 g_printerr ("modest: cannot create TnySessionCamel instance\n");
433                 g_object_unref (obj);
434                 return NULL;
435         }
436
437         tny_session_camel_set_ui_locker (priv->tny_session_camel, tny_gtk_lockable_new ());
438
439         return MODEST_TNY_ACCOUNT_STORE(obj);
440 }
441
442 static void
443 modest_tny_account_store_add_store_account  (TnyAccountStore *self,
444                                              TnyStoreAccount *account)
445 {
446         /* we should not need this...*/
447         g_printerr ("modest: add_store_account_func not implemented\n");
448 }
449
450
451 static void
452 modest_tny_account_store_add_transport_account  (TnyAccountStore *self,
453                                                  TnyTransportAccount *account)
454 {       
455         /* we should not need this...*/
456         g_printerr ("modest: add_transport_account_func not implemented\n");
457 }
458
459
460 /* create a pseudo-account for our local folders */
461 static TnyAccount*
462 get_local_folder_account (ModestTnyAccountStore *self)
463 {
464         TnyStoreAccount *tny_account;
465         CamelURL *url;
466         gchar *maildir, *url_string;
467         ModestTnyAccountStorePrivate *priv;
468
469         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
470         
471         tny_account = tny_camel_store_account_new ();
472         if (!tny_account) {
473                 g_printerr ("modest: cannot create account for local folders");
474                 return NULL;
475         }
476
477         maildir = modest_local_folder_info_get_maildir_path ();
478         
479         url = camel_url_new ("maildir:", NULL);
480         camel_url_set_path (url, maildir);
481
482         url_string = camel_url_to_string (url, 0);
483         tny_account_set_url_string (TNY_ACCOUNT(tny_account), url_string);
484
485         tny_camel_account_set_session (TNY_CAMEL_ACCOUNT(tny_account),
486                                        priv->tny_session_camel);
487
488         tny_account_set_name (TNY_ACCOUNT(tny_account), _("Local folders")); 
489                               
490         camel_url_free (url);
491         g_free (maildir);
492         g_free (url_string);
493
494         return TNY_ACCOUNT(tny_account);
495 }
496
497
498 static TnyAccount*
499 get_tny_account_from_account (ModestTnyAccountStore *self, ModestAccountData *account_data,
500                               TnyGetAccountsRequestType type) 
501 {
502         TnyAccount *tny_account = NULL;
503         ModestServerAccountData *server_account;
504
505         if (type == TNY_ACCOUNT_STORE_STORE_ACCOUNTS && account_data->store_account)
506                 server_account = account_data->store_account;
507         else if (type == TNY_ACCOUNT_STORE_TRANSPORT_ACCOUNTS && account_data->transport_account)
508                 server_account = account_data->transport_account;
509         else
510                 g_return_val_if_reached (NULL);
511         
512         if (!server_account) {
513                 g_printerr ("modest: no %s account defined for '%s'\n",
514                             type == TNY_ACCOUNT_STORE_STORE_ACCOUNTS ? "store" : "transport",
515                             account_data->display_name);
516                 return NULL;
517         }
518         
519         tny_account = get_tny_account_from_server_account (self, server_account, type);
520         if (!tny_account) { 
521                 g_printerr ("modest: failed to create tny account for %s\n",
522                             account_data->account_name);
523                 return NULL;
524         }
525         
526         if (account_data->display_name)
527                 tny_account_set_name (tny_account, account_data->display_name); 
528
529         return tny_account;
530 }
531
532
533 static void
534 modest_tny_account_store_get_accounts  (TnyAccountStore *iface, TnyList *list,
535                                         TnyGetAccountsRequestType type)
536 {
537         ModestTnyAccountStore        *self;
538         ModestTnyAccountStorePrivate *priv;
539         GSList                       *accounts, *cursor;
540         ModestAccountMgr             *account_mgr; 
541         TnyAccount                   *local_folder_account;
542         
543         g_return_if_fail (iface);
544         g_return_if_fail (TNY_IS_LIST(list));
545
546         self        = MODEST_TNY_ACCOUNT_STORE(iface);
547         priv        = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
548         account_mgr = modest_tny_platform_factory_get_account_mgr_instance
549                 (MODEST_TNY_PLATFORM_FACTORY(priv->platform_fact));
550         
551         if (type == TNY_ACCOUNT_STORE_BOTH) {
552                 modest_tny_account_store_get_accounts (iface, list, TNY_ACCOUNT_STORE_STORE_ACCOUNTS);
553                 modest_tny_account_store_get_accounts (iface, list, TNY_ACCOUNT_STORE_TRANSPORT_ACCOUNTS);
554         }
555         
556         accounts = modest_account_mgr_account_names (account_mgr, NULL); 
557         for (cursor = accounts; cursor; cursor = cursor->next) {
558                 TnyAccount *tny_account;
559                 ModestAccountData *account_data =
560                         modest_account_mgr_get_account_data (account_mgr, 
561                                                              (gchar*)cursor->data);
562                 if (account_data && account_data->enabled) {
563                         tny_account = get_tny_account_from_account (self, account_data, type);
564                         if (tny_account)
565                                 tny_list_prepend (list, G_OBJECT(tny_account));
566                 }
567                 g_free (cursor->data);
568                 modest_account_mgr_free_account_data (account_mgr, account_data);
569         }
570         g_slist_free (accounts);
571
572         /* also, add the local folder pseudo-account */
573         local_folder_account = get_local_folder_account (MODEST_TNY_ACCOUNT_STORE(self));
574         if (!local_folder_account) 
575                 g_printerr ("modest: failed to add local folders account\n");
576         else
577                 tny_list_prepend (list, G_OBJECT(local_folder_account));
578         
579         tny_session_camel_set_account_store (priv->tny_session_camel, iface);
580 }
581
582
583 /*
584  * the cache dir will be ~/.modest/cache
585  * might want to change this in a simple #define...
586  */
587 static const gchar*
588 modest_tny_account_store_get_cache_dir (TnyAccountStore *self)
589 {
590         ModestTnyAccountStorePrivate *priv;
591         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
592         
593         if (!priv->cache_dir)
594                 priv->cache_dir = g_build_filename (g_get_home_dir(), ".modest",
595                                                     "cache", NULL);
596         return priv->cache_dir;
597 }
598
599
600 /*
601  * callers need to unref
602  */
603 static TnyDevice*
604 modest_tny_account_store_get_device (TnyAccountStore *self)
605 {
606         ModestTnyAccountStorePrivate *priv;
607
608         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE (self);
609
610         if (!priv->device) 
611                 priv->device = tny_platform_factory_new_device (priv->platform_fact);
612         
613         return g_object_ref (G_OBJECT(priv->device));
614 }
615
616
617
618 static gboolean
619 modest_tny_account_store_alert (TnyAccountStore *self, TnyAlertType type,
620                                 const gchar *prompt)
621 {
622         g_printerr ("modest: alert_func not implemented (%d, %s)\n",
623                     type, prompt);
624         return TRUE;
625 }
626
627
628 static void
629 modest_tny_account_store_init (gpointer g, gpointer iface_data)
630 {
631         TnyAccountStoreIface *klass;
632
633         g_return_if_fail (g);
634
635         klass = (TnyAccountStoreIface *)g;
636
637         klass->get_accounts_func =
638                 modest_tny_account_store_get_accounts;
639         klass->add_transport_account_func =
640                 modest_tny_account_store_add_transport_account;
641         klass->add_store_account_func =
642                 modest_tny_account_store_add_store_account;
643         klass->get_cache_dir_func =
644                 modest_tny_account_store_get_cache_dir;
645         klass->get_device_func =
646                 modest_tny_account_store_get_device;
647         klass->alert_func =
648                 modest_tny_account_store_alert;
649 }
650
651 void
652 modest_tny_account_store_set_get_pass_func (ModestTnyAccountStore *self,
653                                             ModestTnyGetPassFunc func)
654 {
655         g_message (__FUNCTION__);
656         return; /* not implemented, we use signals */
657 }
658
659
660
661 TnySessionCamel*
662 tny_account_store_get_session    (TnyAccountStore *self)
663 {
664         g_return_val_if_fail (self, NULL);      
665         return MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self)->tny_session_camel;
666 }