package auth import ( "errors" "testing" ) func TestUserManagementLifecycle(t *testing.T) { store := openTestStore(t, t.TempDir()) created, err := store.CreateUser("reader@example.com", "Temporary-1!", RoleUser) if err != nil { t.Fatalf("CreateUser() error = %v", err) } if created.Role != RoleUser || !created.MustChangePassword || created.Disabled { t.Errorf("CreateUser() = %#v, want enabled user role with forced password change", created) } user, err := store.Authenticate(created.Email, "Temporary-1!") if err != nil { t.Fatalf("Authenticate(created user) error = %v", err) } if !user.MustChangePassword { t.Error("created user's temporary password does not require a change") } token, err := store.CreateSession(user.ID) if err != nil { t.Fatalf("CreateSession() error = %v", err) } if err := store.ResetPassword(created.ID, "Replacement-2!"); err != nil { t.Fatalf("ResetPassword() error = %v", err) } if _, err := store.LookupSession(token); !errors.Is(err, ErrSessionNotFound) { t.Errorf("LookupSession() after reset error = %v, want ErrSessionNotFound", err) } if _, err := store.Authenticate(created.Email, "Temporary-1!"); !errors.Is(err, ErrInvalidCredentials) { t.Errorf("Authenticate(old password) error = %v, want ErrInvalidCredentials", err) } user, err = store.Authenticate(created.Email, "Replacement-2!") if err != nil { t.Fatalf("Authenticate(reset password) error = %v", err) } if !user.MustChangePassword { t.Error("reset password does not require a change") } token, err = store.CreateSession(user.ID) if err != nil { t.Fatalf("CreateSession() after reset error = %v", err) } if err := store.DisableUser(created.ID); err != nil { t.Fatalf("DisableUser() error = %v", err) } if _, err := store.Authenticate(created.Email, "Replacement-2!"); !errors.Is(err, ErrInvalidCredentials) { t.Errorf("Authenticate(disabled user) error = %v, want ErrInvalidCredentials", err) } if _, err := store.LookupSession(token); !errors.Is(err, ErrSessionNotFound) { t.Errorf("LookupSession() for disabled user error = %v, want ErrSessionNotFound", err) } users, err := store.ListUsers() if err != nil { t.Fatalf("ListUsers() error = %v", err) } managed := userByEmail(users, created.Email) if managed == nil || !managed.Disabled { t.Errorf("ListUsers() did not return %q as disabled: %#v", created.Email, users) } if err := store.DeleteUser(created.ID); err != nil { t.Fatalf("DeleteUser() error = %v", err) } users, err = store.ListUsers() if err != nil { t.Fatalf("ListUsers() after deletion error = %v", err) } if userByEmail(users, created.Email) != nil { t.Errorf("ListUsers() still returned deleted user %q", created.Email) } } func userByEmail(users []User, email string) *User { for index := range users { if users[index].Email == email { return &users[index] } } return nil }