From 031af6a259c38f3f5bba68935033c9b4727f26a3 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Thu, 25 Dec 2008 23:26:59 +0100 Subject: [PATCH] Enotify: implemented notify_method_capability test. --- Makefile.am | 2 + TODO | 1 - .../plugins/enotify/ext-enotify-common.c | 95 +++++++++++++------ .../plugins/enotify/ext-enotify-common.h | 4 + src/lib-sieve/plugins/enotify/ntfy-mailto.c | 23 ++++- .../plugins/enotify/sieve-ext-enotify.h | 3 + .../enotify/tst-notify-method-capability.c | 35 +++---- .../enotify/notify_method_capability.svtest | 12 +++ ...thod.svtest => valid_notify_method.svtest} | 8 +- 9 files changed, 127 insertions(+), 56 deletions(-) create mode 100644 tests/extensions/enotify/notify_method_capability.svtest rename tests/extensions/enotify/{valid-notify-method.svtest => valid_notify_method.svtest} (77%) diff --git a/Makefile.am b/Makefile.am index 832e2806e..33444572f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,6 +24,8 @@ if BUILD_ENOTIFY ENOTIFY_TESTS = \ tests/extensions/enotify/basic.svtest \ tests/extensions/enotify/encodeurl.svtest \ + tests/extensions/enotify/valid_notify_method.svtest \ + tests/extensions/enotify/notify_method_capability.svtest \ tests/extensions/enotify/errors.svtest \ tests/extensions/enotify/execute.svtest endif diff --git a/TODO b/TODO index 807c5b9ff..f9ca65dda 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ Current: * Implement enotify extension: - - Implement notify_method_capability test (currently skeleton) - Implement parsing :options argument - Check whether handling of error conditions matches the standard - Limit the number of notifications generated (on a per-method basis) diff --git a/src/lib-sieve/plugins/enotify/ext-enotify-common.c b/src/lib-sieve/plugins/enotify/ext-enotify-common.c index c9756a333..c26a801a5 100644 --- a/src/lib-sieve/plugins/enotify/ext-enotify-common.c +++ b/src/lib-sieve/plugins/enotify/ext-enotify-common.c @@ -196,10 +196,42 @@ bool ext_enotify_compile_check_arguments /* * Runtime operand checking */ + +bool ext_enotify_runtime_method_validate +(const struct sieve_runtime_env *renv, unsigned int source_line, + string_t *method_uri) +{ + const struct sieve_enotify_method *method; + const char *uri = str_c(method_uri); + const char *scheme; + + if ( (scheme=ext_enotify_uri_scheme_parse(&uri)) == NULL ) + return FALSE; + + if ( (method=ext_enotify_method_find(scheme)) == NULL ) + return FALSE; + + if ( method->runtime_check_operands != NULL ) { + struct sieve_enotify_log nlog; + + memset(&nlog, 0, sizeof(nlog)); + nlog.location = sieve_error_script_location(renv->script, source_line); + nlog.ehandler = sieve_interpreter_get_error_handler(renv->interp); + nlog.prefix = "valid_notify_method test"; -const struct sieve_enotify_method *ext_enotify_runtime_check_operands + if ( method->runtime_check_operands + (&nlog, str_c(method_uri), uri, NULL, NULL, NULL, NULL) ) + return TRUE; + + return FALSE; + } + + return TRUE; +} + +static const struct sieve_enotify_method *ext_enotify_get_method (const struct sieve_runtime_env *renv, unsigned int source_line, - string_t *method_uri, string_t *message, string_t *from, void **context) + string_t *method_uri, const char **uri_body_r) { const struct sieve_enotify_method *method; const char *uri = str_c(method_uri); @@ -219,39 +251,48 @@ const struct sieve_enotify_method *ext_enotify_runtime_check_operands "invalid notify method '%s'", scheme); return NULL; } + + *uri_body_r = uri; - if ( method->runtime_check_operands != NULL ) { + return method; +} + +const char *ext_enotify_runtime_get_method_capability +(const struct sieve_runtime_env *renv, unsigned int source_line, + string_t *method_uri, const char *capability) +{ + const struct sieve_enotify_method *method; + const char *uri; + + /* Get method */ + method = ext_enotify_get_method(renv, source_line, method_uri, &uri); + if ( method == NULL ) return NULL; + + if ( method->runtime_get_method_capability != NULL ) { struct sieve_enotify_log nlog; memset(&nlog, 0, sizeof(nlog)); nlog.location = sieve_error_script_location(renv->script, source_line); nlog.ehandler = sieve_interpreter_get_error_handler(renv->interp); - nlog.prefix = "notify action"; + nlog.prefix = "notify_method_capability test"; - if ( method->runtime_check_operands(&nlog, str_c(method_uri), uri, message, - from, sieve_result_pool(renv->result), context) ) - return method; - - return NULL; + return method->runtime_get_method_capability + (&nlog, str_c(method_uri), uri, capability); } - *context = NULL; - return method; + return NULL; } -bool ext_enotify_runtime_method_validate +const struct sieve_enotify_method *ext_enotify_runtime_check_operands (const struct sieve_runtime_env *renv, unsigned int source_line, - string_t *method_uri) + string_t *method_uri, string_t *message, string_t *from, void **context) { const struct sieve_enotify_method *method; - const char *uri = str_c(method_uri); - const char *scheme; + const char *uri; - if ( (scheme=ext_enotify_uri_scheme_parse(&uri)) == NULL ) - return FALSE; - - if ( (method=ext_enotify_method_find(scheme)) == NULL ) - return FALSE; + /* Get method */ + method = ext_enotify_get_method(renv, source_line, method_uri, &uri); + if ( method == NULL ) return NULL; if ( method->runtime_check_operands != NULL ) { struct sieve_enotify_log nlog; @@ -259,19 +300,19 @@ bool ext_enotify_runtime_method_validate memset(&nlog, 0, sizeof(nlog)); nlog.location = sieve_error_script_location(renv->script, source_line); nlog.ehandler = sieve_interpreter_get_error_handler(renv->interp); - nlog.prefix = NULL; + nlog.prefix = "notify action"; - if ( method->runtime_check_operands - (&nlog, str_c(method_uri), uri, NULL, NULL, NULL, NULL) ) - return TRUE; + if ( method->runtime_check_operands(&nlog, str_c(method_uri), uri, message, + from, sieve_result_pool(renv->result), context) ) + return method; - return FALSE; + return NULL; } - return TRUE; + *context = NULL; + return method; } - /* * Method logging */ diff --git a/src/lib-sieve/plugins/enotify/ext-enotify-common.h b/src/lib-sieve/plugins/enotify/ext-enotify-common.h index 95c2bf0aa..99012e210 100644 --- a/src/lib-sieve/plugins/enotify/ext-enotify-common.h +++ b/src/lib-sieve/plugins/enotify/ext-enotify-common.h @@ -77,6 +77,10 @@ bool ext_enotify_compile_check_arguments /* * Runtime */ + +const char *ext_enotify_runtime_get_method_capability + (const struct sieve_runtime_env *renv, unsigned int source_line, + string_t *method_uri, const char *capability); const struct sieve_enotify_method *ext_enotify_runtime_check_operands (const struct sieve_runtime_env *renv, unsigned int source_line, diff --git a/src/lib-sieve/plugins/enotify/ntfy-mailto.c b/src/lib-sieve/plugins/enotify/ntfy-mailto.c index f83732726..854cd29e4 100644 --- a/src/lib-sieve/plugins/enotify/ntfy-mailto.c +++ b/src/lib-sieve/plugins/enotify/ntfy-mailto.c @@ -54,10 +54,12 @@ static bool ntfy_mailto_compile_check_uri const char *uri_body); static bool ntfy_mailto_compile_check_from (const struct sieve_enotify_log *nlog, string_t *from); +static const char *ntfy_mailto_runtime_get_notify_capability + (const struct sieve_enotify_log *nlog, const char *uri, const char *uri_body, + const char *capability); static bool ntfy_mailto_runtime_check_operands - (const struct sieve_enotify_log *nlog, const char *uri, - const char *uri_body, string_t *message, string_t *from, - pool_t context_pool, void **context); + (const struct sieve_enotify_log *nlog, const char *uri,const char *uri_body, + string_t *message, string_t *from, pool_t context_pool, void **context); static void ntfy_mailto_action_print (const struct sieve_result_print_env *rpenv, const struct sieve_enotify_action *act); @@ -70,6 +72,7 @@ const struct sieve_enotify_method mailto_notify = { ntfy_mailto_compile_check_uri, NULL, ntfy_mailto_compile_check_from, + ntfy_mailto_runtime_get_notify_capability, ntfy_mailto_runtime_check_operands, ntfy_mailto_action_print, ntfy_mailto_action_execute @@ -518,6 +521,20 @@ static bool ntfy_mailto_compile_check_from * Runtime */ +static const char *ntfy_mailto_runtime_get_notify_capability +(const struct sieve_enotify_log *nlog ATTR_UNUSED, const char *uri ATTR_UNUSED, + const char *uri_body, const char *capability) +{ + if ( !ntfy_mailto_parse_uri(NULL, uri_body, NULL, NULL, NULL, NULL) ) { + return NULL; + } + + if ( strcasecmp(capability, "online") == 0 ) + return "maybe"; + + return NULL; +} + static bool ntfy_mailto_runtime_check_operands (const struct sieve_enotify_log *nlog, const char *uri ATTR_UNUSED, const char *uri_body, string_t *message ATTR_UNUSED, string_t *from, diff --git a/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h b/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h index 8836f9854..768907bd2 100644 --- a/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h +++ b/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h @@ -52,6 +52,9 @@ struct sieve_enotify_method { (const struct sieve_enotify_log *nlog, string_t *from); /* Runtime */ + const char *(*runtime_get_method_capability) + (const struct sieve_enotify_log *nlog, const char *uri, + const char *uri_body, const char *capability); bool (*runtime_check_operands) (const struct sieve_enotify_log *nlog, const char *uri, const char *uri_body, string_t *message, string_t *from, diff --git a/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c b/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c index ac331f55b..fd643e50d 100644 --- a/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c +++ b/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c @@ -184,6 +184,7 @@ static int tst_notifymc_operation_execute struct sieve_match_context *mctx; string_t *notify_uri, *notify_capability; struct sieve_coded_stringlist *key_list; + const char *cap_value; bool matched; /* @@ -225,28 +226,22 @@ static int tst_notifymc_operation_execute sieve_runtime_trace(renv, "NOTIFY_METHOD_CAPABILITY test"); - /*mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list); + cap_value = ext_enotify_runtime_get_method_capability + (renv, 0 /* FIXME */, notify_uri, str_c(notify_capability)); - /* Iterate through all requested strings to match * / - matched = FALSE; - while ( result && !matched && - (result=sieve_coded_stringlist_next_item(source, &src_item)) - && src_item != NULL ) { - const char *src = str_len(src_item) > 0 ? str_c(src_item) : NULL; + if ( cap_value != NULL ) { + mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list); - if ( (mret=sieve_match_value - (mctx, src, str_len(src_item))) < 0 ) { + if ( (mret=sieve_match_value(mctx, cap_value, strlen(cap_value))) < 0 ) result = FALSE; - break; - } - - matched = ( mret > 0 ); - } + matched = ( mret > 0 ); - if ( (mret=sieve_match_end(mctx)) < 0 ) - result = FALSE; - else - matched = ( mret > 0 || matched ); + if ( (mret=sieve_match_end(mctx)) < 0 ) + result = FALSE; + matched = ( mret > 0 ) || matched; + } else { + matched = FALSE; + } if ( result ) { sieve_interpreter_set_test_result(renv->interp, matched); @@ -254,7 +249,5 @@ static int tst_notifymc_operation_execute } sieve_runtime_trace_error(renv, "invalid string list item"); - return SIEVE_EXEC_BIN_CORRUPT;*/ - - return SIEVE_EXEC_OK; + return SIEVE_EXEC_BIN_CORRUPT; } diff --git a/tests/extensions/enotify/notify_method_capability.svtest b/tests/extensions/enotify/notify_method_capability.svtest new file mode 100644 index 000000000..9cdb2bef0 --- /dev/null +++ b/tests/extensions/enotify/notify_method_capability.svtest @@ -0,0 +1,12 @@ +require "vnd.dovecot.testsuite"; +require "enotify"; + +test "Mailto" { + if not notify_method_capability :is "mailto:stephan@rename-it.nl" "online" "maybe" { + test_fail "test should have matched"; + } + + if notify_method_capability :is "mailto:stephan@rename-it.nl" "online" "yes" { + test_fail "test should not have matched"; + } +} diff --git a/tests/extensions/enotify/valid-notify-method.svtest b/tests/extensions/enotify/valid_notify_method.svtest similarity index 77% rename from tests/extensions/enotify/valid-notify-method.svtest rename to tests/extensions/enotify/valid_notify_method.svtest index 6ad92495d..505442fcc 100644 --- a/tests/extensions/enotify/valid-notify-method.svtest +++ b/tests/extensions/enotify/valid_notify_method.svtest @@ -2,28 +2,28 @@ require "vnd.dovecot.testsuite"; require "enotify"; -test "Invalid header name" { +test "Mailto: invalid header name" { if valid_notify_method "mailto:stephan@rename-it.nl?header:=frop" { test_fail "invalid uri accepted"; } } -test "Invalid recipient" { +test "Mailto: invalid recipient" { if valid_notify_method "mailto:stephan%23rename-it.nl" { test_fail "invalid uri accepted"; } } -test "Invalid to header recipient" { +test "Mailto: invalid to header recipient" { if valid_notify_method "mailto:stephan@rename-it.nl?to=nico%23vestingbar.nl" { test_fail "invalid uri accepted"; } } -test "Valid URI" { +test "Mailto: valid URI" { if not valid_notify_method "mailto:stephan@rename-it.nl" { test_fail "valid uri denied"; -- GitLab