Skip to content

Commit

Permalink
Sieve: add implicit_keep_target action
Browse files Browse the repository at this point in the history
  • Loading branch information
ksmurchison committed Jun 28, 2023
1 parent d4c7b44 commit 9ff4275
Show file tree
Hide file tree
Showing 19 changed files with 424 additions and 93 deletions.
2 changes: 2 additions & 0 deletions cassandane/Cassandane/Cyrus/Sieve.pm
Original file line number Diff line number Diff line change
Expand Up @@ -7275,4 +7275,6 @@ EOF
$self->check_messages({ 1 => $msg }, check_guid => 0);
}

use Cassandane::Tiny::Loader 'tiny-tests/Sieve';

1;
37 changes: 37 additions & 0 deletions cassandane/tiny-tests/Sieve/implicit-keep-target-bad
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!perl
use Cassandane::Tiny;

sub test_implicit_keep_target_bad
:min_version_3_9 :needs_component_sieve :NoAltNameSpace
{
my ($self) = @_;

my ($res, $errs) = $self->compile_sievec('norequire', <<EOF
implicit_keep_target :mailboxid "xxx" :specialuse "\\\\Important" "INBOX";
EOF
);

$self->assert_str_equals('failure', $res);
$self->assert_matches(qr/vnd.cyrus.implicit_keep_target extension MUST be enabled/, $errs);
$self->assert_matches(qr/mailboxid extension MUST be enabled/, $errs);
$self->assert_matches(qr/special-use extension MUST be enabled/, $errs);

($res, $errs) = $self->compile_sievec('conflict', <<EOF
require [ "vnd.cyrus.implicit_keep_target", "special-use", "mailboxid"];
implicit_keep_target :mailboxid "xxx" :specialuse "\\\\Important" "INBOX";
EOF
);

$self->assert_str_equals('failure', $res);
$self->assert_matches(qr/tag :specialuse MUST NOT be used with tag :mailboxid/, $errs);

($res, $errs) = $self->compile_sievec('badsyntax', <<EOF
require [ "vnd.cyrus.implicit_keep_target", "special-use", "mailboxid"];
implicit_keep_target :mailboxid "xxx" :specialuse "\\\\Important";
EOF
);

$self->assert_str_equals('failure', $res);
$self->assert_matches(qr/syntax error/, $errs);
}

35 changes: 35 additions & 0 deletions cassandane/tiny-tests/Sieve/implicit-keep-target-mailboxid
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!perl
use Cassandane::Tiny;

sub test_implicit_keep_target_mailboxid
:min_version_3_9 :needs_component_sieve :NoAltNameSpace
{
my ($self) = @_;

my $folder = "INBOX.foo";

xlog $self, "Create folder";
my $imaptalk = $self->{store}->get_client();
$imaptalk->create($folder)
or die "Cannot create $folder: $@";

xlog $self, "Get folder id";
my $res = $imaptalk->status($folder, ['mailboxid']);
my $folderid = $res->{mailboxid}[0];

xlog $self, "Install a script";
$self->{instance}->install_sieve_script(<<EOF
require ["vnd.cyrus.implicit_keep_target", "mailboxid"];
implicit_keep_target :mailboxid "$folderid" "INBOX";
EOF
);

xlog $self, "Deliver a message";
my $msg = $self->{gen}->generate(subject => "Message 1");
$self->{instance}->deliver($msg);

xlog $self, "Check that the message made it to $folder";
$self->{store}->set_folder($folder);
$self->check_messages({ 1 => $msg }, check_guid => 0);
}

31 changes: 31 additions & 0 deletions cassandane/tiny-tests/Sieve/implicit-keep-target-mailboxname
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!perl
use Cassandane::Tiny;

sub test_implicit_keep_target_mailboxname
:min_version_3_9 :needs_component_sieve :NoAltNameSpace
{
my ($self) = @_;

my $folder = "INBOX.foo";

xlog $self, "Create folder";
my $imaptalk = $self->{store}->get_client();
$imaptalk->create($folder)
or die "Cannot create $folder: $@";

xlog $self, "Install a script";
$self->{instance}->install_sieve_script(<<EOF
require ["vnd.cyrus.implicit_keep_target"];
implicit_keep_target "$folder";
EOF
);

xlog $self, "Deliver a message";
my $msg = $self->{gen}->generate(subject => "Message 1");
$self->{instance}->deliver($msg);

xlog $self, "Check that the message made it to $folder";
$self->{store}->set_folder($folder);
$self->check_messages({ 1 => $msg }, check_guid => 0);
}

51 changes: 51 additions & 0 deletions cassandane/tiny-tests/Sieve/implicit-keep-target-none
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!perl
use Cassandane::Tiny;

