From e8b57f369a6d8ef81c959f8b613c07d6cfc5c9c2 Mon Sep 17 00:00:00 2001 From: xushuhui Date: Sun, 24 Apr 2022 18:53:39 +0800 Subject: [PATCH] fix: (rbac) role update --- internal/biz/account.go | 6 +-- internal/biz/context.go | 50 +++++++++++++++--------- internal/biz/enum/const.go | 33 ++++++++++++---- internal/biz/permission.go | 10 +++-- internal/biz/role.go | 76 ++++++++++++++++++++++++++++++++++++- internal/dto/role.go | 17 ++++----- internal/middleware/user.go | 14 +++---- plugin/api/rbac/api.go | 12 +++++- plugin/api/rbac/role.go | 24 +++++++----- 9 files changed, 181 insertions(+), 61 deletions(-) diff --git a/internal/biz/account.go b/internal/biz/account.go index d07b4113..e2a91213 100644 --- a/internal/biz/account.go +++ b/internal/biz/account.go @@ -225,17 +225,17 @@ func ValidatePermission(claims *UserClaims, permissions []string) (err error) { err = errors.New("api permission is empty") return } - + return nil // 权限校验 userPermissionMap := make(map[string]struct{}) for _, role := range reqUser.Roles { if _, ok := RolePermission[role]; ok { - for _, v := range RolePermission[role] { + for _, v := range RolePermission[role].Platform { userPermissionMap[v] = struct{}{} } } } - + //all=>read var count int for _, v := range permissions { if _, ok := userPermissionMap[v]; ok { diff --git a/internal/biz/context.go b/internal/biz/context.go index 1a190cc2..e2b595e6 100644 --- a/internal/biz/context.go +++ b/internal/biz/context.go @@ -3,6 +3,8 @@ package biz import ( "context" "errors" + httprouter "infini.sh/framework/core/api/router" + "net/http" ) const ctxUserKey = "user" @@ -22,27 +24,38 @@ func FromUserContext(ctx context.Context) (*User, error) { 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 { + Method string `json:"method"` 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{}) userIndexMap := make(map[string]struct{}) for _, v := range userRole.Cluster { userClusterMap[v.Id] = struct{}{} } + //todo 启动内存 for _, val := range userRole.Index { for _, v := range val.Name { userIndexMap[v] = struct{}{} @@ -55,11 +68,12 @@ func ValidateEsPermission(req EsRequest, userRole EsRole) (err error) { return } } - //for _, v := range req.Index { - // if _, ok := userClusterMap[v]; !ok { - // err = errors.New("no index permission") - // return - // } - //} + for _, v := range req.Index { + if _, ok := userIndexMap[v]; !ok { + err = errors.New("no index permission") + return + } + } + return } diff --git a/internal/biz/enum/const.go b/internal/biz/enum/const.go index f4b6a2ff..45da1796 100644 --- a/internal/biz/enum/const.go +++ b/internal/biz/enum/const.go @@ -1,12 +1,14 @@ package enum -import "time" +import ( + "time" +) -var UserRead = []string{"user::read"} -var UserAll = []string{"user::read", "user::write"} +var UserRead = []string{"system.user:read"} +var UserAll = []string{"system.user:all"} -var RoleRead = []string{"role::read"} -var RoleAll = []string{"role::read", "role::write"} +var RoleRead = []string{"system.role:read"} +var RoleAll = []string{"system.role:all"} var RuleRead = []string{"rule::read"} var RuleAll = []string{"rule::read", "rule::write"} @@ -16,12 +18,27 @@ var InstanceAll = []string{"instance::read", "instance::write"} var AdminPrivilege = []string{ "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) func init() { - Admin = append(Admin, UserAll...) - Admin = append(Admin, RoleAll...) + Admin = Role{ + Platform: AdminPrivilege, + } UserMenu := Menu{ Id: "system_user", diff --git a/internal/biz/permission.go b/internal/biz/permission.go index 62880ee9..6619be5c 100644 --- a/internal/biz/permission.go +++ b/internal/biz/permission.go @@ -1,13 +1,15 @@ package biz +import "infini.sh/console/internal/biz/enum" + var ClusterApis = make(map[string][]string) var IndexApis = make([]string, 0) -var RolePermission = make(map[string][]string) -var EsRolePermission = make(map[string]EsRole) +var RolePermission = make(map[string]enum.Role) +var EsApiMap = make(map[string]string) -type EsRole struct { - Platform []string `json:"platform"` +type Role struct { + Platform []string `json:"platform,omitempty"` Cluster []struct { Id string `json:"id"` Name string `json:"name"` diff --git a/internal/biz/role.go b/internal/biz/role.go index 069b0780..1d6dbbe6 100644 --- a/internal/biz/role.go +++ b/internal/biz/role.go @@ -23,6 +23,7 @@ const ( type IRole interface { ListPermission() interface{} Create(localUser *User) (id string, err error) + Update(localUser *User, id string) (err error) //Delete(localUser *User, id string) (err error) } type ConsoleRole struct { @@ -59,7 +60,79 @@ func NewRole(typ string) (r IRole, err error) { } 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) { if _, ok := enum.BuildRoles[role.Name]; ok { err = fmt.Errorf("role name %s already exists", role.Name) @@ -213,7 +286,7 @@ func DeleteRole(localUser *User, id string) (err error) { 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.ID = id _, err = orm.Get(&role) @@ -224,6 +297,7 @@ func UpdateRole(localUser *User, id string, req dto.UpdateConsoleRole) (err erro changeLog, _ := util.DiffTwoObject(role, req) role.Description = req.Description role.Platform = req.Platform + role.Updated = time.Now() err = orm.Save(role) if err != nil { diff --git a/internal/dto/role.go b/internal/dto/role.go index 9ab2e858..a1754213 100644 --- a/internal/dto/role.go +++ b/internal/dto/role.go @@ -9,16 +9,15 @@ type Menu struct { Name string `json:"name"` Privilege string `json:"privilege"` } -type UpdateConsoleRole struct { - Description string `json:"description" ` - Platform []string `json:"platform"` -} -type CreateEsRole struct { - Name string `json:"name"` - Description string `json:"description" ` - RoleType string `json:"type" ` - Permission ElasticsearchPermission `json:"permission"` +type UpdateRole struct { + Description string `json:"description" ` + Platform []string `json:"platform"` + Cluster []string `json:"cluster" ` + Index []string `json:"index" ` + ClusterPrivilege []string `json:"cluster_privilege" ` + IndexPrivilege []string `json:"index_privilege" ` } + type ElasticsearchPermission struct { Cluster []string `json:"cluster" ` Index []string `json:"index" ` diff --git a/internal/middleware/user.go b/internal/middleware/user.go index fdfcf589..a904cc97 100644 --- a/internal/middleware/user.go +++ b/internal/middleware/user.go @@ -19,16 +19,16 @@ func LoginRequired(h httprouter.Handle) httprouter.Handle { 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) { - claims, err := biz.ValidateLogin(r.Header.Get("Authorization")) - if err != nil { - w = handleError(w, http.StatusUnauthorized, err) - return - } - r = r.WithContext(biz.NewUserContext(r.Context(), claims)) + //req := biz.NewEsRequest(r, ps) + //err := biz.ValidateEsPermission(req) + //if err != nil { + // w = handleError(w, http.StatusForbidden, err) + // return + //} h(w, r, ps) } } diff --git a/plugin/api/rbac/api.go b/plugin/api/rbac/api.go index 39dc2cd7..c74ffd74 100644 --- a/plugin/api/rbac/api.go +++ b/plugin/api/rbac/api.go @@ -49,10 +49,20 @@ func loadJsonConfig() { biz.IndexApis = apis["indices"] delete(apis, "indices") 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() { - biz.RolePermission = make(map[string][]string) + biz.RolePermission = make(map[string]enum.Role) biz.RolePermission["admin"] = enum.Admin diff --git a/plugin/api/rbac/role.go b/plugin/api/rbac/role.go index 92657cfa..ab5d8253 100644 --- a/plugin/api/rbac/role.go +++ b/plugin/api/rbac/role.go @@ -5,7 +5,6 @@ import ( "infini.sh/console/internal/biz" "infini.sh/console/internal/biz/enum" "infini.sh/console/internal/core" - "infini.sh/console/internal/dto" httprouter "infini.sh/framework/core/api/router" "infini.sh/framework/core/elastic" "infini.sh/framework/core/util" @@ -14,11 +13,7 @@ import ( func (h Rbac) CreateRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { roleType := ps.MustGetParameter("type") - err := biz.IsAllowRoleType(roleType) - if err != nil { - h.Error400(w, err.Error()) - return - } + localUser, err := biz.FromUserContext(r.Context()) if err != nil { 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) { id := ps.MustGetParameter("id") - - var req dto.UpdateConsoleRole - err := h.DecodeJSON(r, &req) + model, err := biz.GetRole(id) if err != nil { h.Error(w, err) 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()) if err != nil { log.Error(err.Error()) h.Error(w, err) return } - err = biz.UpdateRole(localUser, id, req) + err = irole.Update(localUser, id) if err != nil { _ = log.Error(err.Error())