feat: add tenant and user management with migrations, handlers, and tests
- Implemented tenant and user management features including: - Tenant creation and management with associated migrations. - User creation and management with associated migrations. - Tenant membership management with associated migrations. - Platform user roles management with associated migrations. - Quota management with associated migrations. - Article and template management with associated migrations. - Added HTTP handlers for templates and workspaces. - Created tests for protected and public routes. - Introduced a script to check tenant scope in SQL queries. - Documented task plan for backend completion and frontend foundation.
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestIssueAndParse(t *testing.T) {
|
||||
mgr := NewManager("test-secret-key", 15*time.Minute, 7*24*time.Hour)
|
||||
|
||||
pair, err := mgr.Issue(42, 10, "tenant_admin")
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, pair.AccessToken)
|
||||
assert.NotEmpty(t, pair.RefreshToken)
|
||||
assert.NotEmpty(t, pair.AccessJTI)
|
||||
assert.NotEmpty(t, pair.RefreshJTI)
|
||||
assert.NotZero(t, pair.ExpiresAt)
|
||||
|
||||
claims, err := mgr.Parse(pair.AccessToken)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(42), claims.UserID)
|
||||
assert.Equal(t, int64(10), claims.TenantID)
|
||||
assert.Equal(t, "tenant_admin", claims.Role)
|
||||
assert.Equal(t, "access", claims.Subject)
|
||||
assert.Equal(t, pair.AccessJTI, claims.ID)
|
||||
}
|
||||
|
||||
func TestParseRefreshToken(t *testing.T) {
|
||||
mgr := NewManager("test-secret-key", 15*time.Minute, 7*24*time.Hour)
|
||||
|
||||
pair, err := mgr.Issue(1, 1, "viewer")
|
||||
require.NoError(t, err)
|
||||
|
||||
claims, err := mgr.Parse(pair.RefreshToken)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "refresh", claims.Subject)
|
||||
assert.Equal(t, pair.RefreshJTI, claims.ID)
|
||||
}
|
||||
|
||||
func TestParseExpired(t *testing.T) {
|
||||
mgr := NewManager("test-secret-key", -1*time.Second, -1*time.Second)
|
||||
|
||||
pair, err := mgr.Issue(1, 1, "viewer")
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = mgr.Parse(pair.AccessToken)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestParseWrongSecret(t *testing.T) {
|
||||
mgr1 := NewManager("secret-one", 15*time.Minute, 7*24*time.Hour)
|
||||
mgr2 := NewManager("secret-two", 15*time.Minute, 7*24*time.Hour)
|
||||
|
||||
pair, err := mgr1.Issue(1, 1, "viewer")
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = mgr2.Parse(pair.AccessToken)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestParseGarbage(t *testing.T) {
|
||||
mgr := NewManager("test-secret-key", 15*time.Minute, 7*24*time.Hour)
|
||||
|
||||
_, err := mgr.Parse("not-a-real-token")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestHashToken(t *testing.T) {
|
||||
h1 := HashToken("some-token")
|
||||
h2 := HashToken("some-token")
|
||||
h3 := HashToken("different-token")
|
||||
|
||||
assert.Equal(t, h1, h2)
|
||||
assert.NotEqual(t, h1, h3)
|
||||
assert.Len(t, h1, 64) // SHA-256 hex
|
||||
}
|
||||
|
||||
func TestAccessAndRefreshTTL(t *testing.T) {
|
||||
mgr := NewManager("s", 15*time.Minute, 24*time.Hour)
|
||||
assert.Equal(t, 15*time.Minute, mgr.AccessTTL())
|
||||
assert.Equal(t, 24*time.Hour, mgr.RefreshTTL())
|
||||
}
|
||||
Reference in New Issue
Block a user