feat: /v1/role list, get, create, update and delete. Reassign members on delete. Write-time validation (ValidateGrants, duplicates, typed keys against real content types). Name uniqueness (role_name_taken), role_locked, role_has_members, role_conflict on version mismatch. No-escalation: nobody grants a permission they don't hold, and roles.edit_owner_only guards the Owner role. Activity events for role changes. Typed-key exposure in /auth/me. Cleanup of typed rows when a content type is deleted. | Backend only. Will carry the deferred ListGrants decision.
This commit is contained in:
1 parent
a043f7f41a
commit
094df63a7f
51 files changed
+4822
-115
No files matched your search
@@ -14,6 +14,7 @@ import (
|
||||
"RenewCMS/api/handlers/llms"
|
||||
"RenewCMS/api/handlers/media"
|
||||
"RenewCMS/api/handlers/permission"
|
||||
rolehandler "RenewCMS/api/handlers/role"
|
||||
"RenewCMS/api/handlers/settings"
|
||||
"RenewCMS/api/handlers/site"
|
||||
"RenewCMS/api/handlers/staticimages"
|
||||
@@ -244,6 +245,39 @@ func NewSiteRouter(container *UseCases, trustedProxies []string) http.Handler {
|
||||
return r
|
||||
}
|
||||
|
||||
func NewRoleRouter(container *UseCases, trustedProxies []string) http.Handler {
|
||||
r := chi.NewRouter()
|
||||
|
||||
roleHandler := rolehandler.NewHandler(container.ListRolesUseCase, container.GetRoleUseCase, container.CreateRoleUseCase, container.UpdateRoleUseCase, container.DeleteRoleUseCase, container.ReassignRoleMembersUseCase)
|
||||
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(authtoken.Verifier(container.Token))
|
||||
r.Use(container.apiKeyAuth())
|
||||
r.Use(authtoken.Authenticator)
|
||||
r.Use(middleware.RequireCurrentToken(container.GetUserUseCase))
|
||||
r.Use(middleware.RequireVerifiedUser(container.GetUserUseCase))
|
||||
r.Use(container.require(role.KeyRolesView))
|
||||
r.Get("/", roleHandler.List)
|
||||
r.Get("/{id}", roleHandler.Get)
|
||||
})
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(middleware.RequireSession)
|
||||
r.Use(authtoken.Verifier(container.Token))
|
||||
r.Use(middleware.AuditContext(container.GetUserUseCase, trustedProxies))
|
||||
r.Use(middleware.RequireSignedIn)
|
||||
r.Use(authtoken.Authenticator)
|
||||
r.Use(middleware.RequireCurrentToken(container.GetUserUseCase))
|
||||
r.Use(middleware.RequireVerifiedUser(container.GetUserUseCase))
|
||||
r.Use(container.require(role.KeyRolesManage))
|
||||
r.Post("/", roleHandler.Create)
|
||||
r.Put("/{id}", roleHandler.Update)
|
||||
r.Delete("/{id}", roleHandler.Delete)
|
||||
r.Post("/{id}/reassign", roleHandler.Reassign)
|
||||
r.Post("/{id}/reset", roleHandler.Reset)
|
||||
})
|
||||
return r
|
||||
}
|
||||
|
||||
func NewAuthorRouter(container *UseCases, trustedProxies []string) http.Handler {
|
||||
r := chi.NewRouter()
|
||||
|
||||
@@ -474,6 +508,7 @@ func InitBackendRoutes(container *UseCases, settings config.Settings) *chi.Mux {
|
||||
r.Mount("/user", NewUserRouter(container, settings.AuthRateLimit, settings.TrustedProxies))
|
||||
r.Mount("/settings", NewSettingsRouter(container, settings.TrustedProxies))
|
||||
r.Mount("/site", NewSiteRouter(container, settings.TrustedProxies))
|
||||
r.Mount("/role", NewRoleRouter(container, settings.TrustedProxies))
|
||||
r.Mount("/author", NewAuthorRouter(container, settings.TrustedProxies))
|
||||
r.Mount("/content-type", NewContentTypeRouter(container, settings.TrustedProxies))
|
||||
r.Mount("/builtin-type", NewBuiltinTypeRouter(container, settings.TrustedProxies))
|
||||
|
||||
Reference in new issue
Block a user