diff --git a/auth.go b/auth.go index 7888819..314cb50 100644 --- a/auth.go +++ b/auth.go @@ -4,7 +4,11 @@ package mail -import "errors" +import ( + "errors" + "fmt" + "strings" +) // SMTPAuthType is a type wrapper for a string type. It represents the type of SMTP authentication // mechanism to be used. @@ -134,3 +138,33 @@ var ( // authentication type. ErrSCRAMSHA256PLUSAuthNotSupported = errors.New("server does not support SMTP AUTH type: SCRAM-SHA-256-PLUS") ) + +// UnmarshalString satisfies the fig.StringUnmarshaler interface for the SMTPAuthType type +// https://pkg.go.dev/github.com/kkyr/fig#StringUnmarshaler +func (sa *SMTPAuthType) UnmarshalString(value string) error { + switch strings.ToLower(value) { + case "cram-md5", "crammd5", "cram": + *sa = SMTPAuthCramMD5 + case "custom": + *sa = SMTPAuthCustom + case "login": + *sa = SMTPAuthLogin + case "none", "noauth", "no": + *sa = SMTPAuthNoAuth + case "plain": + *sa = SMTPAuthPlain + case "scram-sha-1", "scram-sha1", "scramsha1": + *sa = SMTPAuthSCRAMSHA1 + case "scram-sha-1-plus", "scram-sha1-plus", "scramsha1plus": + *sa = SMTPAuthSCRAMSHA1PLUS + case "scram-sha-256", "scram-sha256", "scramsha256": + *sa = SMTPAuthSCRAMSHA256 + case "scram-sha-256-plus", "scram-sha256-plus", "scramsha256plus": + *sa = SMTPAuthSCRAMSHA256PLUS + case "xoauth2", "oauth2": + *sa = SMTPAuthXOAUTH2 + default: + return fmt.Errorf("unsupported SMTP auth type: %s", value) + } + return nil +} diff --git a/auth_test.go b/auth_test.go new file mode 100644 index 0000000..2b8b796 --- /dev/null +++ b/auth_test.go @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: 2024 The go-mail Authors +// +// SPDX-License-Identifier: MIT + +package mail + +import "testing" + +func TestSMTPAuthType_UnmarshalString(t *testing.T) { + tests := []struct { + name string + authString string + expected SMTPAuthType + }{ + {"CRAM-MD5: cram-md5", "cram-md5", SMTPAuthCramMD5}, + {"CRAM-MD5: crammd5", "crammd5", SMTPAuthCramMD5}, + {"CRAM-MD5: cram", "cram", SMTPAuthCramMD5}, + {"CUSTOM", "custom", SMTPAuthCustom}, + {"LOGIN", "login", SMTPAuthLogin}, + {"NONE: none", "none", SMTPAuthNoAuth}, + {"NONE: noauth", "noauth", SMTPAuthNoAuth}, + {"NONE: no", "no", SMTPAuthNoAuth}, + {"PLAIN", "plain", SMTPAuthPlain}, + {"SCRAM-SHA-1: scram-sha-1", "scram-sha-1", SMTPAuthSCRAMSHA1}, + {"SCRAM-SHA-1: scram-sha1", "scram-sha1", SMTPAuthSCRAMSHA1}, + {"SCRAM-SHA-1: scramsha1", "scramsha1", SMTPAuthSCRAMSHA1}, + {"SCRAM-SHA-1-PLUS: scram-sha-1-plus", "scram-sha-1-plus", SMTPAuthSCRAMSHA1PLUS}, + {"SCRAM-SHA-1-PLUS: scram-sha1-plus", "scram-sha1-plus", SMTPAuthSCRAMSHA1PLUS}, + {"SCRAM-SHA-1-PLUS: scramsha1plus", "scramsha1plus", SMTPAuthSCRAMSHA1PLUS}, + {"SCRAM-SHA-256: scram-sha-256", "scram-sha-256", SMTPAuthSCRAMSHA256}, + {"SCRAM-SHA-256: scram-sha256", "scram-sha256", SMTPAuthSCRAMSHA256}, + {"SCRAM-SHA-256: scramsha256", "scramsha256", SMTPAuthSCRAMSHA256}, + {"SCRAM-SHA-256-PLUS: scram-sha-256-plus", "scram-sha-256-plus", SMTPAuthSCRAMSHA256PLUS}, + {"SCRAM-SHA-256-PLUS: scram-sha256-plus", "scram-sha256-plus", SMTPAuthSCRAMSHA256PLUS}, + {"SCRAM-SHA-256-PLUS: scramsha256plus", "scramsha256plus", SMTPAuthSCRAMSHA256PLUS}, + {"XOAUTH2: xoauth2", "xoauth2", SMTPAuthXOAUTH2}, + {"XOAUTH2: oauth2", "oauth2", SMTPAuthXOAUTH2}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var authType SMTPAuthType + if err := authType.UnmarshalString(tt.authString); err != nil { + t.Errorf("UnmarshalString() for type %s failed: %s", tt.authString, err) + } + if authType != tt.expected { + t.Errorf("UnmarshalString() for type %s failed: expected %s, got %s", + tt.authString, tt.expected, authType) + } + }) + } + t.Run("should fail", func(t *testing.T) { + var authType SMTPAuthType + if err := authType.UnmarshalString("invalid"); err == nil { + t.Error("UnmarshalString() should have failed") + } + }) +}