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") } }