sub test_implicit_keep_target_none
:min_version_3_9 :needs_component_sieve :NoAltNameSpace
{
my ($self) = @_;

my $folder = "INBOX.foo";

xlog $self, "Create folder";
my $imaptalk = $self->{store}->get_client();
$imaptalk->create($folder)
or die "Cannot create $folder: $@";

xlog $self, "Allow plus address delivery";
$imaptalk->setacl($folder, 'anyone' => 'p');
my $imaptalk = $self->{store}->get_client();

xlog $self, "Install a script";
$self->{instance}->install_sieve_script(<<EOF
require ["vnd.cyrus.implicit_keep_target", "imap4flags"];
if header :comparator "i;ascii-casemap" :is "Subject" "explicit" {
addflag "\\\\Flagged";
keep;
}
EOF
);

xlog $self, "Deliver a message";
my $msg = $self->{gen}->generate(subject => "Implicit");
$self->{instance}->deliver($msg);

xlog $self, "Check that the message made it to INBOX";
$self->{store}->set_folder('INBOX');
$self->{store}->set_fetch_attributes(qw(uid flags));
$msg->set_attribute(uid => 1);
$msg->set_attribute(flags => [ '\\Recent' ]);
$self->check_messages({ 1 => $msg }, check_guid => 0);

xlog $self, "Deliver a message to plus address";
$msg = $self->{gen}->generate(subject => "Explicit");
$self->{instance}->deliver($msg, user => "cassandane+foo");

xlog $self, "Check that the message made it to $folder";
$self->{store}->set_folder($folder);
$msg->set_attribute(uid => 1);
$msg->set_attribute(flags => [ '\\Recent', '\\Flagged']);
$self->check_messages({ 1 => $msg }, check_guid => 0);
}

31 changes: 31 additions & 0 deletions cassandane/tiny-tests/Sieve/implicit-keep-target-specialuse
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!perl
use Cassandane::Tiny;

sub test_implicit_keep_target_specialuse
:min_version_3_9 :needs_component_sieve :NoAltNameSpace
{
my ($self) = @_;

my $folder = "INBOX.foo";

xlog $self, "Create folder";
my $imaptalk = $self->{store}->get_client();
$imaptalk->create($folder, "(use (\\Important))")
or die "Cannot create $folder: $@";

xlog $self, "Install a script";
$self->{instance}->install_sieve_script(<<EOF
require ["vnd.cyrus.implicit_keep_target", "special-use"];
implicit_keep_target :specialuse "\\\\Important" "INBOX";
EOF
);

xlog $self, "Deliver a message";
my $msg = $self->{gen}->generate(subject => "Message 1");
$self->{instance}->deliver($msg);

xlog $self, "Check that the message made it to $folder";
$self->{store}->set_folder($folder);
$self->check_messages({ 1 => $msg }, check_guid => 0);
}

20 changes: 20 additions & 0 deletions changes/next/sieve-implicit-keep-target
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

Description:

Adds an 'implicit_keep_target' action to Sieve to change the target mailbox
for an implicit keep.

Syntax:

implicit_keep_target [ :specialuse <string> | :mailboxid <string> ] <folder: string>


Config changes:

The bitfield "vnd.cyrus.implicit_keep_target" has been added to
the "sieve_extensions" option to control the availability of this option.


Upgrade instructions:

None.
2 changes: 1 addition & 1 deletion lib/imapoptions
Original file line number Diff line number Diff line change
Expand Up @@ -2574,7 +2574,7 @@ product version in the capabilities
assumed. */
*/

