mox/imapserver/append_test.go
Mechiel Lukkien c57aeac7f0
prevent unicode-confusion in password by applying PRECIS, and username/email address by applying unicode NFC normalization
an é (e with accent) can also be written as e+\u0301. the first form is NFC,
the second NFD. when logging in, we transform usernames (email addresses) to
NFC. so both forms will be accepted. if a client is using NFD, they can log
in too.

for passwords, we apply the PRECIS "opaquestring", which (despite the name)
transforms the value too: unicode spaces are replaced with ascii spaces. the
string is also normalized to NFC. PRECIS may reject confusing passwords when
you set a password.
2024-03-09 09:20:29 +01:00

92 lines
3.4 KiB
Go

package imapserver
import (
"testing"
"github.com/mjl-/mox/imapclient"
)
func TestAppend(t *testing.T) {
defer mockUIDValidity()()
tc := start(t) // note: with switchboard because this connection stays alive unlike tc2.
defer tc.close()
tc2 := startNoSwitchboard(t) // note: without switchboard because this connection will break during tests.
defer tc2.close()
tc3 := startNoSwitchboard(t)
defer tc3.close()
tc2.client.Login("mjl@mox.example", password0)
tc2.client.Select("inbox")
tc.client.Login("mjl@mox.example", password0)
tc.client.Select("inbox")
tc3.client.Login("mjl@mox.example", password0)
tc2.transactf("bad", "append") // Missing params.
tc2.transactf("bad", `append inbox`) // Missing message.
tc2.transactf("bad", `append inbox "test"`) // Message must be literal.
// Syntax error for line ending in literal causes connection abort.
tc2.transactf("bad", "append inbox (\\Badflag) {1+}\r\nx") // Unknown flag.
tc2 = startNoSwitchboard(t)
defer tc2.close()
tc2.client.Login("mjl@mox.example", password0)
tc2.client.Select("inbox")
tc2.transactf("bad", "append inbox () \"bad time\" {1+}\r\nx") // Bad time.
tc2 = startNoSwitchboard(t)
defer tc2.close()
tc2.client.Login("mjl@mox.example", password0)
tc2.client.Select("inbox")
tc2.transactf("no", "append nobox (\\Seen) \" 1-Jan-2022 10:10:00 +0100\" {1}")
tc2.xcode("TRYCREATE")
tc2.transactf("ok", "append inbox (\\Seen Label1 $label2) \" 1-Jan-2022 10:10:00 +0100\" {1+}\r\nx")
tc2.xuntagged(imapclient.UntaggedExists(1))
tc2.xcodeArg(imapclient.CodeAppendUID{UIDValidity: 1, UID: 1})
tc.transactf("ok", "noop")
uid1 := imapclient.FetchUID(1)
flags := imapclient.FetchFlags{`\Seen`, "$label2", "label1"}
tc.xuntagged(imapclient.UntaggedExists(1), imapclient.UntaggedFetch{Seq: 1, Attrs: []imapclient.FetchAttr{uid1, flags}})
tc3.transactf("ok", "noop")
tc3.xuntagged() // Inbox is not selected, nothing to report.
tc2.transactf("ok", "append inbox (\\Seen) \" 1-Jan-2022 10:10:00 +0100\" UTF8 ({47+}\r\ncontent-type: just completely invalid;;\r\n\r\ntest)")
tc2.xuntagged(imapclient.UntaggedExists(2))
tc2.xcodeArg(imapclient.CodeAppendUID{UIDValidity: 1, UID: 2})
tc2.transactf("ok", "append inbox (\\Seen) \" 1-Jan-2022 10:10:00 +0100\" UTF8 ({31+}\r\ncontent-type: text/plain;\n\ntest)")
tc2.xuntagged(imapclient.UntaggedExists(3))
tc2.xcodeArg(imapclient.CodeAppendUID{UIDValidity: 1, UID: 3})
// Messages that we cannot parse are marked as application/octet-stream. Perhaps
// the imap client knows how to deal with them.
tc2.transactf("ok", "uid fetch 2 body")
uid2 := imapclient.FetchUID(2)
xbs := imapclient.FetchBodystructure{
RespAttr: "BODY",
Body: imapclient.BodyTypeBasic{
MediaType: "APPLICATION",
MediaSubtype: "OCTET-STREAM",
BodyFields: imapclient.BodyFields{
Octets: 4,
},
},
}
tc2.xuntagged(imapclient.UntaggedFetch{Seq: 2, Attrs: []imapclient.FetchAttr{uid2, xbs}})
tclimit := startArgs(t, false, false, true, true, "limit")
defer tclimit.close()
tclimit.client.Login("limit@mox.example", password0)
tclimit.client.Select("inbox")
// First message of 1 byte is within limits.
tclimit.transactf("ok", "append inbox (\\Seen Label1 $label2) \" 1-Jan-2022 10:10:00 +0100\" {1+}\r\nx")
tclimit.xuntagged(imapclient.UntaggedExists(1))
// Second message would take account past limit.
tclimit.transactf("no", "append inbox (\\Seen Label1 $label2) \" 1-Jan-2022 10:10:00 +0100\" {1+}\r\nx")
tclimit.xcode("OVERQUOTA")
}