Skip to content

Commit

Permalink
feat: change rabc code struct (#552)
Browse files Browse the repository at this point in the history
* feat: change rabc code struct

Signed-off-by: yxxhero <aiopsclub@163.com>
  • Loading branch information
yxxhero authored Aug 24, 2021
1 parent c34a6e7 commit 2621b5e
Show file tree
Hide file tree
Showing 13 changed files with 349 additions and 151 deletions.
143 changes: 93 additions & 50 deletions manager/handlers/permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,116 +23,159 @@ import (
"github.com/gin-gonic/gin"
)

// @Summary Get PermissionGroups
// @Description Get PermissionGroups
// @Summary Get Permissions
// @Description Get Permissions
// @Tags permission
// @Produce json
// @Success 200 {object} types.PermissionGroups
// @Failure 400
// @Failure 500
// @Router /permission/groups [get]
// @Success 200 {object} RoutesInfo
// @Failure 400 {object} HTTPError
// @Failure 500 {object} HTTPError
// @Router /permissions [get]

func (h *Handlers) GetPermissionGroups(g *gin.Engine) func(ctx *gin.Context) {
func (h *Handlers) GetPermissions(g *gin.Engine) func(ctx *gin.Context) {
return func(ctx *gin.Context) {

permissionGroups := h.Service.GetPermissionGroups(g)
permissionGroups := h.Service.GetPermissions(g)

ctx.JSON(http.StatusOK, permissionGroups)
}
}

// @Summary Get User Roles
// @Description Get User Roles
// @Tags permission
// @Summary Create Role
// @Description Create Role by json config
// @Tags role
// @Accept json
// @Produce json
// @Success 200 {object} []map[string]string
// @Failure 400
// @Failure 500
// @Router /permission/roles/{subject} [get]
// @Success 200
// @Failure 400 {object} HTTPError
// @Failure 500 {object} HTTPError
// @Router /roles [post]

func (h *Handlers) GetRolesForUser(ctx *gin.Context) {
var params types.UserRolesParams
if err := ctx.ShouldBindUri(&params); err != nil {
func (h *Handlers) CreateRole(ctx *gin.Context) {
var json types.CreateRolePermissionRequest
if err := ctx.ShouldBindJSON(&json); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
roles, err := h.Service.GetRolesForUser(params.Subject)
err := h.Service.CreateRole(json)
if err != nil {
ctx.Error(err)
return
}
ctx.JSON(http.StatusOK, gin.H{"roles": roles})

ctx.Status(http.StatusOK)
}

// @Summary Judge User Role
// @Description Judge User Role
// @Tags permission
// @Summary Update Role
// @Description Remove Role Permission by json config
// @Tags role
// @Accept json
// @Produce json
// @Success 200 {object}
// @Failure 400
// @Failure 500
// @Router /permission/{subject}/{object}/{action} [get]
// @Success 200
// @Failure 400 {object} HTTPError
// @Failure 500 {object} HTTPError
// @Router /roles/:role_name/permission [delete]

func (h *Handlers) HasRoleForUser(ctx *gin.Context) {
var params types.UserHasRoleParams
func (h *Handlers) RemoveRolePermission(ctx *gin.Context) {

var params types.RoleParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
if params.Subject == "admin" {
ctx.JSON(http.StatusOK, gin.H{"has": true})
var json types.ObjectPermission
if err := ctx.ShouldBindJSON(&json); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
has, err := h.Service.HasRoleForUser(params.Subject, params.Object, params.Action)
err := h.Service.RemoveRolePermission(params.RoleName, json)
if err != nil {
ctx.Error(err)
return
}
ctx.JSON(http.StatusOK, gin.H{"has": has})
ctx.Status(http.StatusOK)
}

// @Summary Create Permission
// @Description Create Permission by json config
// @Tags permission
// @Summary Update Role
// @Description Add Role Permission by json config
// @Tags role
// @Accept json
// @Produce json
// @Success 200
// @Failure 400
// @Failure 500
// @Router /permission [post]
// @Failure 400 {object} HTTPError
// @Failure 500 {object} HTTPError
// @Router /roles/:role_name/permission [post]

func (h *Handlers) CreatePermission(ctx *gin.Context) {
var json types.PolicyRequest
func (h *Handlers) AddRolePermission(ctx *gin.Context) {

var params types.RoleParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
var json types.ObjectPermission
if err := ctx.ShouldBindJSON(&json); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
err := h.Service.CreatePermission(json)
err := h.Service.AddRolePermission(params.RoleName, json)
if err != nil {
ctx.Error(err)
return
}
ctx.Status(http.StatusOK)
}

// @Summary Get Roles
// @Description Get Roles by name
// @Tags role
// @Accept text
// @Produce json
// @Success 200
// @Failure 400 {object} HTTPError
// @Failure 500 {object} HTTPError
// @Router /roles [get]

func (h *Handlers) GetRoles(ctx *gin.Context) {
roles := h.Service.GetRoles()
ctx.JSON(http.StatusOK, roles)
}

// @Summary Get Role
// @Description Get Role
// @Tags permission
// @Accept text
// @Produce json
// @Success 200
// @Failure 400 {object} HTTPError
// @Failure 500 {object} HTTPError
// @Router /roles/:role_name [get]

func (h *Handlers) GetRole(ctx *gin.Context) {
var params types.RoleParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
ctx.JSON(http.StatusOK, h.Service.GetRole(params.RoleName))
}

// @Summary Destroy Permission
// @Description Destroy Permission by json config
// @Tags permission
// @Accept json
// @Produce json
// @Success 200
// @Failure 400
// @Failure 500
// @Router /permission [delete]
// @Failure 400 {object} HTTPError
// @Failure 500 {object} HTTPError
// @Router /role/:role_name [delete]

func (h *Handlers) DestroyPermission(ctx *gin.Context) {
var json types.PolicyRequest
if err := ctx.ShouldBindJSON(&json); err != nil {
func (h *Handlers) DestroyRole(ctx *gin.Context) {
var params types.RoleParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
err := h.Service.DestroyPermission(json)
err := h.Service.DestroyRole(params.RoleName)
if err != nil {
ctx.Error(err)
return
Expand Down
72 changes: 72 additions & 0 deletions manager/handlers/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,75 @@ func (h *Handlers) SignUp(ctx *gin.Context) {

ctx.JSON(http.StatusOK, user)
}

// @Summary Delete Role For User
// @Description Delete Role For User by uri config
// @Tags users
// @Accept text
// @Produce json
// @Success 200
// @Failure 400 {object} HTTPError
// @Failure 500 {object} HTTPError
// @Router /users/:id/roles/:role_name [delete]

func (h *Handlers) DeleteRoleForUser(ctx *gin.Context) {
var params types.RoleRequest
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
err := h.Service.DeleteRoleForUser(params.ID, params.RoleName)
if err != nil {
ctx.Error(err)
return
}
ctx.Status(http.StatusOK)
}

// @Summary Add Role For User
// @Description Add Role For User by uri config
// @Tags users
// @Accept text
// @Produce json
// @Success 200
// @Failure 400 {object} HTTPError
// @Failure 500 {object} HTTPError
// @Router /users/:id/roles/:role_name [post]

func (h *Handlers) AddRoleToUser(ctx *gin.Context) {
var params types.RoleRequest
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
err := h.Service.AddRoleForUser(params.ID, params.RoleName)
if err != nil {
ctx.Error(err)
return
}
ctx.Status(http.StatusOK)
}

// @Summary Get User Roles
// @Description Get User Roles
// @Tags User
// @Produce json
// @Success 200 {object} RoutesInfo
// @Failure 400 {object} HTTPError
// @Failure 500 {object} HTTPError
// @Router /users/:id/roles [get]

func (h *Handlers) GetRolesForUser(ctx *gin.Context) {
var params types.UserParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
roles, err := h.Service.GetRolesForUser(params.ID, ctx.GetString("userName"))
if err != nil {
ctx.Error(err)
return
}
ctx.JSON(http.StatusOK, roles)

}
6 changes: 6 additions & 0 deletions manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ func New(cfg *config.Config) (*Server, error) {
if err != nil {
return nil, err
}

// Initialize roles and check roles
err = rbac.InitRole(enforcer, router)
if err != nil {
return nil, err
}
restServer := &http.Server{
Addr: cfg.Server.REST.Addr,
Handler: router,
Expand Down
16 changes: 14 additions & 2 deletions manager/middlewares/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (

type user struct {
userName string
ID uint
}

func Jwt(service service.REST) (*jwt.GinJWTMiddleware, error) {
Expand All @@ -42,18 +43,28 @@ func Jwt(service service.REST) (*jwt.GinJWTMiddleware, error) {

IdentityHandler: func(c *gin.Context) interface{} {
claims := jwt.ExtractClaims(c)
userNmae, ok := claims[identityKey]
userName, ok := claims[identityKey]
if !ok {
c.JSON(http.StatusUnauthorized, gin.H{
"message": "Unavailable token: require username info",
})
c.Abort()
return nil
}
userID, ok := claims["ID"]
if !ok {
c.JSON(http.StatusUnauthorized, gin.H{
"message": "Unavailable token: require id info",
})
c.Abort()
return nil
}
u := &user{
userName: userNmae.(string),
userName: userName.(string),
ID: uint(userID.(float64)),
}
c.Set("userName", u.userName)
c.Set("userID", u.ID)
return u
},

Expand All @@ -75,6 +86,7 @@ func Jwt(service service.REST) (*jwt.GinJWTMiddleware, error) {
if u, ok := data.(*model.User); ok {
return jwt.MapClaims{
identityKey: u.Name,
"ID": u.ID,
}
}
return jwt.MapClaims{}
Expand Down
17 changes: 13 additions & 4 deletions manager/middlewares/rbac.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package middlewares
import (
"net/http"

logger "d7y.io/dragonfly/v2/internal/dflog"
"d7y.io/dragonfly/v2/manager/permission/rbac"
"github.com/casbin/casbin/v2"
"github.com/gin-gonic/gin"
Expand All @@ -29,7 +30,7 @@ func RBAC(e *casbin.Enforcer) gin.HandlerFunc {
userName := c.GetString("userName")
// request path
p := c.Request.URL.Path
permissionGroupName, err := rbac.GetAPIGroupName(p)
permissionName, err := rbac.GetAPIGroupName(p)
if err != nil {
c.Next()
return
Expand All @@ -50,10 +51,18 @@ func RBAC(e *casbin.Enforcer) gin.HandlerFunc {
c.Next()
return
}
res, err := e.Enforce(userName, permissionGroupName, action)
if err != nil || !res {
res, err := e.Enforce(userName, permissionName, action)
if err != nil {
logger.Errorf("RBAC validate error: %s", err)
c.JSON(http.StatusUnauthorized, gin.H{
"message": "permission validate error",
"message": "permission validate error, please see log!",
})
c.Abort()
return
}
if !res {
c.JSON(http.StatusUnauthorized, gin.H{
"message": "permission deny",
})
c.Abort()
return
Expand Down
Loading

0 comments on commit 2621b5e

Please sign in to comment.