feat: Users API, ownership transfer and removal of the legacy role string

This commit is contained in:
Florian Sylvain committed 2026-10-27 03:08:15 +01:00
1 parent 094df63a7f
commit 80f7037d3a
124 files changed
+4644 -824

No files matched your search

+16 -17
View File
@@ -3,10 +3,10 @@ package test
import (
"RenewCMS/api/pkg/apperr"
"RenewCMS/internal/domain/role"
"RenewCMS/internal/domain/user"
"encoding/json"
"net/http"
"net/http/httptest"
"strconv"
"strings"
"testing"
)
@@ -32,17 +32,17 @@ func (g gateOutcome) blocked() bool {
func newEnforcementEnv(t *testing.T) *apiKeyEnv {
t.Helper()
e := newAPIKeyEnv(t)
e.addUser(enforcementOwnerID, user.RoleOwner, ownerRoleID, true)
e.addUser(enforcementAdminID, user.RoleAdmin, adminRoleID, true)
e.addUser(enforcementWriterID, "", writerRoleID, true)
e.addUser(enforcementUnverified, user.RoleAdmin, adminRoleID, false)
e.addUser(enforcementOrphanID, "", 99, true)
e.addUser(enforcementOwnerID, ownerRoleID, true)
e.addUser(enforcementAdminID, adminRoleID, true)
e.addUser(enforcementWriterID, writerRoleID, true)
e.addUser(enforcementUnverified, adminRoleID, false)
e.addUser(enforcementOrphanID, 99, true)
return e
}
func (e *apiKeyEnv) customRoleUser(id uint32, grants ...role.Grant) role.Role {
custom, _ := e.roles.Create(role.Role{Name: "Custom " + string(rune('a'+id)), Version: 1, Grants: grants})
e.addUser(id, "", custom.ID, true)
e.addUser(id, custom.ID, true)
return custom
}
@@ -370,26 +370,25 @@ func TestRolesPermissionsEnforcementHTTP(t *testing.T) {
assertAPIKeyMessage(t, rec, http.StatusInternalServerError, "Internal server error")
})
t.Run("The legacy role string is no longer read for authorization", func(t *testing.T) {
t.Run("Only role_id decides authorization, and role_id 0 is denied", func(t *testing.T) {
rows := []struct {
id uint32
legacy user.Role
roleID uint32
method string
path string
key string
}{
{14, user.RoleOwner, writerRoleID, http.MethodPost, "/v1/user/invite", "users.invite"},
{15, user.RoleAdmin, writerRoleID, http.MethodPost, "/v1/content-type", "schema.edit"},
{16, "", adminRoleID, http.MethodPost, "/v1/content-type", ""},
{17, user.RoleOwner, 0, http.MethodPost, "/v1/user/invite", ""},
{18, user.RoleAdmin, 0, http.MethodPost, "/v1/content-type", ""},
{19, user.RoleAdmin, 0, http.MethodPatch, "/v1/settings", "system.edit_retention"},
{14, writerRoleID, http.MethodPost, "/v1/user/invite", "users.invite"},
{15, writerRoleID, http.MethodPost, "/v1/content-type", "schema.edit"},
{16, adminRoleID, http.MethodPost, "/v1/content-type", ""},
{17, 0, http.MethodPost, "/v1/user/invite", "users.invite"},
{18, 0, http.MethodPost, "/v1/content-type", "schema.edit"},
{19, 0, http.MethodPatch, "/v1/settings", "system.edit_retention"},
}
for _, row := range rows {
t.Run(string(row.legacy)+" "+row.method+" "+row.path+" -> "+resultOf(row.key), func(t *testing.T) {
t.Run(strconv.Itoa(int(row.roleID))+" "+row.method+" "+row.path+" -> "+resultOf(row.key), func(t *testing.T) {
e := newEnforcementEnv(t)
e.addUser(row.id, row.legacy, row.roleID, true)
e.addUser(row.id, row.roleID, true)
assertGate(t, e.gateAs(t, row.id, row.method, row.path, ""), row.key)
})
}