bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2015-2018 Dovecot authors, see the included COPYING file */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#include "push-notification-events-rfc5423.h"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#define PUSH_NOTIFICATION_CONFIG "push_notification_driver"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#define PUSH_NOTIFICATION_CONFIG_OLD "push_notification_backend"
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#define PUSH_NOTIFICATION_USER_CONTEXT(obj) \
d567cc27913a45c893b4c091f84b496854d814e7Aki Tuomi MODULE_CONTEXT_REQUIRE(obj, push_notification_user_module)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic MODULE_CONTEXT_DEFINE_INIT(push_notification_user_module,
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarzpush_notification_transaction_init(struct push_notification_txn *ptxn)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct push_notification_driver_txn *dtxn;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct push_notification_driver_user **duser;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* no notifications for autocreated raw users */
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz array_foreach_modifiable(&ptxn->puser->driverlist->drivers, duser) {
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz dtxn = p_new(ptxn->pool, struct push_notification_driver_txn, 1);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz if ((dtxn->duser->driver->v.begin_txn == NULL) ||
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarzpush_notification_transaction_create(struct mailbox *box,
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz pool = pool_alloconly_create("push notification transaction", 2048);
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz ptxn = p_new(pool, struct push_notification_txn, 1);
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz ptxn->muser = mail_storage_get_user(storage);
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz ptxn->puser = PUSH_NOTIFICATION_USER_CONTEXT(ptxn->muser);
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz ptxn->trigger = PUSH_NOTIFICATION_EVENT_TRIGGER_NONE;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_transaction_end
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz(struct push_notification_txn *ptxn, bool success)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct push_notification_driver_txn **dtxn;
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz array_foreach_modifiable(&ptxn->drivers, dtxn) {
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz if ((*dtxn)->duser->driver->v.end_txn != NULL) {
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz (*dtxn)->duser->driver->v.end_txn(*dtxn, success);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_transaction_commit
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz(void *txn, struct mail_transaction_commit_changes *changes)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct push_notification_txn *ptxn = (struct push_notification_txn *)txn;
a44595f7b1afc7ccbd8653598753b32899d01c76Timo Sirainen /* Make sure we're not in just any random ioloop, which could get
a44595f7b1afc7ccbd8653598753b32899d01c76Timo Sirainen destroyed soon. This way the push-notification drivers can do async
a44595f7b1afc7ccbd8653598753b32899d01c76Timo Sirainen operations that finish in the main ioloop. */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_txn_msg_end(ptxn, changes);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_transaction_end(ptxn, TRUE);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_mailbox_create(struct mailbox *box)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz ptxn = push_notification_transaction_create(box, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_trigger_mbox_create(ptxn, box, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_transaction_commit(ptxn, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_mailbox_delete(void *txn ATTR_UNUSED,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz ptxn = push_notification_transaction_create(box, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_trigger_mbox_delete(ptxn, box, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_transaction_commit(ptxn, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_mailbox_rename(struct mailbox *src,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz ptxn = push_notification_transaction_create(dest, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_trigger_mbox_rename(ptxn, src, dest, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_transaction_commit(ptxn, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_mailbox_subscribe(struct mailbox *box,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz ptxn = push_notification_transaction_create(box, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_trigger_mbox_subscribe(ptxn, box, subscribed, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_transaction_commit(ptxn, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_mail_save(void *txn, struct mail *mail)
4ee5a85e75d520497bd43dbfcc6fc273f3e57ceaMichael Slusarz /* POST_SESSION means MTA delivery. */
23bdbb7b1831785c6ba6df190f6369da882d2b9dTimo Sirainen if ((mail->box->flags & MAILBOX_FLAG_POST_SESSION) != 0) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_trigger_msg_save_new(ptxn, mail, NULL);
4ee5a85e75d520497bd43dbfcc6fc273f3e57ceaMichael Slusarz push_notification_trigger_msg_save_append(ptxn, mail, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_mail_copy(void *txn,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_mail_expunge(void *txn, struct mail *mail)
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz push_notification_trigger_msg_save_expunge(txn, mail, NULL);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzpush_notification_mail_update_flags(void *txn, struct mail *mail,
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz push_notification_trigger_msg_flag_change(txn, mail, NULL, old_flags);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzpush_notification_mail_update_keywords(void *txn, struct mail *mail,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz const char *const *old_keywords)
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz push_notification_trigger_msg_keyword_change(txn, mail, NULL, old_keywords);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzpush_notification_transaction_begin(struct mailbox_transaction_context *t)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz return push_notification_transaction_create(mailbox_transaction_get_mailbox(t), t);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void push_notification_transaction_rollback(void *txn)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_transaction_end(ptxn, FALSE);
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarzpush_notification_config_init(const char *config_name,
41dc355b0d4e20037a36ec05206e7880f49f4ca9Michael Slusarz struct push_notification_driver_list *dlist)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz struct push_notification_driver_user *duser;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz unsigned int i;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz for (i = 2;; i++) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz env = mail_user_plugin_getenv(user, str_c(root_name));
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen if (push_notification_driver_init(user, env, user->pool, &duser) < 0) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz // Add driver.
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz str_truncate(root_name, strlen(config_name));
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainenpush_notification_driver_list_init(struct mail_user *user)
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen dlist = p_new(user->pool, struct push_notification_driver_list, 1);
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz push_notification_config_init(PUSH_NOTIFICATION_CONFIG, user, dlist);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* Support old configuration (it was available at time initial OX
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz * driver was first released). */
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz push_notification_config_init(PUSH_NOTIFICATION_CONFIG_OLD, user,
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainenstatic void push_notification_user_deinit(struct mail_user *user)
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen struct push_notification_user *puser = PUSH_NOTIFICATION_USER_CONTEXT(user);
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen struct push_notification_driver_list *dlist = puser->driverlist;
a846e6d6b4f1e9fcef4c07a5982b243a274f0a42Timo Sirainen /* Make sure we're in the main ioloop, so if the deinit/cleanup moves any
a846e6d6b4f1e9fcef4c07a5982b243a274f0a42Timo Sirainen I/Os or timeouts they won't get moved to some temporary ioloop. */
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen array_foreach_modifiable(&dlist->drivers, duser) {
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainenstatic void push_notification_user_created(struct mail_user *user)
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz puser = p_new(user->pool, struct push_notification_user, 1);
33cbadf0114f3a5cb83bdb5a8bc07035f807e466Timo Sirainen puser->driverlist = push_notification_driver_list_init(user);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz MODULE_CONTEXT_SET(user, push_notification_user_module, puser);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz/* Plugin interface. */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzconst char *push_notification_plugin_version = DOVECOT_ABI_VERSION;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzconst char *push_notification_plugin_dependencies[] = { "notify", NULL };
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzextern struct push_notification_driver push_notification_driver_dlog;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzextern struct push_notification_driver push_notification_driver_ox;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic struct notify_context *push_notification_ctx;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic const struct notify_vfuncs push_notification_vfuncs = {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* Mailbox Events */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mailbox_create = push_notification_mailbox_create,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mailbox_delete_commit = push_notification_mailbox_delete,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mailbox_rename = push_notification_mailbox_rename,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mailbox_set_subscribed = push_notification_mailbox_subscribe,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* Mail Events */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_expunge = push_notification_mail_expunge,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_update_flags = push_notification_mail_update_flags,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_update_keywords = push_notification_mail_update_keywords,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_transaction_begin = push_notification_transaction_begin,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_transaction_commit = push_notification_transaction_commit,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_transaction_rollback = push_notification_transaction_rollback
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic struct mail_storage_hooks push_notification_storage_hooks = {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz .mail_user_created = push_notification_user_created
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzvoid push_notification_plugin_init(struct module *module)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_ctx = notify_register(&push_notification_vfuncs);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz mail_storage_hooks_add(module, &push_notification_storage_hooks);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_driver_register(&push_notification_driver_dlog);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_driver_register(&push_notification_driver_ox);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_event_register_rfc5423_events();
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_driver_unregister(&push_notification_driver_dlog);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz push_notification_driver_unregister(&push_notification_driver_ox);
da2423165d31474f5384833fdaa6dc4c0cee28f4Timo Sirainen push_notification_event_unregister_rfc5423_events();