{ "sieve_extensions", "fileinto reject vacation vacation-seconds notify include envelope environment body relational regex subaddress copy date index imap4flags mailbox mboxmetadata servermetadata variables editheader extlists duplicate ihave fcc special-use redirect-dsn redirect-deliverby mailboxid vnd.cyrus.log vnd.cyrus.jmapquery vnd.cyrus.imip snooze", BITFIELD("fileinto", "reject", "vacation", "vacation-seconds", "notify", "include", "envelope", "environment", "body", "relational", "regex", "subaddress", "copy", "date", "index", "imap4flags=imapflags", "mailbox", "mboxmetadata", "servermetadata", "variables", "editheader", "extlists", "duplicate", "ihave", "fcc", "special-use", "redirect-dsn", "redirect-deliverby", "mailboxid", "vnd.cyrus.log=x-cyrus-log", "vnd.cyrus.jmapquery=x-cyrus-jmapquery", "vnd.cyrus.imip", "snooze=vnd.cyrus.snooze=x-cyrus-snooze"), "3.6.0" }
{ "sieve_extensions", "fileinto reject vacation vacation-seconds notify include envelope environment body relational regex subaddress copy date index imap4flags mailbox mboxmetadata servermetadata variables editheader extlists duplicate ihave fcc special-use redirect-dsn redirect-deliverby mailboxid vnd.cyrus.log vnd.cyrus.jmapquery vnd.cyrus.imip snooze vnd.cyrus.implicit_keep_target", BITFIELD("fileinto", "reject", "vacation", "vacation-seconds", "notify", "include", "envelope", "environment", "body", "relational", "regex", "subaddress", "copy", "date", "index", "imap4flags=imapflags", "mailbox", "mboxmetadata", "servermetadata", "variables", "editheader", "extlists", "duplicate", "ihave", "fcc", "special-use", "redirect-dsn", "redirect-deliverby", "mailboxid", "vnd.cyrus.log=x-cyrus-log", "vnd.cyrus.jmapquery=x-cyrus-jmapquery", "vnd.cyrus.imip", "snooze=vnd.cyrus.snooze=x-cyrus-snooze", "vnd.cyrus.implicit_keep_target"), "UNRELEASED" }
/* Space-separated list of Sieve extensions allowed to be used in
sieve scripts, enforced at submission by timsieved(8). Any
previously installed script will be unaffected by this option and
Expand Down
1 change: 1 addition & 0 deletions sieve/bc_emit.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,7 @@ static int bc_action_emit(int fd, int codep, int stopcodep,
case B_RETURN:
case B_SNOOZE:
case B_PROCESSIMIP:
case B_IKEEP_TARGET:
/* Spew the action parameters */
ret = bc_params_emit(fd, &codep, stopcodep, bc);
if (ret < 0) return -1;
Expand Down
35 changes: 24 additions & 11 deletions sieve/bc_eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -1794,9 +1794,9 @@ int sieve_eval_bc(sieve_execute_t *exe, int *impl_keep_p, sieve_interp_t *i,
case B_FILEINTO_COPY:
case B_FILEINTO_ORIG:
{
const char *folder = cmd.u.f.folder;
const char *mailboxid = cmd.u.f.mailboxid;
const char *specialuse = cmd.u.f.specialuse;
const char *folder = cmd.u.f.t.folder;
const char *mailboxid = cmd.u.f.t.mailboxid;
const char *specialuse = cmd.u.f.t.specialuse;
struct buf *headers = NULL;

if (requires & BFE_VARIABLES) {
Expand Down Expand Up @@ -1833,16 +1833,16 @@ int sieve_eval_bc(sieve_execute_t *exe, int *impl_keep_p, sieve_interp_t *i,
case B_SNOOZE_TZID:
case B_SNOOZE_ORIG:
{
const char *awaken_mbox = cmd.u.sn.f.folder;
const char *awaken_mboxid = cmd.u.sn.f.mailboxid;
const char *awaken_spluse = cmd.u.sn.f.specialuse;
const char *awaken_mbox = cmd.u.sn.f.t.folder;
const char *awaken_mboxid = cmd.u.sn.f.t.mailboxid;
const char *awaken_spluse = cmd.u.sn.f.t.specialuse;
const char *tzid = cmd.u.sn.tzid;
strarray_t *addflags = NULL;
strarray_t *removeflags = NULL;
struct buf *headers = NULL;

if (!awaken_mboxid && cmd.u.sn.is_mboxid) {
awaken_mboxid = cmd.u.sn.f.folder;
awaken_mboxid = cmd.u.sn.f.t.folder;
awaken_mbox = NULL;
}

Expand Down Expand Up @@ -2162,11 +2162,11 @@ int sieve_eval_bc(sieve_execute_t *exe, int *impl_keep_p, sieve_interp_t *i,
{
int respond;
sieve_fileinto_context_t fcc = {
cmd.u.v.fcc.folder,
cmd.u.v.fcc.specialuse,
cmd.u.v.fcc.t.folder,
cmd.u.v.fcc.t.specialuse,
NULL,
cmd.u.v.fcc.create,
cmd.u.v.fcc.mailboxid,
cmd.u.v.fcc.t.mailboxid,
/*headers*/NULL,
/*resolved_mailbox*/NULL
};
Expand Down Expand Up @@ -2541,6 +2541,12 @@ int sieve_eval_bc(sieve_execute_t *exe, int *impl_keep_p, sieve_interp_t *i,
}
break;

case B_IKEEP_TARGET:
i->ikeep.folder = cmd.u.ikt.folder;
i->ikeep.mailboxid = cmd.u.ikt.mailboxid;
i->ikeep.specialuse = cmd.u.ikt.specialuse;
break;

case B_ERROR:
res = SIEVE_RUN_ERROR;
*errmsg = cmd.u.str;
Expand All @@ -2567,7 +2573,14 @@ int sieve_eval_bc(sieve_execute_t *exe, int *impl_keep_p, sieve_interp_t *i,

if (i->edited_headers) i->getheadersection(m, &headers);

res = do_keep(i, sc, actions, actionflags, headers);
if (i->ikeep.folder) {
res = do_fileinto(i, sc, actions, i->ikeep.folder,
i->ikeep.specialuse, 1, 0, i->ikeep.mailboxid,
actionflags, headers);
}
else {
res = do_keep(i, sc, actions, actionflags, headers);
}

implicit_keep = 0;
}
Expand Down
Loading

0 comments on commit 9ff4275

Please sign in to comment.