This is the v1 version, had the v2 before.
This commit is contained in:
299
client/cmd_noauth_test.go
Normal file
299
client/cmd_noauth_test.go
Normal file
@@ -0,0 +1,299 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/emersion/go-imap"
|
||||
"github.com/emersion/go-imap/internal"
|
||||
"github.com/emersion/go-sasl"
|
||||
)
|
||||
|
||||
func TestClient_StartTLS(t *testing.T) {
|
||||
c, s := newTestClient(t)
|
||||
defer s.Close()
|
||||
|
||||
cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
|
||||
if err != nil {
|
||||
t.Fatal("cannot load test certificate:", err)
|
||||
}
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
Certificates: []tls.Certificate{cert},
|
||||
}
|
||||
|
||||
if c.IsTLS() {
|
||||
t.Fatal("Client has TLS enabled before STARTTLS")
|
||||
}
|
||||
|
||||
if ok, err := c.SupportStartTLS(); err != nil {
|
||||
t.Fatalf("c.SupportStartTLS() = %v", err)
|
||||
} else if !ok {
|
||||
t.Fatalf("c.SupportStartTLS() = %v, want true", ok)
|
||||
}
|
||||
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- c.StartTLS(tlsConfig)
|
||||
}()
|
||||
|
||||
tag, cmd := s.ScanCmd()
|
||||
if cmd != "STARTTLS" {
|
||||
t.Fatalf("client sent command %v, want STARTTLS", cmd)
|
||||
}
|
||||
s.WriteString(tag + " OK Begin TLS negotiation now\r\n")
|
||||
|
||||
ss := tls.Server(s.Conn, tlsConfig)
|
||||
if err := ss.Handshake(); err != nil {
|
||||
t.Fatal("cannot perform TLS handshake:", err)
|
||||
}
|
||||
|
||||
if err := <-done; err != nil {
|
||||
t.Error("c.StartTLS() =", err)
|
||||
}
|
||||
|
||||
if !c.IsTLS() {
|
||||
t.Errorf("Client has not TLS enabled after STARTTLS")
|
||||
}
|
||||
|
||||
go func() {
|
||||
_, err := c.Capability()
|
||||
done <- err
|
||||
}()
|
||||
|
||||
tag, cmd = newCmdScanner(ss).ScanCmd()
|
||||
if cmd != "CAPABILITY" {
|
||||
t.Fatalf("client sent command %v, want CAPABILITY", cmd)
|
||||
}
|
||||
io.WriteString(ss, "* CAPABILITY IMAP4rev1 AUTH=PLAIN\r\n")
|
||||
io.WriteString(ss, tag+" OK CAPABILITY completed.\r\n")
|
||||
}
|
||||
|
||||
func TestClient_Authenticate(t *testing.T) {
|
||||
c, s := newTestClient(t)
|
||||
defer s.Close()
|
||||
|
||||
if ok, err := c.SupportAuth(sasl.Plain); err != nil {
|
||||
t.Fatalf("c.SupportAuth(sasl.Plain) = %v", err)
|
||||
} else if !ok {
|
||||
t.Fatalf("c.SupportAuth(sasl.Plain) = %v, want true", ok)
|
||||
}
|
||||
|
||||
sasl := sasl.NewPlainClient("", "username", "password")
|
||||
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- c.Authenticate(sasl)
|
||||
}()
|
||||
|
||||
tag, cmd := s.ScanCmd()
|
||||
if cmd != "AUTHENTICATE PLAIN" {
|
||||
t.Fatalf("client sent command %v, want AUTHENTICATE PLAIN", cmd)
|
||||
}
|
||||
|
||||
s.WriteString("+ \r\n")
|
||||
|
||||
wantLine := "AHVzZXJuYW1lAHBhc3N3b3Jk"
|
||||
if line := s.ScanLine(); line != wantLine {
|
||||
t.Fatalf("client sent auth %v, want %v", line, wantLine)
|
||||
}
|
||||
|
||||
s.WriteString(tag + " OK AUTHENTICATE completed\r\n")
|
||||
|
||||
if err := <-done; err != nil {
|
||||
t.Fatalf("c.Authenticate() = %v", err)
|
||||
}
|
||||
|
||||
if state := c.State(); state != imap.AuthenticatedState {
|
||||
t.Errorf("c.State() = %v, want %v", state, imap.AuthenticatedState)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_Authenticate_InitialResponse(t *testing.T) {
|
||||
c, s := newTestClientWithGreeting(t, "* OK [CAPABILITY IMAP4rev1 SASL-IR STARTTLS AUTH=PLAIN] Server ready.\r\n")
|
||||
defer s.Close()
|
||||
|
||||
if ok, err := c.SupportAuth(sasl.Plain); err != nil {
|
||||
t.Fatalf("c.SupportAuth(sasl.Plain) = %v", err)
|
||||
} else if !ok {
|
||||
t.Fatalf("c.SupportAuth(sasl.Plain) = %v, want true", ok)
|
||||
}
|
||||
|
||||
sasl := sasl.NewPlainClient("", "username", "password")
|
||||
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- c.Authenticate(sasl)
|
||||
}()
|
||||
|
||||
tag, cmd := s.ScanCmd()
|
||||
if cmd != "AUTHENTICATE PLAIN AHVzZXJuYW1lAHBhc3N3b3Jk" {
|
||||
t.Fatalf("client sent command %v, want AUTHENTICATE PLAIN AHVzZXJuYW1lAHBhc3N3b3Jk", cmd)
|
||||
}
|
||||
|
||||
s.WriteString(tag + " OK AUTHENTICATE completed\r\n")
|
||||
|
||||
if err := <-done; err != nil {
|
||||
t.Fatalf("c.Authenticate() = %v", err)
|
||||
}
|
||||
|
||||
if state := c.State(); state != imap.AuthenticatedState {
|
||||
t.Errorf("c.State() = %v, want %v", state, imap.AuthenticatedState)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_Login_Success(t *testing.T) {
|
||||
c, s := newTestClient(t)
|
||||
defer s.Close()
|
||||
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- c.Login("username", "password")
|
||||
}()
|
||||
|
||||
tag, cmd := s.ScanCmd()
|
||||
if cmd != "LOGIN \"username\" \"password\"" {
|
||||
t.Fatalf("client sent command %v, want LOGIN username password", cmd)
|
||||
}
|
||||
s.WriteString(tag + " OK LOGIN completed\r\n")
|
||||
|
||||
if err := <-done; err != nil {
|
||||
t.Fatalf("c.Login() = %v", err)
|
||||
}
|
||||
|
||||
if state := c.State(); state != imap.AuthenticatedState {
|
||||
t.Errorf("c.State() = %v, want %v", state, imap.AuthenticatedState)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_Login_8bitSync(t *testing.T) {
|
||||
c, s := newTestClientWithGreeting(t, "* OK [CAPABILITY IMAP4rev1 SASL-IR STARTTLS AUTH=PLAIN] Server ready.\r\n")
|
||||
defer s.Close()
|
||||
|
||||
// Use of UTF-8 will force go-imap to send password in literal.
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- c.Login("username", "пароль")
|
||||
}()
|
||||
|
||||
tag, cmd := s.ScanCmd()
|
||||
if cmd != "LOGIN \"username\" {12}" {
|
||||
t.Fatalf("client sent command %v, want LOGIN \"username\" {12}", cmd)
|
||||
}
|
||||
s.WriteString("+ send literal\r\n")
|
||||
pass := s.ScanLine()
|
||||
if pass != "пароль" {
|
||||
t.Fatalf("client sent %v, want {12}'пароль' literal", pass)
|
||||
}
|
||||
s.WriteString(tag + " OK LOGIN completed\r\n")
|
||||
|
||||
if err := <-done; err != nil {
|
||||
t.Fatalf("c.Login() = %v", err)
|
||||
}
|
||||
|
||||
if state := c.State(); state != imap.AuthenticatedState {
|
||||
t.Errorf("c.State() = %v, want %v", state, imap.AuthenticatedState)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_Login_8bitNonSync(t *testing.T) {
|
||||
c, s := newTestClientWithGreeting(t, "* OK [CAPABILITY IMAP4rev1 LITERAL- SASL-IR STARTTLS AUTH=PLAIN] Server ready.\r\n")
|
||||
defer s.Close()
|
||||
|
||||
// Use of UTF-8 will force go-imap to send password in literal.
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- c.Login("username", "пароль")
|
||||
}()
|
||||
|
||||
tag, cmd := s.ScanCmd()
|
||||
if cmd != "LOGIN \"username\" {12+}" {
|
||||
t.Fatalf("client sent command %v, want LOGIN \"username\" {12+}", cmd)
|
||||
}
|
||||
pass := s.ScanLine()
|
||||
if pass != "пароль" {
|
||||
t.Fatalf("client sent %v, want {12+}'пароль' literal", pass)
|
||||
}
|
||||
s.WriteString(tag + " OK LOGIN completed\r\n")
|
||||
|
||||
if err := <-done; err != nil {
|
||||
t.Fatalf("c.Login() = %v", err)
|
||||
}
|
||||
|
||||
if state := c.State(); state != imap.AuthenticatedState {
|
||||
t.Errorf("c.State() = %v, want %v", state, imap.AuthenticatedState)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_Login_Error(t *testing.T) {
|
||||
c, s := newTestClient(t)
|
||||
defer s.Close()
|
||||
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- c.Login("username", "password")
|
||||
}()
|
||||
|
||||
tag, cmd := s.ScanCmd()
|
||||
if cmd != "LOGIN \"username\" \"password\"" {
|
||||
t.Fatalf("client sent command %v, want LOGIN username password", cmd)
|
||||
}
|
||||
s.WriteString(tag + " NO LOGIN incorrect\r\n")
|
||||
|
||||
if err := <-done; err == nil {
|
||||
t.Fatal("c.Login() = nil, want LOGIN incorrect")
|
||||
}
|
||||
|
||||
if state := c.State(); state != imap.NotAuthenticatedState {
|
||||
t.Errorf("c.State() = %v, want %v", state, imap.NotAuthenticatedState)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_Login_State_Allowed(t *testing.T) {
|
||||
c, s := newTestClient(t)
|
||||
defer s.Close()
|
||||
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- c.Login("username", "password")
|
||||
}()
|
||||
|
||||
tag, cmd := s.ScanCmd()
|
||||
if cmd != "LOGIN \"username\" \"password\"" {
|
||||
t.Fatalf("client sent command %v, want LOGIN \"username\" \"password\"", cmd)
|
||||
}
|
||||
s.WriteString(tag + " OK LOGIN completed\r\n")
|
||||
|
||||
if err := <-done; err != nil {
|
||||
t.Fatalf("c.Login() = %v", err)
|
||||
}
|
||||
|
||||
if state := c.State(); state != imap.AuthenticatedState {
|
||||
t.Errorf("c.State() = %v, want %v", state, imap.AuthenticatedState)
|
||||
}
|
||||
|
||||
go func() {
|
||||
done <- c.Login("username", "password")
|
||||
}()
|
||||
if err := <-done; err != ErrAlreadyLoggedIn {
|
||||
t.Fatalf("c.Login() = %v, want %v", err, ErrAlreadyLoggedIn)
|
||||
}
|
||||
|
||||
go func() {
|
||||
done <- c.Logout()
|
||||
}()
|
||||
|
||||
s.ScanCmd()
|
||||
s.WriteString("* BYE Client asked to close the connection.\r\n")
|
||||
s.WriteString(tag + " OK LOGOUT completed\r\n")
|
||||
|
||||
if err := <-done; err != nil {
|
||||
t.Fatalf("c.Logout() = %v", err)
|
||||
}
|
||||
|
||||
if err := c.Login("username", "password"); err == ErrAlreadyLoggedIn {
|
||||
t.Errorf("Client is logout, login must not give %v", ErrAlreadyLoggedIn)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user