Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBHF4R9EAejDJUMdwr6C68
72 lines
2.3 KiB
Go
72 lines
2.3 KiB
Go
package auth
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"testing"
|
|
)
|
|
|
|
func TestReasonFromLDAPError(t *testing.T) {
|
|
// Formulierung wie sie AD in LDAP-Result-Code 49 liefert.
|
|
const tmpl = "LDAP Result Code 49 \"Invalid Credentials\": 80090308: LdapErr: " +
|
|
"DSID-0C0903A9, comment: AcceptSecurityContext error, data %s, v4563"
|
|
|
|
cases := map[string]string{
|
|
"52e": ReasonInvalidCredentials,
|
|
"533": ReasonAccountDisabled,
|
|
"775": ReasonAccountLocked,
|
|
"532": ReasonPasswordExpired,
|
|
"773": ReasonPasswordChangeRequired,
|
|
"525": ReasonInvalidCredentials, // user not found -> generisch, keine Enumeration
|
|
"701": ReasonAccountDisabled, // account expired
|
|
"999": ReasonInvalidCredentials, // unbekannter Code -> generisch
|
|
}
|
|
for code, want := range cases {
|
|
err := errors.New(fmt.Sprintf(tmpl, code))
|
|
if got := ReasonFromLDAPError(err); got != want {
|
|
t.Errorf("data %s: got %q, want %q", code, got, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestReasonFromLDAPErrorIsCaseInsensitive(t *testing.T) {
|
|
err := errors.New("AcceptSecurityContext error, DATA 52E, v4563")
|
|
if got := ReasonFromLDAPError(err); got != ReasonInvalidCredentials {
|
|
t.Errorf("got %q, want %q", got, ReasonInvalidCredentials)
|
|
}
|
|
}
|
|
|
|
func TestReasonFromLDAPErrorWithoutDataCode(t *testing.T) {
|
|
if got := ReasonFromLDAPError(errors.New("connection refused")); got != ReasonBackendUnavailable {
|
|
t.Errorf("got %q, want %q", got, ReasonBackendUnavailable)
|
|
}
|
|
if got := ReasonFromLDAPError(nil); got != "" {
|
|
t.Errorf("nil-Fehler muss leeren Reason liefern, got %q", got)
|
|
}
|
|
}
|
|
|
|
func TestErrorUserVisibleOnlyForExpiredPassword(t *testing.T) {
|
|
if !(&Error{Reason: ReasonPasswordExpired}).UserVisible() {
|
|
t.Error("abgelaufenes Passwort ist die einzige spezifische Meldung")
|
|
}
|
|
for _, r := range []string{
|
|
ReasonInvalidCredentials, ReasonAccountDisabled, ReasonAccountLocked,
|
|
ReasonNotInVPNGroup, ReasonPasswordChangeRequired, ReasonBackendUnavailable,
|
|
} {
|
|
if (&Error{Reason: r}).UserVisible() {
|
|
t.Errorf("Reason %q darf keine spezifische Meldung erzeugen", r)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestErrorUnwraps(t *testing.T) {
|
|
inner := errors.New("boom")
|
|
err := &Error{Reason: ReasonBackendUnavailable, Err: inner}
|
|
if !errors.Is(err, inner) {
|
|
t.Error("Error muss den inneren Fehler durchreichen")
|
|
}
|
|
var authErr *Error
|
|
if !errors.As(error(err), &authErr) {
|
|
t.Error("errors.As muss *Error finden")
|
|
}
|
|
}
|