rbac
This commit is contained in:
@@ -0,0 +1,373 @@
|
||||
// Package rbachdl 是后台 RBAC 管理(管理员 / 角色 / 权限)的 HTTP 接入层。
|
||||
package rbachdl
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"portal-mini-go/internal/middleware"
|
||||
"portal-mini-go/internal/pkg/errors"
|
||||
"portal-mini-go/internal/pkg/response"
|
||||
"portal-mini-go/internal/service/admin/rbac"
|
||||
)
|
||||
|
||||
// Handler 聚合管理员 / 角色 / 权限三类管理接口。
|
||||
type Handler struct {
|
||||
adminSvc *rbac.AdminService
|
||||
roleSvc *rbac.RoleService
|
||||
permSvc *rbac.PermissionService
|
||||
}
|
||||
|
||||
func NewHandler(adminSvc *rbac.AdminService, roleSvc *rbac.RoleService, permSvc *rbac.PermissionService) *Handler {
|
||||
return &Handler{adminSvc: adminSvc, roleSvc: roleSvc, permSvc: permSvc}
|
||||
}
|
||||
|
||||
// ---- 管理员 ----
|
||||
|
||||
// CreateAdmin 新建管理员。
|
||||
func (h *Handler) CreateAdmin(c *gin.Context) {
|
||||
var req rbac.CreateAdminReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.Error(errors.ErrBadRequest)
|
||||
return
|
||||
}
|
||||
u, err := h.adminSvc.Create(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, u)
|
||||
}
|
||||
|
||||
// ListAdmins 分页查询管理员。支持 query:keyword、status、page、size。
|
||||
func (h *Handler) ListAdmins(c *gin.Context) {
|
||||
keyword := c.Query("keyword")
|
||||
status, _ := strconv.ParseInt(c.DefaultQuery("status", "-1"), 10, 8)
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
|
||||
list, total, err := h.adminSvc.List(c.Request.Context(), rbac.AdminListReq{
|
||||
Keyword: keyword,
|
||||
Status: int8(status),
|
||||
Page: page,
|
||||
Size: size,
|
||||
})
|
||||
if err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, gin.H{"list": list, "total": total, "page": page, "size": size})
|
||||
}
|
||||
|
||||
// GetAdmin 查询单个管理员。
|
||||
func (h *Handler) GetAdmin(c *gin.Context) {
|
||||
id, ok := parseID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
u, err := h.adminSvc.GetByID(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, u)
|
||||
}
|
||||
|
||||
// UpdateAdmin 编辑管理员昵称 / 状态。
|
||||
func (h *Handler) UpdateAdmin(c *gin.Context) {
|
||||
id, ok := parseID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var req rbac.UpdateAdminReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.Error(errors.ErrBadRequest)
|
||||
return
|
||||
}
|
||||
u, err := h.adminSvc.Update(c.Request.Context(), id, req)
|
||||
if err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, u)
|
||||
}
|
||||
|
||||
// DeleteAdmin 删除管理员。
|
||||
func (h *Handler) DeleteAdmin(c *gin.Context) {
|
||||
id, ok := parseID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if err := h.adminSvc.Delete(c.Request.Context(), id); err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, nil)
|
||||
}
|
||||
|
||||
// AssignAdminRoles 为管理员分配角色。
|
||||
func (h *Handler) AssignAdminRoles(c *gin.Context) {
|
||||
id, ok := parseID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var req struct {
|
||||
RoleIDs []uint64 `json:"role_ids" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.Error(errors.ErrBadRequest)
|
||||
return
|
||||
}
|
||||
if err := h.adminSvc.SetRoles(c.Request.Context(), id, req.RoleIDs); err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, nil)
|
||||
}
|
||||
|
||||
// ResetAdminPassword 重置管理员密码。
|
||||
func (h *Handler) ResetAdminPassword(c *gin.Context) {
|
||||
id, ok := parseID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var req struct {
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.Error(errors.ErrBadRequest)
|
||||
return
|
||||
}
|
||||
if err := h.adminSvc.ResetPassword(c.Request.Context(), id, req.Password); err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, nil)
|
||||
}
|
||||
|
||||
// ---- 角色 ----
|
||||
|
||||
// CreateRole 新建角色。
|
||||
func (h *Handler) CreateRole(c *gin.Context) {
|
||||
var req rbac.CreateRoleReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.Error(errors.ErrBadRequest)
|
||||
return
|
||||
}
|
||||
r, err := h.roleSvc.Create(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, r)
|
||||
}
|
||||
|
||||
// ListRoles 分页查询角色。支持 query:keyword、status、page、size。
|
||||
func (h *Handler) ListRoles(c *gin.Context) {
|
||||
keyword := c.Query("keyword")
|
||||
status, _ := strconv.ParseInt(c.DefaultQuery("status", "-1"), 10, 8)
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
|
||||
list, total, err := h.roleSvc.List(c.Request.Context(), rbac.RoleListReq{
|
||||
Keyword: keyword,
|
||||
Status: int8(status),
|
||||
Page: page,
|
||||
Size: size,
|
||||
})
|
||||
if err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, gin.H{"list": list, "total": total, "page": page, "size": size})
|
||||
}
|
||||
|
||||
// GetRole 查询单个角色。
|
||||
func (h *Handler) GetRole(c *gin.Context) {
|
||||
id, ok := parseID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
r, err := h.roleSvc.GetByID(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, r)
|
||||
}
|
||||
|
||||
// UpdateRole 编辑角色。
|
||||
func (h *Handler) UpdateRole(c *gin.Context) {
|
||||
id, ok := parseID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var req rbac.UpdateRoleReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.Error(errors.ErrBadRequest)
|
||||
return
|
||||
}
|
||||
r, err := h.roleSvc.Update(c.Request.Context(), id, req)
|
||||
if err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, r)
|
||||
}
|
||||
|
||||
// DeleteRole 删除角色。
|
||||
func (h *Handler) DeleteRole(c *gin.Context) {
|
||||
id, ok := parseID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if err := h.roleSvc.Delete(c.Request.Context(), id); err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, nil)
|
||||
}
|
||||
|
||||
// AssignRolePermissions 为角色分配权限。
|
||||
func (h *Handler) AssignRolePermissions(c *gin.Context) {
|
||||
id, ok := parseID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var req struct {
|
||||
PermissionIDs []uint64 `json:"permission_ids" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.Error(errors.ErrBadRequest)
|
||||
return
|
||||
}
|
||||
if err := h.roleSvc.SetPermissions(c.Request.Context(), id, req.PermissionIDs); err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, nil)
|
||||
}
|
||||
|
||||
// ---- 权限 ----
|
||||
|
||||
// ListPermissions 分页查询权限。支持 query:type(api/menu)、keyword、page、size。
|
||||
func (h *Handler) ListPermissions(c *gin.Context) {
|
||||
permType := c.Query("type")
|
||||
keyword := c.Query("keyword")
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
|
||||
list, total, err := h.permSvc.List(c.Request.Context(), rbac.PermListReq{
|
||||
Type: permType,
|
||||
Keyword: keyword,
|
||||
Page: page,
|
||||
Size: size,
|
||||
})
|
||||
if err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, gin.H{"list": list, "total": total, "page": page, "size": size})
|
||||
}
|
||||
|
||||
// CreatePermission 新建权限。
|
||||
func (h *Handler) CreatePermission(c *gin.Context) {
|
||||
var req rbac.CreatePermReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.Error(errors.ErrBadRequest)
|
||||
return
|
||||
}
|
||||
p, err := h.permSvc.Create(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, p)
|
||||
}
|
||||
|
||||
// GetPermission 查询单个权限。
|
||||
func (h *Handler) GetPermission(c *gin.Context) {
|
||||
id, ok := parseID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
p, err := h.permSvc.GetByID(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, p)
|
||||
}
|
||||
|
||||
// UpdatePermission 编辑权限。
|
||||
func (h *Handler) UpdatePermission(c *gin.Context) {
|
||||
id, ok := parseID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var req rbac.UpdatePermReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.Error(errors.ErrBadRequest)
|
||||
return
|
||||
}
|
||||
p, err := h.permSvc.Update(c.Request.Context(), id, req)
|
||||
if err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, p)
|
||||
}
|
||||
|
||||
// DeletePermission 删除权限。
|
||||
func (h *Handler) DeletePermission(c *gin.Context) {
|
||||
id, ok := parseID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if err := h.permSvc.Delete(c.Request.Context(), id); err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
response.OK(c, nil)
|
||||
}
|
||||
|
||||
func parseID(c *gin.Context) (uint64, bool) {
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
c.Error(errors.ErrBadRequest)
|
||||
return 0, false
|
||||
}
|
||||
return id, true
|
||||
}
|
||||
|
||||
// Register 注册后台 RBAC 管理路由,各资源按权限粒度挂载守卫。
|
||||
func Register(g *gin.RouterGroup, h *Handler) {
|
||||
// 管理员
|
||||
ag := g.Group("/rbac/admins", middleware.RequirePerm(middleware.PermAdminManage))
|
||||
{
|
||||
ag.POST("", h.CreateAdmin)
|
||||
ag.GET("", h.ListAdmins)
|
||||
ag.GET("/:id", h.GetAdmin)
|
||||
ag.PUT("/:id", h.UpdateAdmin)
|
||||
ag.DELETE("/:id", h.DeleteAdmin)
|
||||
ag.POST("/:id/roles", h.AssignAdminRoles)
|
||||
ag.POST("/:id/reset-pwd", h.ResetAdminPassword)
|
||||
}
|
||||
// 角色
|
||||
rg := g.Group("/rbac/roles", middleware.RequirePerm(middleware.PermRoleManage))
|
||||
{
|
||||
rg.POST("", h.CreateRole)
|
||||
rg.GET("", h.ListRoles)
|
||||
rg.GET("/:id", h.GetRole)
|
||||
rg.PUT("/:id", h.UpdateRole)
|
||||
rg.DELETE("/:id", h.DeleteRole)
|
||||
rg.POST("/:id/permissions", h.AssignRolePermissions)
|
||||
}
|
||||
// 权限
|
||||
pg := g.Group("/rbac/permissions", middleware.RequirePerm(middleware.PermPermManage))
|
||||
{
|
||||
pg.POST("", h.CreatePermission)
|
||||
pg.GET("", h.ListPermissions)
|
||||
pg.GET("/:id", h.GetPermission)
|
||||
pg.PUT("/:id", h.UpdatePermission)
|
||||
pg.DELETE("/:id", h.DeletePermission)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user