Files
configcenter/internal/auth/auth_test.go

73 lines
2.6 KiB
Go

package auth
import (
"context"
"errors"
"net/http/httptest"
"testing"
"time"
"github.com/longpeng/configcenter/internal/domain"
memory_store "github.com/longpeng/configcenter/internal/store/memory"
)
func TestLoginTokenExpiryAndApplicationRoles(t *testing.T) {
ctx := context.Background()
repository := memory_store.New(false)
manager, err := New(repository, true, "0123456789abcdef0123456789abcdef", time.Hour)
if err != nil {
t.Fatal(err)
}
clock := time.Date(2026, 8, 30, 2, 0, 0, 0, time.UTC)
manager.now = func() time.Time { return clock }
if err := manager.Bootstrap(ctx, "root", "a-strong-password", "Root"); err != nil {
t.Fatal(err)
}
token, principal, err := manager.Login(ctx, "root", "a-strong-password")
if err != nil || !principal.IsAdmin {
t.Fatalf("bootstrap login failed: principal=%#v err=%v", principal, err)
}
request := httptest.NewRequestWithContext(ctx, "GET", "/v1/applications", nil)
request.Header.Set("Authorization", "Bearer "+token)
parsed, err := manager.AuthenticateRequest(request)
if err != nil || parsed.Username != "root" {
t.Fatalf("token validation failed: principal=%#v err=%v", parsed, err)
}
app, err := repository.CreateApplication(ctx, domain.Application{Code: "orders", Name: "Orders"})
if err != nil {
t.Fatal(err)
}
viewer, err := manager.CreateUser(ctx, domain.User{Username: "Reader", DisplayName: "Reader"}, "another-strong-password")
if err != nil {
t.Fatal(err)
}
if viewer.Username != "reader" {
t.Fatalf("username was not normalized: %q", viewer.Username)
}
if err := repository.SetUserAppRole(ctx, domain.UserAppRole{UserID: viewer.ID, AppID: app.ID, Role: RoleViewer}); err != nil {
t.Fatal(err)
}
viewerToken, viewerPrincipal, err := manager.Login(ctx, "READER", "another-strong-password")
if err != nil || viewerToken == "" {
t.Fatal(err)
}
viewerContext := WithPrincipal(ctx, viewerPrincipal)
if err := manager.RequireAppRole(viewerContext, app.ID, RoleViewer); err != nil {
t.Fatalf("viewer should read application: %v", err)
}
if err := manager.RequireAppRole(viewerContext, app.ID, RoleAppOwner); !errors.Is(err, ErrForbidden) {
t.Fatalf("viewer must not edit application: %v", err)
}
clock = clock.Add(2 * time.Hour)
if _, err := manager.AuthenticateRequest(request); !errors.Is(err, ErrUnauthorized) {
t.Fatalf("expired token must be rejected: %v", err)
}
tampered := httptest.NewRequestWithContext(ctx, "GET", "/", nil)
tampered.Header.Set("Authorization", "Bearer "+token+"x")
if _, err := manager.AuthenticateRequest(tampered); !errors.Is(err, ErrUnauthorized) {
t.Fatalf("tampered token must be rejected: %v", err)
}
}