83 lines
2.3 KiB
Go
83 lines
2.3 KiB
Go
|
|
package auth
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"errors"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"golang.org/x/crypto/bcrypt"
|
||
|
|
|
||
|
|
"kereru.forms/internal/config"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestLocalPasswordLoginAndAuthenticate(t *testing.T) {
|
||
|
|
cfg := config.Default().Auth
|
||
|
|
cfg.LocalPassword = "secret"
|
||
|
|
cfg.LocalTokenSecret = "test-secret"
|
||
|
|
service, err := New(context.Background(), cfg)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("new auth service: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
token, user, err := service.Login("secret")
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("login: %v", err)
|
||
|
|
}
|
||
|
|
if token == "" {
|
||
|
|
t.Fatal("expected a token")
|
||
|
|
}
|
||
|
|
if !user.CanAdmin || !user.CanView {
|
||
|
|
t.Fatalf("expected admin and view roles, got %+v", user)
|
||
|
|
}
|
||
|
|
|
||
|
|
authenticated, err := service.Authenticate(context.Background(), token)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("authenticate: %v", err)
|
||
|
|
}
|
||
|
|
if authenticated.ID != "local" || !authenticated.CanAdmin || !authenticated.CanView {
|
||
|
|
t.Fatalf("unexpected authenticated user: %+v", authenticated)
|
||
|
|
}
|
||
|
|
|
||
|
|
if _, _, err := service.Login("wrong"); !errors.Is(err, ErrInvalidCredentials) {
|
||
|
|
t.Fatalf("expected invalid credentials, got %v", err)
|
||
|
|
}
|
||
|
|
if _, err := service.Authenticate(context.Background(), token+"x"); !errors.Is(err, ErrInvalidToken) {
|
||
|
|
t.Fatalf("expected invalid token, got %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestLocalPasswordSupportsBcrypt(t *testing.T) {
|
||
|
|
hash, err := bcrypt.GenerateFromPassword([]byte("hashed-secret"), bcrypt.MinCost)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("hash password: %v", err)
|
||
|
|
}
|
||
|
|
cfg := config.Default().Auth
|
||
|
|
cfg.LocalPassword = string(hash)
|
||
|
|
cfg.LocalTokenSecret = "test-secret"
|
||
|
|
service, err := New(context.Background(), cfg)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("new auth service: %v", err)
|
||
|
|
}
|
||
|
|
if _, _, err := service.Login("hashed-secret"); err != nil {
|
||
|
|
t.Fatalf("login with bcrypt password: %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClaimValuesSupportsNestedPathsAndArrays(t *testing.T) {
|
||
|
|
claims := map[string]any{
|
||
|
|
"roles": []any{"admin", "view", "admin"},
|
||
|
|
"realm_access": map[string]any{
|
||
|
|
"roles": []any{"viewer", "auditor"},
|
||
|
|
},
|
||
|
|
}
|
||
|
|
if got := claimValues(claims, "roles"); len(got) != 2 || got[0] != "admin" || got[1] != "view" {
|
||
|
|
t.Fatalf("unexpected flat roles: %#v", got)
|
||
|
|
}
|
||
|
|
if got := claimValues(claims, "realm_access.roles"); len(got) != 2 || got[0] != "viewer" || got[1] != "auditor" {
|
||
|
|
t.Fatalf("unexpected nested roles: %#v", got)
|
||
|
|
}
|
||
|
|
if got := claimValues(claims, "missing.roles"); got != nil {
|
||
|
|
t.Fatalf("expected nil for missing path, got %#v", got)
|
||
|
|
}
|
||
|
|
}
|