fix: (rbac) role update

This commit is contained in:
xushuhui 2022-04-24 18:53:39 +08:00
parent 28f360eaf9
commit e8b57f369a
9 changed files with 181 additions and 61 deletions

View File

@ -225,17 +225,17 @@ func ValidatePermission(claims *UserClaims, permissions []string) (err error) {
err = errors.New("api permission is empty") err = errors.New("api permission is empty")
return return
} }
return nil
// 权限校验 // 权限校验
userPermissionMap := make(map[string]struct{}) userPermissionMap := make(map[string]struct{})
for _, role := range reqUser.Roles { for _, role := range reqUser.Roles {
if _, ok := RolePermission[role]; ok { if _, ok := RolePermission[role]; ok {
for _, v := range RolePermission[role] { for _, v := range RolePermission[role].Platform {
userPermissionMap[v] = struct{}{} userPermissionMap[v] = struct{}{}
} }
} }
} }
//all=>read
var count int var count int
for _, v := range permissions { for _, v := range permissions {
if _, ok := userPermissionMap[v]; ok { if _, ok := userPermissionMap[v]; ok {

View File

@ -3,6 +3,8 @@ package biz
import ( import (
"context" "context"
"errors" "errors"
httprouter "infini.sh/framework/core/api/router"
"net/http"
) )
const ctxUserKey = "user" const ctxUserKey = "user"
@ -22,27 +24,38 @@ func FromUserContext(ctx context.Context) (*User, error) {
return reqUser.User, nil return reqUser.User, nil
} }
//type EsRole struct {
// Cluster []string `json:"cluster,omitempty"`
// Index []string `json:"index,omitempty"`
//}
func NewEsContext(ctx context.Context, role EsRole) {
//get user es role
}
type EsRequest struct { type EsRequest struct {
Method string `json:"method"`
Cluster []string `json:"cluster"` Cluster []string `json:"cluster"`
Index []string `json:"index"`
Index []string `json:"index"`
Doc string `json:"doc"`
Path string `json:"path"`
} }
func ValidateEsPermission(req EsRequest, userRole EsRole) (err error) { func NewEsRequest(r *http.Request, ps httprouter.Params) EsRequest {
//GET elasticsearch/c6dgjtgvi076f32oibj0/index/test/_mappings
clusterId := ps.ByName("id")
index := ps.ByName("index")
doc := ps.ByName("docId")
//如果index存在说明调用的是index api
return EsRequest{
Cluster: []string{clusterId},
Index: []string{index},
Doc: doc,
Path: r.URL.Path,
Method: r.Method,
}
}
func ValidateEsPermission(req EsRequest, userRole Role) (err error) {
userClusterMap := make(map[string]struct{}) userClusterMap := make(map[string]struct{})
userIndexMap := make(map[string]struct{}) userIndexMap := make(map[string]struct{})
for _, v := range userRole.Cluster { for _, v := range userRole.Cluster {
userClusterMap[v.Id] = struct{}{} userClusterMap[v.Id] = struct{}{}
} }
//todo 启动内存
for _, val := range userRole.Index { for _, val := range userRole.Index {
for _, v := range val.Name { for _, v := range val.Name {
userIndexMap[v] = struct{}{} userIndexMap[v] = struct{}{}
@ -55,11 +68,12 @@ func ValidateEsPermission(req EsRequest, userRole EsRole) (err error) {
return return
} }
} }
//for _, v := range req.Index { for _, v := range req.Index {
// if _, ok := userClusterMap[v]; !ok { if _, ok := userIndexMap[v]; !ok {
// err = errors.New("no index permission") err = errors.New("no index permission")
// return return
// } }
//} }
return return
} }

View File

@ -1,12 +1,14 @@
package enum package enum
import "time" import (
"time"
)
var UserRead = []string{"user::read"} var UserRead = []string{"system.user:read"}
var UserAll = []string{"user::read", "user::write"} var UserAll = []string{"system.user:all"}
var RoleRead = []string{"role::read"} var RoleRead = []string{"system.role:read"}
var RoleAll = []string{"role::read", "role::write"} var RoleAll = []string{"system.role:all"}
var RuleRead = []string{"rule::read"} var RuleRead = []string{"rule::read"}
var RuleAll = []string{"rule::read", "rule::write"} var RuleAll = []string{"rule::read", "rule::write"}
@ -16,12 +18,27 @@ var InstanceAll = []string{"instance::read", "instance::write"}
var AdminPrivilege = []string{ var AdminPrivilege = []string{
"system.role:read", "system.role:all", "system.user:read", "system.user:all", "system.role:read", "system.role:all", "system.user:read", "system.user:all",
} }
var Admin []string
type Role struct {
Platform []string `json:"platform,omitempty"`
Cluster []struct {
Id string `json:"id"`
Name string `json:"name"`
} `json:"cluster,omitempty"`
ClusterPrivilege []map[string][]string `json:"cluster_privilege,omitempty"`
Index []struct {
Name []string `json:"name"`
Privilege []string `json:"privilege"`
} `json:"index,omitempty"`
}
var Admin Role
var BuildRoles = make(map[string]map[string]interface{}, 0) var BuildRoles = make(map[string]map[string]interface{}, 0)
func init() { func init() {
Admin = append(Admin, UserAll...) Admin = Role{
Admin = append(Admin, RoleAll...) Platform: AdminPrivilege,
}
UserMenu := Menu{ UserMenu := Menu{
Id: "system_user", Id: "system_user",

View File

@ -1,13 +1,15 @@
package biz package biz
import "infini.sh/console/internal/biz/enum"
var ClusterApis = make(map[string][]string) var ClusterApis = make(map[string][]string)
var IndexApis = make([]string, 0) var IndexApis = make([]string, 0)
var RolePermission = make(map[string][]string) var RolePermission = make(map[string]enum.Role)
var EsRolePermission = make(map[string]EsRole) var EsApiMap = make(map[string]string)
type EsRole struct { type Role struct {
Platform []string `json:"platform"` Platform []string `json:"platform,omitempty"`
Cluster []struct { Cluster []struct {
Id string `json:"id"` Id string `json:"id"`
Name string `json:"name"` Name string `json:"name"`

View File

@ -23,6 +23,7 @@ const (
type IRole interface { type IRole interface {
ListPermission() interface{} ListPermission() interface{}
Create(localUser *User) (id string, err error) Create(localUser *User) (id string, err error)
Update(localUser *User, id string) (err error)
//Delete(localUser *User, id string) (err error) //Delete(localUser *User, id string) (err error)
} }
type ConsoleRole struct { type ConsoleRole struct {
@ -59,7 +60,79 @@ func NewRole(typ string) (r IRole, err error) {
} }
return return
} }
func (role ConsoleRole) Update(localUser *User, id string) (err error) {
model := rbac.Role{}
model.ID = id
_, err = orm.Get(&model)
if err != nil {
err = ErrNotFound
return
}
changeLog, _ := util.DiffTwoObject(model, role)
model.Description = role.Description
model.Platform = role.Platform
model.Updated = time.Now()
err = orm.Save(model)
if err != nil {
return
}
err = orm.Save(GenerateEvent(event.ActivityMetadata{
Category: "platform",
Group: "rbac",
Name: "role",
Type: "update",
Labels: util.MapStr{
"id": id,
"description": model.Description,
"platform": model.Platform,
"updated": model.Updated,
},
User: util.MapStr{
"userid": localUser.UserId,
"username": localUser.Username,
},
}, nil, changeLog))
return
}
func (role ElasticsearchRole) Update(localUser *User, id string) (err error) {
model := rbac.Role{}
model.ID = id
_, err = orm.Get(&model)
if err != nil {
err = ErrNotFound
return
}
changeLog, _ := util.DiffTwoObject(model, role)
model.Description = role.Description
model.Cluster = role.Cluster
model.Index = role.Index
model.ClusterPrivilege = role.ClusterPrivilege
model.Updated = time.Now()
err = orm.Save(model)
if err != nil {
return
}
err = orm.Save(GenerateEvent(event.ActivityMetadata{
Category: "platform",
Group: "rbac",
Name: "role",
Type: "update",
Labels: util.MapStr{
"id": id,
"description": model.Description,
"platform": model.Platform,
"updated": model.Updated,
},
User: util.MapStr{
"userid": localUser.UserId,
"username": localUser.Username,
},
}, nil, changeLog))
return
}
func (role ConsoleRole) Create(localUser *User) (id string, err error) { func (role ConsoleRole) Create(localUser *User) (id string, err error) {
if _, ok := enum.BuildRoles[role.Name]; ok { if _, ok := enum.BuildRoles[role.Name]; ok {
err = fmt.Errorf("role name %s already exists", role.Name) err = fmt.Errorf("role name %s already exists", role.Name)
@ -213,7 +286,7 @@ func DeleteRole(localUser *User, id string) (err error) {
return return
} }
func UpdateRole(localUser *User, id string, req dto.UpdateConsoleRole) (err error) { func UpdateRole(localUser *User, id string, req dto.UpdateRole) (err error) {
role := rbac.Role{} role := rbac.Role{}
role.ID = id role.ID = id
_, err = orm.Get(&role) _, err = orm.Get(&role)
@ -224,6 +297,7 @@ func UpdateRole(localUser *User, id string, req dto.UpdateConsoleRole) (err erro
changeLog, _ := util.DiffTwoObject(role, req) changeLog, _ := util.DiffTwoObject(role, req)
role.Description = req.Description role.Description = req.Description
role.Platform = req.Platform role.Platform = req.Platform
role.Updated = time.Now() role.Updated = time.Now()
err = orm.Save(role) err = orm.Save(role)
if err != nil { if err != nil {

View File

@ -9,16 +9,15 @@ type Menu struct {
Name string `json:"name"` Name string `json:"name"`
Privilege string `json:"privilege"` Privilege string `json:"privilege"`
} }
type UpdateConsoleRole struct { type UpdateRole struct {
Description string `json:"description" ` Description string `json:"description" `
Platform []string `json:"platform"` Platform []string `json:"platform"`
} Cluster []string `json:"cluster" `
type CreateEsRole struct { Index []string `json:"index" `
Name string `json:"name"` ClusterPrivilege []string `json:"cluster_privilege" `
Description string `json:"description" ` IndexPrivilege []string `json:"index_privilege" `
RoleType string `json:"type" `
Permission ElasticsearchPermission `json:"permission"`
} }
type ElasticsearchPermission struct { type ElasticsearchPermission struct {
Cluster []string `json:"cluster" ` Cluster []string `json:"cluster" `
Index []string `json:"index" ` Index []string `json:"index" `

View File

@ -19,16 +19,16 @@ func LoginRequired(h httprouter.Handle) httprouter.Handle {
h(w, r, ps) h(w, r, ps)
} }
} }
func EsPermissionReqired(h httprouter.Handle) httprouter.Handle { func EsPermissionRequired(h httprouter.Handle) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
claims, err := biz.ValidateLogin(r.Header.Get("Authorization")) //req := biz.NewEsRequest(r, ps)
if err != nil { //err := biz.ValidateEsPermission(req)
w = handleError(w, http.StatusUnauthorized, err) //if err != nil {
return // w = handleError(w, http.StatusForbidden, err)
} // return
r = r.WithContext(biz.NewUserContext(r.Context(), claims)) //}
h(w, r, ps) h(w, r, ps)
} }
} }

View File

@ -49,10 +49,20 @@ func loadJsonConfig() {
biz.IndexApis = apis["indices"] biz.IndexApis = apis["indices"]
delete(apis, "indices") delete(apis, "indices")
biz.ClusterApis = apis biz.ClusterApis = apis
bytes, err = util.FileGetContent(path.Join(pwd, "/config/map.json"))
if err != nil {
panic("load json file err " + err.Error())
}
err = json.Unmarshal(bytes, &biz.EsApiMap)
if err != nil {
panic("json config unmarshal err " + err.Error())
}
} }
func loadRolePermission() { func loadRolePermission() {
biz.RolePermission = make(map[string][]string) biz.RolePermission = make(map[string]enum.Role)
biz.RolePermission["admin"] = enum.Admin biz.RolePermission["admin"] = enum.Admin

View File

@ -5,7 +5,6 @@ import (
"infini.sh/console/internal/biz" "infini.sh/console/internal/biz"
"infini.sh/console/internal/biz/enum" "infini.sh/console/internal/biz/enum"
"infini.sh/console/internal/core" "infini.sh/console/internal/core"
"infini.sh/console/internal/dto"
httprouter "infini.sh/framework/core/api/router" httprouter "infini.sh/framework/core/api/router"
"infini.sh/framework/core/elastic" "infini.sh/framework/core/elastic"
"infini.sh/framework/core/util" "infini.sh/framework/core/util"
@ -14,11 +13,7 @@ import (
func (h Rbac) CreateRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { func (h Rbac) CreateRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
roleType := ps.MustGetParameter("type") roleType := ps.MustGetParameter("type")
err := biz.IsAllowRoleType(roleType)
if err != nil {
h.Error400(w, err.Error())
return
}
localUser, err := biz.FromUserContext(r.Context()) localUser, err := biz.FromUserContext(r.Context())
if err != nil { if err != nil {
log.Error(err.Error()) log.Error(err.Error())
@ -125,20 +120,29 @@ func (h Rbac) DeleteRole(w http.ResponseWriter, r *http.Request, ps httprouter.P
func (h Rbac) UpdateRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { func (h Rbac) UpdateRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
id := ps.MustGetParameter("id") id := ps.MustGetParameter("id")
model, err := biz.GetRole(id)
var req dto.UpdateConsoleRole
err := h.DecodeJSON(r, &req)
if err != nil { if err != nil {
h.Error(w, err) h.Error(w, err)
return return
} }
irole, err := biz.NewRole(model.RoleType)
if err != nil {
h.Error(w, err)
return
}
err = h.DecodeJSON(r, &irole)
if err != nil {
h.Error400(w, err.Error())
return
}
localUser, err := biz.FromUserContext(r.Context()) localUser, err := biz.FromUserContext(r.Context())
if err != nil { if err != nil {
log.Error(err.Error()) log.Error(err.Error())
h.Error(w, err) h.Error(w, err)
return return
} }
err = biz.UpdateRole(localUser, id, req) err = irole.Update(localUser, id)
if err != nil { if err != nil {
_ = log.Error(err.Error()) _ = log.Error(err.Error())