#include "lib.h"
#include "array.h"
+#include "settings.h"
#include "mail-storage-private.h"
#include "push-notification-plugin.h"
#include "push-notification-drivers.h"
#include "push-notification-events.h"
+#include "push-notification-settings.h"
#include "push-notification-txn-mbox.h"
#include "push-notification-txn-msg.h"
static int
push_notification_driver_dlog_init(
- struct push_notification_driver_config *config,
- struct mail_user *user, pool_t pool,
- void **context, const char **error_r ATTR_UNUSED)
+ struct mail_user *user, pool_t pool, ATTR_UNUSED const char *name,
+ void **context_r, ATTR_UNUSED const char **error_r)
{
struct event *log_event = create_dlog_event(user->event);
struct dlog_push_notification_txn_context *ctx = p_new(
pool, struct dlog_push_notification_txn_context, 1);
ctx->event = log_event;
- *context = ctx;
+ *context_r = ctx;
e_debug(log_event, "Called init push_notification plugin hook.");
- if (config->raw_config != NULL) {
- e_debug(log_event,
- "Config string for dlog push_notification driver: %s",
- config->raw_config);
- }
-
return 0;
}
#include "hash.h"
#include "dlua-script.h"
#include "dlua-script-private.h"
+#include "settings.h"
#include "mail-storage.h"
#include "mail-user.h"
#include "push-notification-drivers.h"
#include "push-notification-events.h"
#include "push-notification-event-message-common.h"
+#include "push-notification-settings.h"
#include "push-notification-txn-mbox.h"
#include "push-notification-txn-msg.h"
static int
push_notification_driver_lua_init(
- struct push_notification_driver_config *config, struct mail_user *user,
- pool_t pool, void **context, const char **error_r)
+ struct mail_user *user, pool_t pool, const char *name,
+ void **context, const char **error_r)
{
struct dlua_push_notification_context *ctx;
const char *path;
+ struct push_notification_lua_settings *lua_settings;
+ if (settings_get_filter(user->event, PUSH_NOTIFICATION_SETTINGS_FILTER_NAME,
+ name, &push_notification_lua_setting_parser_info,
+ 0, &lua_settings, error_r) < 0)
+ return -1;
+
struct event *event = event_create(user->event);
event_add_category(event, push_notification_get_event_category());
event_set_append_log_prefix(event, "lua: ");
if ((path = mail_user_plugin_getenv(user, DLUA_LOG_USERENV_KEY)) == NULL)
- path = hash_table_lookup(config->config, (const char *)"path");
+ path = t_strdup(lua_settings->path);
+
+ settings_free(lua_settings);
if (path == NULL) {
struct dlua_script *script;
#include "json-ostream.h"
#include "mailbox-attribute.h"
#include "mail-storage-private.h"
+#include "settings.h"
#include "str.h"
#include "strescape.h"
+#include "strnum.h"
#include "str-parse.h"
#include "iostream-ssl.h"
+#include "push-notification-settings.h"
#include "push-notification-plugin.h"
#include "push-notification-drivers.h"
#include "push-notification-event-messagenew.h"
/* Default values. */
static const char *const default_events[] = { "MessageNew", NULL };
static const char *const default_mboxes[] = { "INBOX", NULL };
-#define DEFAULT_CACHE_LIFETIME_SECS 60
/* This is data that is shared by all plugin users. */
struct push_notification_driver_ox_global {
}
static int
-push_notification_driver_ox_init(struct push_notification_driver_config *config,
- struct mail_user *user, pool_t pool,
- void **context, const char **error_r)
+push_notification_driver_ox_init(struct mail_user *user, pool_t pool,
+ const char *name, void **context,
+ const char **error_r)
{
struct push_notification_driver_ox_config *dconfig;
- const char *error, *tmp;
- /* Valid config keys: cache_lifetime, url */
- tmp = hash_table_lookup(config->config, (const char *)"url");
- if (tmp == NULL) {
- *error_r = "Driver requires the url parameter";
+ struct push_notification_ox_settings *ox_settings;
+ if (settings_get_filter(user->event, PUSH_NOTIFICATION_SETTINGS_FILTER_NAME,
+ name, &push_notification_ox_setting_parser_info,
+ 0, &ox_settings, error_r) < 0)
return -1;
- }
dconfig = p_new(pool, struct push_notification_driver_ox_config, 1);
dconfig->event = event_create(user->event);
event_add_category(dconfig->event, &event_category_push_notification);
event_set_append_log_prefix(dconfig->event, "push-notification-ox: ");
- if (http_url_parse(tmp, NULL, HTTP_URL_ALLOW_USERINFO_PART, pool,
- &dconfig->http_url, &error) < 0) {
- event_unref(&dconfig->event);
- *error_r = t_strdup_printf("Failed to parse OX REST URL %s: %s",
- tmp, error);
- return -1;
- }
- dconfig->use_unsafe_username =
- hash_table_lookup(config->config,
- (const char *)"user_from_metadata") != NULL;
-
- e_debug(dconfig->event, "Using URL %s", tmp);
-
- tmp = hash_table_lookup(config->config, (const char *)"cache_lifetime");
- if (tmp == NULL) {
- dconfig->cached_ox_metadata_lifetime_secs =
- DEFAULT_CACHE_LIFETIME_SECS;
- } else if (str_parse_get_interval(
- tmp, &dconfig->cached_ox_metadata_lifetime_secs, &error) < 0) {
- event_unref(&dconfig->event);
- *error_r = t_strdup_printf(
- "Failed to parse OX cache_lifetime %s: %s", tmp, error);
- return -1;
+ /* The settings check is deliberately only validating a url if it is
+ given in the settings. Otherwise any file that does not contain
+ push-notification specific settings would fail the validation.
+ Thus we need to check here, whether the parsed url exists. */
+ if (ox_settings->parsed_url == NULL) {
+ *error_r = "push_notification_ox_url is missing or empty";
+ event_unref(&dconfig->event);
+ settings_free(ox_settings);
+ return -1;
}
+
+ dconfig->http_url = http_url_clone_with_userinfo(pool, ox_settings->parsed_url);
+ e_debug(dconfig->event, "Using URL %s",
+ http_url_create(dconfig->http_url));
+ dconfig->cached_ox_metadata_lifetime_secs = ox_settings->cache_ttl;
e_debug(dconfig->event, "Using cache lifetime: %u",
dconfig->cached_ox_metadata_lifetime_secs);
+ dconfig->use_unsafe_username = ox_settings->user_from_metadata;
+ e_debug(dconfig->event, "Using user %s",
+ dconfig->use_unsafe_username ? "stored in METADATA" : "sent by OX endpoint");
+
if (ox_global == NULL) {
ox_global = i_new(struct push_notification_driver_ox_global, 1);
ox_global->refcount = 0;
++ox_global->refcount;
*context = dconfig;
+ settings_free(ox_settings);
return 0;
}
#include "array.h"
#include "hash.h"
#include "mail-user.h"
+#include "settings.h"
#include "push-notification-drivers.h"
#include "push-notification-events.h"
+#include "push-notification-settings.h"
static ARRAY(const struct push_notification_driver *) push_notification_drivers;
return FALSE;
}
-static const struct push_notification_driver *
-push_notification_driver_find_class(const char *driver)
+static bool
+push_notification_driver_identify(struct mail_user *user, const char *name,
+ const struct push_notification_driver **driver_r,
+ const char **error_r)
{
+ struct push_notification_settings *set;
unsigned int idx;
-
- if (!push_notification_driver_find(driver, &idx))
- return NULL;
-
- return array_idx_elem(&push_notification_drivers, idx);
-}
-
-static struct push_notification_driver_config *
-push_notification_driver_parse_config(const char *p)
-{
- const char **args, *key, *p2, *value;
- struct push_notification_driver_config *config;
-
- config = t_new(struct push_notification_driver_config, 1);
- config->raw_config = p;
-
- hash_table_create(&config->config, unsafe_data_stack_pool, 0,
- str_hash, strcmp);
-
- if (p == NULL)
- return config;
-
- args = t_strsplit_spaces(p, " ");
-
- for (; *args != NULL; args++) {
- p2 = strchr(*args, '=');
- if (p2 != NULL) {
- key = t_strdup_until(*args, p2);
- value = t_strdup(p2 + 1);
- } else {
- key = *args;
- value = "";
- }
- hash_table_update(config->config, key, value);
+ if (settings_get_filter(user->event, PUSH_NOTIFICATION_SETTINGS_FILTER_NAME,
+ name, &push_notification_setting_parser_info,
+ 0, &set, error_r) < 0)
+ return FALSE;
+
+ bool ret = FALSE;
+ if (push_notification_driver_find(set->driver, &idx)) {
+ *driver_r = array_idx_elem(&push_notification_drivers, idx);
+ ret = TRUE;
}
+ settings_free(set);
- return config;
+ if (!ret)
+ *error_r = "Name does not match any registered drivers";
+
+ return ret;
}
int push_notification_driver_init(
{
void *context = NULL;
const struct push_notification_driver *driver;
- const char *driver_name, *error_r, *p;
+ const char *error;
struct push_notification_driver_user *duser;
int ret;
- /* <driver>[:<driver config>] */
- p = strchr(config_in, ':');
- if (p == NULL)
- driver_name = config_in;
- else
- driver_name = t_strdup_until(config_in, p);
-
- driver = push_notification_driver_find_class(driver_name);
- if (driver == NULL) {
+ bool found_driver = push_notification_driver_identify(user, config_in,
+ &driver, &error);
+ if (!found_driver) {
e_error(user->event,
- "Unknown push notification driver: %s", driver_name);
+ "Unable to identify push notification driver '%s': %s",
+ config_in, error);
return -1;
}
if (driver->v.init != NULL) {
T_BEGIN {
- struct push_notification_driver_config *config;
-
- config = push_notification_driver_parse_config(
- (p == NULL) ? p : p + 1);
- ret = driver->v.init(config, user, pool,
- &context, &error_r);
- if (ret < 0)
- e_error(user->event, "%s: %s",
- driver_name, error_r);
- hash_table_destroy(&config->config);
- } T_END;
-
- if (ret < 0)
+ ret = driver->v.init(user, pool, config_in, &context,
+ &error);
+ } T_END_PASS_STR_IF(ret < 0, &error);
+
+ if (ret < 0) {
+ e_error(user->event, "%s: %s", driver->name,
+ error);
return -1;
+ }
}
duser = p_new(pool, struct push_notification_driver_user, 1);
#include "push-notification-triggers.h"
struct mail_user;
-struct push_notification_driver_config;
struct push_notification_driver_txn;
struct push_notification_driver_user;
struct push_notification_txn_mbox;
struct push_notification_txn_msg *);
struct push_notification_driver_vfuncs {
- /* Init driver. Config (from plugin configuration) is parsed once (no
- user variable substitutions). Return 0 on success, or -1 if this
- driver should be disabled (or on error). */
- int (*init)(struct push_notification_driver_config *config,
- struct mail_user *user, pool_t pool, void **context,
- const char **error_r);
+ /* Init driver. Config should be read from settings via the name
+ parameter. Return 0 on success, or -1 if this driver should be
+ disabled (or on error). */
+ int (*init)(struct mail_user *user, pool_t pool, const char *name,
+ void **context, const char **error_r);
/* Called at the beginning of a notification transaction. Return TRUE on
success, or FALSE if this driver should be ignored for this
transaction. */
struct push_notification_driver_vfuncs v;
};
-struct push_notification_driver_config {
- HASH_TABLE_TYPE(push_notification_config) config;
- const char *raw_config;
-};
-
struct push_notification_driver_user {
const struct push_notification_driver *driver;
void *context;
#include "mail-storage.h"
#include "mail-storage-private.h"
#include "notify-plugin.h"
+#include "settings.h"
#include "str.h"
#include "push-notification-drivers.h"
#include "push-notification-events.h"
#include "push-notification-events-rfc5423.h"
+#include "push-notification-settings.h"
#include "push-notification-plugin.h"
#include "push-notification-triggers.h"
#include "push-notification-txn-mbox.h"
#include "push-notification-txn-msg.h"
-#define PUSH_NOTIFICATION_CONFIG "push_notification_driver"
#define PUSH_NOTIFICATION_EVENT_FINISHED "push_notification_finished"
#define PUSH_NOTIFICATION_USER_CONTEXT(obj) \
}
static void
-push_notification_config_init(const char *config_name, struct mail_user *user,
+push_notification_config_init(struct mail_user *user,
struct push_notification_driver_list *dlist)
{
+ const struct push_notification_settings *set;
struct push_notification_driver_user *duser;
- const char *env;
- unsigned int i;
- string_t *root_name;
+ const char *error, *name;
- root_name = t_str_new(32);
- str_append(root_name, config_name);
-
- for (i = 2;; i++) {
- env = mail_user_plugin_getenv(user, str_c(root_name));
- if ((env == NULL) || (*env == '\0'))
- break;
+ if (settings_get(user->event, &push_notification_setting_parser_info,
+ 0, &set, &error) < 0) {
+ e_error(user->event, "Failed to get push_notification settings: %s",
+ error);
+ return;
+ }
- if (push_notification_driver_init(
- user, env, user->pool, &duser) < 0)
- break;
+ if (array_is_created(&set->push_notifications)) {
+ array_foreach_elem(&set->push_notifications, name) {
+ if (push_notification_driver_init(
+ user, name, user->pool,
+ &duser) < 0)
+ break;
- /* Add driver. */
- array_push_back(&dlist->drivers, &duser);
+ /* Add driver. */
+ array_push_back(&dlist->drivers, &duser);
+ }
- str_truncate(root_name, strlen(config_name));
- str_printfa(root_name, "%d", i);
}
+ settings_free(set);
}
static struct push_notification_driver_list *
dlist = p_new(user->pool, struct push_notification_driver_list, 1);
p_array_init(&dlist->drivers, user->pool, 4);
- push_notification_config_init(PUSH_NOTIFICATION_CONFIG, user, dlist);
+ push_notification_config_init(user, dlist);
return dlist;
}