Some checks failed
CI / Build & Test (push) Failing after 33s
- 37 个端点全部添加 godoc Swagger 注解(RBAC 11 / Org 5 / Audit 1 / Settings 7 / Notification 7) - 重新生成 docs/(swagger.json/yaml/docs.go) - M8 质量横切:IP 限流、安全头、Body 限制、结构化日志增强、优雅关闭 - 新增 Dockerfile 多阶段构建 + .dockerignore - 新增 testutil 测试工具包 - 修复 testutil.go 编译错误
351 lines
10 KiB
Go
351 lines
10 KiB
Go
package interfaces
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"mengstack/internal/kernel/response"
|
|
"mengstack/internal/modules/rbac/application"
|
|
"mengstack/internal/modules/rbac/domain"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type Handler struct {
|
|
svc *application.Service
|
|
}
|
|
|
|
func NewHandler(svc *application.Service) *Handler {
|
|
return &Handler{svc: svc}
|
|
}
|
|
|
|
// ListPermissions godoc
|
|
// @Summary 列出权限
|
|
// @Description 获取所有权限列表,可按模块筛选
|
|
// @Tags RBAC
|
|
// @Produce json
|
|
// @Param module query string false "按模块筛选"
|
|
// @Success 200 {object} response.Response{data=[]domain.PermissionDTO}
|
|
// @Failure 500 {object} response.Response
|
|
// @Security Bearer
|
|
// @Security TenantID
|
|
// @Router /api/v1/rbac/permissions [get]
|
|
func (h *Handler) ListPermissions(c *gin.Context) {
|
|
module := c.Query("module")
|
|
|
|
var (
|
|
dtos []domain.PermissionDTO
|
|
err error
|
|
)
|
|
|
|
if module != "" {
|
|
dtos, err = h.svc.ListPermissionsByModule(c.Request.Context(), module)
|
|
} else {
|
|
dtos, err = h.svc.ListPermissions(c.Request.Context())
|
|
}
|
|
|
|
if err != nil {
|
|
response.HandleError(c, err)
|
|
return
|
|
}
|
|
|
|
response.Success(c, dtos)
|
|
}
|
|
|
|
// CreateRole godoc
|
|
// @Summary 创建角色
|
|
// @Description 在当前租户下创建新角色
|
|
// @Tags RBAC
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param request body domain.CreateRoleRequest true "角色信息"
|
|
// @Success 200 {object} response.Response{data=domain.RoleDTO}
|
|
// @Failure 400 {object} response.Response
|
|
// @Failure 409 {object} response.Response
|
|
// @Security Bearer
|
|
// @Security TenantID
|
|
// @Router /api/v1/rbac/roles [post]
|
|
func (h *Handler) CreateRole(c *gin.Context) {
|
|
var req domain.CreateRoleRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.Fail(c, response.NewBadRequest("invalid request body"))
|
|
return
|
|
}
|
|
|
|
dto, err := h.svc.CreateRole(c.Request.Context(), req)
|
|
if err != nil {
|
|
response.HandleError(c, err)
|
|
return
|
|
}
|
|
|
|
response.Success(c, dto)
|
|
}
|
|
|
|
// ListRoles godoc
|
|
// @Summary 列出角色
|
|
// @Description 获取当前租户下的所有角色
|
|
// @Tags RBAC
|
|
// @Produce json
|
|
// @Success 200 {object} response.Response{data=[]domain.RoleDTO}
|
|
// @Failure 500 {object} response.Response
|
|
// @Security Bearer
|
|
// @Security TenantID
|
|
// @Router /api/v1/rbac/roles [get]
|
|
func (h *Handler) ListRoles(c *gin.Context) {
|
|
dtos, err := h.svc.ListRoles(c.Request.Context())
|
|
if err != nil {
|
|
response.HandleError(c, err)
|
|
return
|
|
}
|
|
|
|
response.Success(c, dtos)
|
|
}
|
|
|
|
// GetRole godoc
|
|
// @Summary 获取角色详情
|
|
// @Description 根据 ID 获取角色信息,包含权限列表
|
|
// @Tags RBAC
|
|
// @Produce json
|
|
// @Param id path int true "角色 ID"
|
|
// @Success 200 {object} response.Response{data=domain.RoleDTO}
|
|
// @Failure 400 {object} response.Response
|
|
// @Failure 404 {object} response.Response
|
|
// @Security Bearer
|
|
// @Security TenantID
|
|
// @Router /api/v1/rbac/roles/{id} [get]
|
|
func (h *Handler) GetRole(c *gin.Context) {
|
|
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
|
if err != nil {
|
|
response.Fail(c, response.NewBadRequest("invalid role id"))
|
|
return
|
|
}
|
|
|
|
dto, err := h.svc.GetRole(c.Request.Context(), uint(id))
|
|
if err != nil {
|
|
response.HandleError(c, err)
|
|
return
|
|
}
|
|
|
|
response.Success(c, dto)
|
|
}
|
|
|
|
// UpdateRole godoc
|
|
// @Summary 更新角色
|
|
// @Description 更新角色名称或描述
|
|
// @Tags RBAC
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "角色 ID"
|
|
// @Param request body domain.UpdateRoleRequest true "更新内容"
|
|
// @Success 200 {object} response.Response{data=domain.RoleDTO}
|
|
// @Failure 400 {object} response.Response
|
|
// @Failure 404 {object} response.Response
|
|
// @Security Bearer
|
|
// @Security TenantID
|
|
// @Router /api/v1/rbac/roles/{id} [put]
|
|
func (h *Handler) UpdateRole(c *gin.Context) {
|
|
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
|
if err != nil {
|
|
response.Fail(c, response.NewBadRequest("invalid role id"))
|
|
return
|
|
}
|
|
|
|
var req domain.UpdateRoleRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.Fail(c, response.NewBadRequest("invalid request body"))
|
|
return
|
|
}
|
|
|
|
dto, err := h.svc.UpdateRole(c.Request.Context(), uint(id), req)
|
|
if err != nil {
|
|
response.HandleError(c, err)
|
|
return
|
|
}
|
|
|
|
response.Success(c, dto)
|
|
}
|
|
|
|
// DeleteRole godoc
|
|
// @Summary 删除角色
|
|
// @Description 删除指定角色(系统角色不可删除)
|
|
// @Tags RBAC
|
|
// @Param id path int true "角色 ID"
|
|
// @Success 200 {object} response.Response
|
|
// @Failure 400 {object} response.Response
|
|
// @Failure 403 {object} response.Response
|
|
// @Security Bearer
|
|
// @Security TenantID
|
|
// @Router /api/v1/rbac/roles/{id} [delete]
|
|
func (h *Handler) DeleteRole(c *gin.Context) {
|
|
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
|
if err != nil {
|
|
response.Fail(c, response.NewBadRequest("invalid role id"))
|
|
return
|
|
}
|
|
|
|
if err := h.svc.DeleteRole(c.Request.Context(), uint(id)); err != nil {
|
|
response.HandleError(c, err)
|
|
return
|
|
}
|
|
|
|
response.Success(c, nil)
|
|
}
|
|
|
|
// SetRolePermissions godoc
|
|
// @Summary 设置角色权限
|
|
// @Description 为角色批量设置权限(覆盖原有权限)
|
|
// @Tags RBAC
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "角色 ID"
|
|
// @Param request body domain.SetRolePermissionsRequest true "权限 ID 列表"
|
|
// @Success 200 {object} response.Response
|
|
// @Failure 400 {object} response.Response
|
|
// @Failure 404 {object} response.Response
|
|
// @Security Bearer
|
|
// @Security TenantID
|
|
// @Router /api/v1/rbac/roles/{id}/permissions [put]
|
|
func (h *Handler) SetRolePermissions(c *gin.Context) {
|
|
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
|
if err != nil {
|
|
response.Fail(c, response.NewBadRequest("invalid role id"))
|
|
return
|
|
}
|
|
|
|
var req domain.SetRolePermissionsRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.Fail(c, response.NewBadRequest("invalid request body"))
|
|
return
|
|
}
|
|
|
|
if err := h.svc.SetRolePermissions(c.Request.Context(), uint(id), req); err != nil {
|
|
response.HandleError(c, err)
|
|
return
|
|
}
|
|
|
|
response.Success(c, nil)
|
|
}
|
|
|
|
// GetRolePermissions godoc
|
|
// @Summary 获取角色权限列表
|
|
// @Description 获取指定角色已分配的权限列表
|
|
// @Tags RBAC
|
|
// @Produce json
|
|
// @Param id path int true "角色 ID"
|
|
// @Success 200 {object} response.Response{data=[]domain.PermissionDTO}
|
|
// @Failure 400 {object} response.Response
|
|
// @Failure 404 {object} response.Response
|
|
// @Security Bearer
|
|
// @Security TenantID
|
|
// @Router /api/v1/rbac/roles/{id}/permissions [get]
|
|
func (h *Handler) GetRolePermissions(c *gin.Context) {
|
|
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
|
if err != nil {
|
|
response.Fail(c, response.NewBadRequest("invalid role id"))
|
|
return
|
|
}
|
|
|
|
dto, err := h.svc.GetRole(c.Request.Context(), uint(id))
|
|
if err != nil {
|
|
response.HandleError(c, err)
|
|
return
|
|
}
|
|
|
|
response.Success(c, dto.Permissions)
|
|
}
|
|
|
|
// AssignRole godoc
|
|
// @Summary 分配角色给用户
|
|
// @Description 为指定用户分配一个角色
|
|
// @Tags RBAC
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param userId path int true "用户 ID"
|
|
// @Param request body domain.AssignRoleRequest true "角色 ID"
|
|
// @Success 200 {object} response.Response
|
|
// @Failure 400 {object} response.Response
|
|
// @Failure 409 {object} response.Response
|
|
// @Security Bearer
|
|
// @Security TenantID
|
|
// @Router /api/v1/rbac/users/{userId}/roles [post]
|
|
func (h *Handler) AssignRole(c *gin.Context) {
|
|
userID, err := strconv.ParseUint(c.Param("userId"), 10, 64)
|
|
if err != nil {
|
|
response.Fail(c, response.NewBadRequest("invalid user id"))
|
|
return
|
|
}
|
|
|
|
var req domain.AssignRoleRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.Fail(c, response.NewBadRequest("invalid request body"))
|
|
return
|
|
}
|
|
|
|
if err := h.svc.AssignRoleToUser(c.Request.Context(), uint(userID), req); err != nil {
|
|
response.HandleError(c, err)
|
|
return
|
|
}
|
|
|
|
response.Success(c, nil)
|
|
}
|
|
|
|
// RemoveRole godoc
|
|
// @Summary 移除用户角色
|
|
// @Description 从指定用户移除一个角色
|
|
// @Tags RBAC
|
|
// @Param userId path int true "用户 ID"
|
|
// @Param roleId path int true "角色 ID"
|
|
// @Success 200 {object} response.Response
|
|
// @Failure 400 {object} response.Response
|
|
// @Failure 404 {object} response.Response
|
|
// @Security Bearer
|
|
// @Security TenantID
|
|
// @Router /api/v1/rbac/users/{userId}/roles/{roleId} [delete]
|
|
func (h *Handler) RemoveRole(c *gin.Context) {
|
|
userID, err := strconv.ParseUint(c.Param("userId"), 10, 64)
|
|
if err != nil {
|
|
response.Fail(c, response.NewBadRequest("invalid user id"))
|
|
return
|
|
}
|
|
|
|
roleID, err := strconv.ParseUint(c.Param("roleId"), 10, 64)
|
|
if err != nil {
|
|
response.Fail(c, response.NewBadRequest("invalid role id"))
|
|
return
|
|
}
|
|
|
|
if err := h.svc.RemoveRoleFromUser(c.Request.Context(), uint(userID), uint(roleID)); err != nil {
|
|
response.HandleError(c, err)
|
|
return
|
|
}
|
|
|
|
response.Success(c, nil)
|
|
}
|
|
|
|
// GetUserRoles godoc
|
|
// @Summary 获取用户角色
|
|
// @Description 获取指定用户的所有角色及权限
|
|
// @Tags RBAC
|
|
// @Produce json
|
|
// @Param userId path int true "用户 ID"
|
|
// @Success 200 {object} response.Response{data=[]domain.RoleDTO}
|
|
// @Failure 400 {object} response.Response
|
|
// @Failure 404 {object} response.Response
|
|
// @Security Bearer
|
|
// @Security TenantID
|
|
// @Router /api/v1/rbac/users/{userId}/roles [get]
|
|
func (h *Handler) GetUserRoles(c *gin.Context) {
|
|
userID, err := strconv.ParseUint(c.Param("userId"), 10, 64)
|
|
if err != nil {
|
|
response.Fail(c, response.NewBadRequest("invalid user id"))
|
|
return
|
|
}
|
|
|
|
dtos, err := h.svc.GetUserPermissions(c.Request.Context(), uint(userID))
|
|
if err != nil {
|
|
response.HandleError(c, err)
|
|
return
|
|
}
|
|
|
|
response.Success(c, dtos)
|
|
}
|