mirror of
https://github.com/EZ-Api/ez-api.git
synced 2026-01-13 17:47:51 +00:00
Add `POST /admin/masters/{id}/keys` allowing admins to issue child keys
on behalf of a master. Introduce an `issued_by` field in the Key model
to audit whether a key was issued by the master or an admin.
Refactor master service to use typed errors for consistent HTTP status
mapping and ensure validation logic (active status, group check) is
shared.
98 lines
2.2 KiB
Go
98 lines
2.2 KiB
Go
package service
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/ez-api/ez-api/internal/model"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func newTestDB(t *testing.T) *gorm.DB {
|
|
t.Helper()
|
|
db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{})
|
|
if err != nil {
|
|
t.Fatalf("open sqlite: %v", err)
|
|
}
|
|
if err := db.AutoMigrate(&model.Master{}, &model.Key{}); err != nil {
|
|
t.Fatalf("migrate: %v", err)
|
|
}
|
|
return db
|
|
}
|
|
|
|
func TestMasterService_CreateAndValidateMasterKey(t *testing.T) {
|
|
db := newTestDB(t)
|
|
svc := NewMasterService(db)
|
|
|
|
m, raw, err := svc.CreateMaster("m1", "default", 2, 10)
|
|
if err != nil {
|
|
t.Fatalf("CreateMaster: %v", err)
|
|
}
|
|
if raw == "" {
|
|
t.Fatalf("expected raw master key")
|
|
}
|
|
if m.MasterKeyDigest == "" {
|
|
t.Fatalf("expected master key digest to be set")
|
|
}
|
|
|
|
got, err := svc.ValidateMasterKey(raw)
|
|
if err != nil {
|
|
t.Fatalf("ValidateMasterKey: %v", err)
|
|
}
|
|
if got.ID != m.ID {
|
|
t.Fatalf("expected master id %d, got %d", m.ID, got.ID)
|
|
}
|
|
}
|
|
|
|
func TestMasterService_IssueChildKey_RespectsLimit(t *testing.T) {
|
|
db := newTestDB(t)
|
|
svc := NewMasterService(db)
|
|
|
|
m, _, err := svc.CreateMaster("m1", "default", 1, 10)
|
|
if err != nil {
|
|
t.Fatalf("CreateMaster: %v", err)
|
|
}
|
|
|
|
_, raw1, err := svc.IssueChildKey(m.ID, "default", "chat:write")
|
|
if err != nil {
|
|
t.Fatalf("IssueChildKey #1: %v", err)
|
|
}
|
|
if raw1 == "" {
|
|
t.Fatalf("expected raw child key")
|
|
}
|
|
|
|
_, _, err = svc.IssueChildKey(m.ID, "default", "chat:write")
|
|
if err == nil {
|
|
t.Fatalf("expected child key limit error")
|
|
}
|
|
}
|
|
|
|
func TestMasterService_IssueChildKeyAsAdmin_SetsIssuedBy(t *testing.T) {
|
|
db := newTestDB(t)
|
|
svc := NewMasterService(db)
|
|
|
|
m, _, err := svc.CreateMaster("m1", "default", 2, 10)
|
|
if err != nil {
|
|
t.Fatalf("CreateMaster: %v", err)
|
|
}
|
|
|
|
key, raw, err := svc.IssueChildKeyAsAdmin(m.ID, "", "chat:write")
|
|
if err != nil {
|
|
t.Fatalf("IssueChildKeyAsAdmin: %v", err)
|
|
}
|
|
if raw == "" {
|
|
t.Fatalf("expected raw child key")
|
|
}
|
|
if key.IssuedBy != "admin" {
|
|
t.Fatalf("expected IssuedBy=admin, got %q", key.IssuedBy)
|
|
}
|
|
|
|
var stored model.Key
|
|
if err := db.First(&stored, key.ID).Error; err != nil {
|
|
t.Fatalf("load key: %v", err)
|
|
}
|
|
if stored.IssuedBy != "admin" {
|
|
t.Fatalf("expected stored IssuedBy=admin, got %q", stored.IssuedBy)
|
|
}
|
|
}
|