2023-01-30 16:27:06 +03:00
|
|
|
package imapserver
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/mjl-/mox/imapclient"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestCreate(t *testing.T) {
|
|
|
|
tc := start(t)
|
|
|
|
defer tc.close()
|
|
|
|
|
|
|
|
tc2 := startNoSwitchboard(t)
|
|
|
|
defer tc2.close()
|
|
|
|
|
2024-03-09 01:29:15 +03:00
|
|
|
tc.client.Login("mjl@mox.example", password0)
|
|
|
|
tc2.client.Login("mjl@mox.example", password0)
|
2023-01-30 16:27:06 +03:00
|
|
|
|
|
|
|
tc.transactf("no", "create inbox") // Already exists and not allowed. ../rfc/9051:1913
|
|
|
|
tc.transactf("no", "create Inbox") // Idem.
|
|
|
|
|
|
|
|
// ../rfc/9051:1937
|
|
|
|
tc.transactf("ok", "create inbox/a/c")
|
|
|
|
tc.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "Inbox/a"}, imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "Inbox/a/c"})
|
|
|
|
|
|
|
|
tc2.transactf("ok", "noop")
|
|
|
|
tc2.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "Inbox/a"}, imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "Inbox/a/c"})
|
|
|
|
|
|
|
|
tc.transactf("no", "create inbox/a/c") // Exists.
|
|
|
|
|
|
|
|
tc.transactf("ok", "create inbox/a/x")
|
|
|
|
tc.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "Inbox/a/x"})
|
|
|
|
|
|
|
|
tc2.transactf("ok", "noop")
|
|
|
|
tc2.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "Inbox/a/x"})
|
|
|
|
|
|
|
|
// ../rfc/9051:1934
|
|
|
|
tc.transactf("ok", "create mailbox/")
|
2023-12-14 22:09:13 +03:00
|
|
|
tc.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "mailbox"})
|
|
|
|
|
|
|
|
// OldName is only set for IMAP4rev2 or NOTIFY.
|
|
|
|
tc.client.Enable("imap4rev2")
|
|
|
|
tc.transactf("ok", "create mailbox2/")
|
|
|
|
tc.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "mailbox2", OldName: "mailbox2/"})
|
2023-01-30 16:27:06 +03:00
|
|
|
|
|
|
|
tc2.transactf("ok", "noop")
|
2023-12-14 22:09:13 +03:00
|
|
|
tc2.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "mailbox"}, imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "mailbox2"})
|
2023-01-30 16:27:06 +03:00
|
|
|
|
|
|
|
// If we are already subscribed, create should still work, and we still want to see the subscribed flag.
|
|
|
|
tc.transactf("ok", "subscribe newbox")
|
|
|
|
tc2.transactf("ok", "noop")
|
|
|
|
tc2.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`, `\NonExistent`}, Separator: '/', Mailbox: "newbox"})
|
|
|
|
|
|
|
|
tc.transactf("ok", "create newbox")
|
|
|
|
tc.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "newbox"})
|
|
|
|
tc2.transactf("ok", "noop")
|
|
|
|
tc2.xuntagged(imapclient.UntaggedList{Flags: []string{`\Subscribed`}, Separator: '/', Mailbox: "newbox"})
|
|
|
|
|
|
|
|
// todo: test create+delete+create of a name results in a higher uidvalidity.
|
|
|
|
|
|
|
|
tc.transactf("no", "create /bad/root")
|
|
|
|
tc.transactf("no", "create bad//root") // Cannot have internal duplicate slashes.
|
|
|
|
tc.transactf("no", `create ""`) // Refuse empty mailbox name.
|
|
|
|
// We are not allowing special characters.
|
|
|
|
tc.transactf("bad", `create "\n"`)
|
|
|
|
tc.transactf("bad", `create "\x7f"`)
|
|
|
|
tc.transactf("bad", `create "\x9f"`)
|
|
|
|
tc.transactf("bad", `create "\u2028"`)
|
|
|
|
tc.transactf("bad", `create "\u2029"`)
|
imapserver: allow creating mailboxes with characters &#*%, and encode mailbox names in imap with imaputf7 when needed
the imapserver started with imap4rev2-only and utf8=only. to prevent potential
issues with imaputf7, which makes "&" special, we refused any mailbox with an
"&" in the name. we already tried decoding utf7, falling back to using a
mailbox name verbatim. that behaviour wasn't great. we now treat the enabled
extensions IMAP4rev2 and/or UTF8=ACCEPT as indication whether mailbox names are
in imaputf7. if they are, the encoding must be correct.
we now also send mailbox names in imaputf7 when imap4rev2/utf8=accept isn't
enabled.
and we now allow "*" and "%" (wildcard characters for matching) in mailbox
names. not ideal for IMAP LIST with patterns, but not enough reason to refuse
them in mailbox names. people that migrate may run into this, possibly as
blocker.
we also allow "#" in mailbox names, but not as first character, to prevent
potential clashes with IMAP namespaces in the future.
based on report from Damian Poddebniak using
https://github.com/duesee/imap-flow and issue #110, thanks for reporting!
2024-01-01 15:15:25 +03:00
|
|
|
tc.transactf("ok", `create "%%"`)
|
|
|
|
tc.transactf("ok", `create "*"`)
|
|
|
|
tc.transactf("no", `create "#"`) // Leading hash not allowed.
|
|
|
|
tc.transactf("ok", `create "test#"`)
|
|
|
|
|
|
|
|
// UTF-7 checks are only for IMAP4 before rev2 and without UTF8=ACCEPT.
|
|
|
|
tc.transactf("ok", `create "&"`) // Interpreted as UTF-8, no UTF-7.
|
|
|
|
tc2.transactf("bad", `create "&"`) // Bad UTF-7.
|
|
|
|
tc2.transactf("ok", `create "&Jjo-"`) // ☺, valid UTF-7.
|
2023-01-30 16:27:06 +03:00
|
|
|
}
|