diff --git a/constant/const.go b/constant/const.go index 5e6e70cd7feb4fd5b20b80cfdb2cbd75f028ea78..7ecd791f6d96e12232192b26ef28ad678a3eaa0f 100644 --- a/constant/const.go +++ b/constant/const.go @@ -20,14 +20,11 @@ package constant const ( SystemGroup = "system" SystemAdminRole = "admin" + DevAdminRole = "devManager" SystemMemberRole = "developer" SystemAdminUser = "admin" AdminDefaultPassword = "123456" - // SysDevManager = "devManager" - // TODO: change to sys devmanger - CompanyAdminRole = "devManager" - StepBuild = "build" StepSubTaskCheckout = "checkout" diff --git a/controllers/role.go b/controllers/role.go index 38ba48a74421eb0973db654e3c2b5cbe6300387d..2035650baffcb4a9d2539d952afb0dbd85c53eff 100644 --- a/controllers/role.go +++ b/controllers/role.go @@ -28,11 +28,7 @@ type RoleController struct { // RoleList .. func (r *RoleController) RoleList() { - groupName := r.GetStringFromPath(":group") - if groupName == "" { - groupName = "system" - } - rsp, err := dao.GroupRoleList(groupName) + rsp, err := dao.GroupRoleList("system") if err != nil { r.HandleInternalServerError(err.Error()) log.Log.Error("Get role list error: %s", err.Error()) @@ -43,10 +39,9 @@ func (r *RoleController) RoleList() { } func (r *RoleController) GetRole() { - groupName := r.GetStringFromPath(":group") roleName := r.GetStringFromPath(":role") - rsp, err := dao.GetGroupRoleByName(groupName, roleName) + rsp, err := dao.GetGroupRoleByName("system", roleName) if err != nil { r.HandleInternalServerError(err.Error()) log.Log.Error("Get role error: %s", err.Error()) @@ -80,11 +75,10 @@ func (r *RoleController) CreateRole() { } func (r *RoleController) UpdateRole() { - groupName := r.GetStringFromPath(":group") roleName := r.GetStringFromPath(":role") var req models.GroupRoleReq r.DecodeJSONReq(&req) - req.Group = groupName + req.Group = "system" req.Role = roleName if err := req.Verify(); err != nil { @@ -104,10 +98,8 @@ func (r *RoleController) UpdateRole() { } func (r *RoleController) DeleteRole() { - groupName := r.GetStringFromPath(":group") roleName := r.GetStringFromPath(":role") - - if err := dao.DeleteGroupRole(groupName, roleName); err != nil { + if err := dao.DeleteGroupRole("system", roleName); err != nil { r.HandleInternalServerError(err.Error()) log.Log.Error("Delete role error: %s", err.Error()) return @@ -166,26 +158,40 @@ func (r *RoleController) RoleUnbundling() { r.ServeJSON() } -func (r *RoleController) RolePolicyList() { - // groupName := r.GetStringFromPath(":group") - // roleName := r.GetStringFromPath(":role") - // TODO: need change role resources list - rsp := []string{} +func (r *RoleController) RoleOperationList() { + roleName := r.GetStringFromPath(":role") + rolesOperations, err := dao.GetRoleOperationsByRoleName(roleName) + if err != nil { + r.HandleInternalServerError(err.Error()) + log.Log.Error("get role operations by role name error: %s", err.Error()) + return + } + resIDs := []int64{} + for _, item := range rolesOperations { + resIDs = append(resIDs, item.OperationID) + } + rsp, err := dao.GetResourceOperationByIDs(resIDs) + if err != nil { + r.HandleInternalServerError(err.Error()) + log.Log.Error("get role operations by ids error: %s", err.Error()) + return + } + r.Data["json"] = NewResult(true, rsp, "") r.ServeJSON() } -func (r *RoleController) AddRolePolicy() { - groupName := r.GetStringFromPath(":group") +func (r *RoleController) AddRoleOperation() { + roleName := r.GetStringFromPath(":role") var req models.GroupRolePolicyReq r.DecodeJSONReq(&req) - req.Group = groupName + req.Group = "system" req.Role = roleName if err := dao.AddRoleOperation(&req); err != nil { r.HandleInternalServerError(err.Error()) - log.Log.Error("Add role policy error: %s", err.Error()) + log.Log.Error("Add role operation error: %s", err.Error()) return } @@ -193,13 +199,12 @@ func (r *RoleController) AddRolePolicy() { r.ServeJSON() } -func (r *RoleController) RemoveRolePolicy() { - groupName := r.GetStringFromPath(":group") +func (r *RoleController) RemoveRoleOperation() { roleName := r.GetStringFromPath(":role") - var req models.GroupRolePolicyReq - r.DecodeJSONReq(&req) - req.Group = groupName + operationID, _ := r.GetInt64FromPath(":operationID") + req := models.GroupRolePolicyReq{} req.Role = roleName + req.Operations = []int64{operationID} if err := dao.DeleteGroupRolePolicy(&req); err != nil { r.HandleInternalServerError(err.Error()) diff --git a/dao/resource.go b/dao/resource.go index 6f8dcc14a5c83e6c4e7e751cc4844fd034113c2d..fa42a2a9e703f43f2cf0e1eea762eedcaf33339a 100644 --- a/dao/resource.go +++ b/dao/resource.go @@ -94,10 +94,6 @@ func BatchCreateResourceType(req models.BatchResourceTypeReq) error { if _, err := GetOrmer().Raw(sql, resourceType, resource.ResourceType.Description).Exec(); err != nil { return err } - sql = `insert ignore into sys_resource_operation(resource_type,resource_operation,description) values(?,'*','所有操作')` - if _, err := GetOrmer().Raw(sql, resourceType).Exec(); err != nil { - return err - } if len(resource.ResourceOperations) > 0 { values := "" @@ -137,9 +133,7 @@ func CreateResourceType(resourceType, description string) (*models.ResourceType, if _, err := GetOrmer().Raw(sql, resourceType, description).Exec(); err != nil { return nil, err } - if err := AddResourceOperation(resourceType, "*", "所有操作"); err != nil { - return nil, err - } + res, err := GetResourceTypeDetail(resourceType, []string{}, []string{}) if err != nil { return nil, err @@ -194,6 +188,36 @@ func GetResourceOperation(resourceType, resourceOperation string) (*models.Resou return &op, nil } +func GetResourceOperationByResourceTypes(resourceTypes []string) ([]*models.ResourceOperation, error) { + var resItems []*models.ResourceOperation + if _, err := GetOrmer().QueryTable("sys_resource_operation"). + Filter("resource_type__in", resourceTypes). + All(&resItems); err != nil { + return nil, err + } + return resItems, nil +} + +func GetResourceOperationByResourceOperations(resourceOperations []string) ([]*models.ResourceOperation, error) { + var resItems []*models.ResourceOperation + if _, err := GetOrmer().QueryTable("sys_resource_operation"). + Filter("resource_operation__in", resourceOperations). + All(&resItems); err != nil { + return nil, err + } + return resItems, nil +} + +func GetResourceOperationByIDs(resourceItemIDs []int64) ([]*models.ResourceOperation, error) { + var resItems []*models.ResourceOperation + if _, err := GetOrmer().QueryTable("sys_resource_operation"). + Filter("id__in", resourceItemIDs). + All(&resItems); err != nil { + return nil, err + } + return resItems, nil +} + func AddResourceOperation(resourceType, resourceOperation, description string) error { sql := `insert into sys_resource_operation(resource_type,resource_operation,description) values(?,?,?)` if _, err := GetOrmer().Raw(sql, resourceType, resourceOperation, description).Exec(); err != nil { @@ -266,11 +290,7 @@ func GetUserConstraintByKey(user string, constraintKey []string) (map[string][]s } res := map[string][]string{} for _, con := range constraints { - if _, ok := res[con.Constraint]; ok { - res[con.Constraint] = append(res[con.Constraint], con.Value) - } else { - res[con.Constraint] = []string{con.Value} - } + res[con.Constraint] = append(res[con.Constraint], con.Value) } return res, nil } diff --git a/dao/resource_router.go b/dao/resource_router.go index 1d7f8a237b1baa5fb542cf8d1a7f2897a421f920..95688fce2f36d6b19ec6db9763001eb7f5f588a6 100644 --- a/dao/resource_router.go +++ b/dao/resource_router.go @@ -21,6 +21,7 @@ import ( "strings" "github.com/go-atomci/atomci/models" + "github.com/isbrick/tools" ) func CreateGatewayRoute(router, method, backend, resourceType, resourceOperation string) error { @@ -32,11 +33,15 @@ func CreateGatewayRoute(router, method, backend, resourceType, resourceOperation } // GetResourceRouterItems .. -func GetResourceRouterItems(resourceOperations []string) ([]models.GatewayRouter, error) { +func GetResourceRouterItems(resourceType string, resourceOperations []string) ([]models.GatewayRouter, error) { routerItems := []models.GatewayRouter{} query := GetOrmer().QueryTable("sys_resource_router") if len(resourceOperations) > 0 { - query = query.Filter("resource_operation__in", resourceOperations) + if tools.IsSliceContainsStr(resourceOperations, "*") { + query = query.Filter("resource_type", resourceType) + } else { + query = query.Filter("resource_operation__in", resourceOperations) + } } if _, err := query.All(&routerItems); err != nil { return nil, err diff --git a/dao/role.go b/dao/role.go index d517f025c755cc08b4a7b6375a434ecb058b37b1..8ecdd60bdd4e8971e935e4e23af8c16adffc2b6e 100644 --- a/dao/role.go +++ b/dao/role.go @@ -50,6 +50,17 @@ func GetGroupRoleByName(group, role string) (*models.GroupRole, error) { return &groupRole, nil } +func GetRoleOperationsByRoleName(role string) ([]*models.GroupRoleOperation, error) { + roleOperations := []*models.GroupRoleOperation{} + if _, err := GetOrmer().QueryTable("sys_group_role_operation"). + Filter("group", "system"). + Filter("role", role). + All(&roleOperations); err != nil { + return nil, err + } + return roleOperations, nil +} + func CreateGroupRole(req *models.GroupRoleReq) (*models.GroupRole, error) { role, _ := GetGroupRoleByName(req.Group, req.Role) if role == nil { @@ -70,12 +81,23 @@ func CreateGroupRole(req *models.GroupRoleReq) (*models.GroupRole, error) { // TODO: generate casbin rules rely on req.Operations log.Log.Debug("req operations length: %v", len(req.Operations)) - resourceRouterItems, err := GetResourceRouterItems(req.Operations) + resOperationItems, err := GetResourceOperationByIDs(req.Operations) if err != nil { - log.Log.Error("when create group role, get resource router items error: %s", err.Error()) + log.Log.Error("when get resource operation by ids occur error: %s", err.Error()) return nil, err } + resTypeOperationsMapping := orderByResourceType(resOperationItems) + resourceRouterItems := []models.GatewayRouter{} + for key, item := range resTypeOperationsMapping { + resRouterItems, err := GetResourceRouterItems(key, item) + if err != nil { + log.Log.Error("when create group role, get resource router items error: %s", err.Error()) + continue + } + resourceRouterItems = append(resourceRouterItems, resRouterItems...) + } + if len(resourceRouterItems) > 0 { casbinRules := generateCasbinRules(resourceRouterItems, req.Role) e, err := mycasbin.NewCasbin() @@ -171,14 +193,14 @@ func GroupRoleUnbundling(req *models.GroupRoleBundlingReq) error { func AddRoleOperation(req *models.GroupRolePolicyReq) error { if len(req.Operations) > 0 { values := "" - for index, policy := range req.Operations { + for index, operationID := range req.Operations { if index == 0 { - values = fmt.Sprintf("('%v','%v','%v')", req.Group, req.Role, policy) + values = fmt.Sprintf("('%v','%v',%v)", req.Group, req.Role, operationID) } else { - values = values + "," + fmt.Sprintf("('%v','%v','%v')", req.Group, req.Role, policy) + values = values + "," + fmt.Sprintf("('%v','%v',%v)", req.Group, req.Role, operationID) } } - sql := `insert ignore into sys_group_role_operation(` + "`group`" + `,role,policy_name) values` + values + sql := `insert ignore into sys_group_role_operation(` + "`group`" + `,role, operation_id) values` + values if _, err := GetOrmer().Raw(sql).Exec(); err != nil { return err } @@ -196,10 +218,20 @@ func DeleteGroupRolePolicy(req *models.GroupRolePolicyReq) error { values = values + "," + fmt.Sprintf("'%v'", police) } } - sql := `delete from sys_group_role_operation where ` + "`group`" + `=? and role=? and policy_name in (` + values + `)` - if _, err := GetOrmer().Raw(sql, req.Group, req.Role).Exec(); err != nil { + sql := `delete from sys_group_role_operation where ` + `role=? and operation_id in (` + values + `)` + if _, err := GetOrmer().Raw(sql, req.Role).Exec(); err != nil { return err } + + // TODO: clean casbin item } return nil } + +func orderByResourceType(res []*models.ResourceOperation) map[string][]string { + resMap := map[string][]string{} + for _, item := range res { + resMap[item.ResourceType] = append(resMap[item.ResourceType], item.ResourceOperation) + } + return resMap +} diff --git a/dao/user.go b/dao/user.go index f2016860a2f3b44ee8d8f20b3b8433171c2122b1..57b02ff7e104b0414717f0bd5a4b3c54af79605e 100644 --- a/dao/user.go +++ b/dao/user.go @@ -99,7 +99,7 @@ func GetUserDetail(userName string) (*models.User, error) { user.GroupAdmin = 1 break } - if role.Role == constant.CompanyAdminRole { + if role.Role == constant.DevAdminRole { user.GroupAdmin = 1 } } diff --git a/deploy/release/sql/v1.2.2_00.sql b/deploy/release/sql/v1.2.2_00.sql new file mode 100644 index 0000000000000000000000000000000000000000..a071300c7537ed6eb492d1c407d2309ebfaa32f6 --- /dev/null +++ b/deploy/release/sql/v1.2.2_00.sql @@ -0,0 +1,3 @@ +ALTER TABLE atomci.sys_group_role_operation DROP KEY `group`; + +ALTER TABLE atomci.sys_group_role_operation ADD CONSTRAINT roleOperation UNIQUE (role, operation_id); \ No newline at end of file diff --git a/go.mod b/go.mod index ea139a9f4238eef4fcb7e909092d2d5b4f006e88..b119c8ba76c781477faad9f43625fc040bea6870 100644 --- a/go.mod +++ b/go.mod @@ -43,6 +43,7 @@ require ( github.com/google/go-cmp v0.5.5 // indirect github.com/google/uuid v1.2.0 // indirect github.com/gorilla/websocket v1.4.2 + github.com/isbrick/tools v0.0.0-20211027093338-a3a0ded37175 github.com/kr/text v0.2.0 // indirect github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 // indirect github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect diff --git a/go.sum b/go.sum index 3561bb226647aba46962189da00e54c448ef326a..b0fea008f2fef5fcc74cf693698a46488c5330c2 100644 --- a/go.sum +++ b/go.sum @@ -416,6 +416,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/isbrick/http-client v0.0.0-20210321135403-0a5df00fdb84 h1:f+X6/PyYYWQx2LQEUwCEdZiLxYHrpc4b87KFBHrZBnE= github.com/isbrick/http-client v0.0.0-20210321135403-0a5df00fdb84/go.mod h1:ILI7SGUToE8ebBaVw9+tdlWlj2naGFmnMU+FrQj+6ro= +github.com/isbrick/tools v0.0.0-20211027093338-a3a0ded37175 h1:HnZgYkC7M0z/0Ll+qXQS2jizZgWjSkC90j6HDmr/SuM= +github.com/isbrick/tools v0.0.0-20211027093338-a3a0ded37175/go.mod h1:3jxvSrtFqeDL15wHztv4lLjQqB1YiPU3jAewh3LwUW0= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= diff --git a/initialize/init_system_user.go b/initialize/init_system_user.go index 0be0ed60b24fce1083b46d119ff46d3d12bdaa62..3446920b155f01470a0cdd6eb8e147b540b973af 100644 --- a/initialize/init_system_user.go +++ b/initialize/init_system_user.go @@ -93,26 +93,83 @@ func initAdminUser() (int64, error) { // 初始化系统角色和管理员用户 func initSystemRole() error { + adminResourceItem, err := dao.GetResourceOperation("*", "*") + if err != nil { + return err + } + memberResourceOperationIDs := []int64{} + devAdminResourceOperationIDs := []int64{} + + devAdminResourceOperations, err := dao.GetResourceOperationByResourceTypes([]string{"pipeline", "project", "publish"}) + if err != nil { + return err + } + for _, item := range devAdminResourceOperations { + devAdminResourceOperationIDs = append(devAdminResourceOperationIDs, item.ID) + } + + sysMemberResourceOperations, err := dao.GetResourceOperationByResourceOperations([]string{ + "ProjectList", + "CreateProject", + "UpdateProject", + "GetProject", + "CreateProjectApp", + "UpdateProjectApp", + "GetProjectApps", + "GetProjectApp", + "GetAppsByPagination", + "GetArrange", + "SetArrange", + "GetAppBranches", + "SyncAppBranches", + "SwitchProjectBranch", + "DeleteProjectApp", + + "PublishList", + "CreatePublishOrder", + "GetPublish", + "ClosePublish", + "DeletePublish", + "GetCanAddedApps", + "AddPublishApp", + "DeletePublishApp", + "GetOpertaionLogByPagination", + "GetBackTo", + "TriggerBackTo", + "GetNextStage", + "TriggerNextStage", + "GetStepInfo", + "RunStep", + "RunStepCallback", + }) + if err != nil { + return err + } + + for _, item := range sysMemberResourceOperations { + memberResourceOperationIDs = append(memberResourceOperationIDs, item.ID) + } + roles := []models.GroupRoleReq{ { Group: constant.SystemGroup, Role: constant.SystemAdminRole, Description: "超级管理员", - Operations: []string{"*"}, + Operations: []int64{adminResourceItem.ID}, }, { Group: constant.SystemGroup, Role: constant.SystemMemberRole, Description: "普通成员", // TODO: change to real resouce operation - Operations: []string{"CreateProject"}, + Operations: memberResourceOperationIDs, }, { Group: constant.SystemGroup, - Role: constant.CompanyAdminRole, + Role: constant.DevAdminRole, Description: "项目管理员", // TODO: change to real resouce operation - Operations: []string{"CreateProject"}, + Operations: devAdminResourceOperationIDs, }, } for _, role := range roles { diff --git a/models/models.go b/models/models.go index 350c238a4eb2f2fb8f27721d730891112981a637..eae429e5876e815727f6ab059d61601ecb10f4f1 100644 --- a/models/models.go +++ b/models/models.go @@ -166,7 +166,7 @@ func initOrm() { new(GroupRoleUser), new(GroupUserConstraint), new(GroupRole), - new(GroupRolePolicy), + new(GroupRoleOperation), new(Audit), new(GatewayRouter), diff --git a/models/role.go b/models/role.go index da605843faa8a8ce14809a49832aa41c54095fcc..5d9a91059fcf0019ae6d3f5596b5a8d57c2bd70d 100644 --- a/models/role.go +++ b/models/role.go @@ -51,10 +51,10 @@ func (t *GroupRole) TableUnique() [][]string { // GroupRoleReq .. type GroupRoleReq struct { - Group string `json:"group"` - Role string `json:"role"` - Description string `json:"description"` - Operations []string `json:"operations"` + Group string `json:"group"` + Role string `json:"role"` + Description string `json:"description"` + Operations []int64 `json:"operations"` } // Verify .. @@ -76,37 +76,38 @@ type RoleRsp struct { Description string `json:"description"` } -type GroupRolePolicy struct { +type GroupRoleOperation struct { Addons - Group string `orm:"column(group)" json:"group"` - Role string `orm:"column(role)" json:"role"` - PolicyName string `orm:"column(policy_name)" json:"policy_name"` + Group string `orm:"column(group)" json:"group"` + Role string `orm:"column(role)" json:"role"` + PolicyName string `orm:"column(policy_name)" json:"policy_name"` + OperationID int64 `orm:"column(operation_id)" json:"operation_id"` } // TableName .. -func (t *GroupRolePolicy) TableName() string { +func (t *GroupRoleOperation) TableName() string { return "sys_group_role_operation" } // TableIndex .. -func (t *GroupRolePolicy) TableIndex() [][]string { +func (t *GroupRoleOperation) TableIndex() [][]string { return [][]string{ {"Group", "Role"}, } } // TableUnique .. -func (t *GroupRolePolicy) TableUnique() [][]string { +func (t *GroupRoleOperation) TableUnique() [][]string { return [][]string{ - {"Group", "Role", "PolicyName"}, + {"Group", "Role", "OperationID"}, } } // GroupRolePolicyReq .. type GroupRolePolicyReq struct { - Group string `json:"group"` - Role string `json:"role"` - Operations []string `json:"operations"` + Group string `json:"group"` + Role string `json:"role"` + Operations []int64 `json:"operations"` } type GroupRoleBundlingUser struct { diff --git a/routers/routers.go b/routers/routers.go index 634fddef56242d08860b8ff33054e8e4d27bf532..680d7f099db369e1ab727cffad192e850e70b96f 100644 --- a/routers/routers.go +++ b/routers/routers.go @@ -73,9 +73,10 @@ func init() { beego.NSRouter("/roles", &controllers.RoleController{}, "get:RoleList;post:CreateRole"), - beego.NSRouter("/groups/:group/roles", &controllers.RoleController{}, "get:RoleList;post:CreateRole"), - beego.NSRouter("/groups/:group/roles/:role", &controllers.RoleController{}, "get:GetRole;put:UpdateRole;delete:DeleteRole"), - beego.NSRouter("/groups/:group/roles/:role/policies", &controllers.RoleController{}, "get:RolePolicyList;post:AddRolePolicy;delete:RemoveRolePolicy"), + beego.NSRouter("/roles", &controllers.RoleController{}, "get:RoleList;post:CreateRole"), + beego.NSRouter("/roles/:role", &controllers.RoleController{}, "get:GetRole;put:UpdateRole;delete:DeleteRole"), + beego.NSRouter("/roles/:role/operations", &controllers.RoleController{}, "get:RoleOperationList;post:AddRoleOperation"), + beego.NSRouter("/roles/:role/operations/:operationID", &controllers.RoleController{}, "delete:RemoveRoleOperation"), beego.NSRouter("/groups/:group/roles/:role/bundling", &controllers.RoleController{}, "get:RoleBundlingList;post:RoleBundling;delete:RoleUnbundling"), // PipelineStage diff --git a/vendor/github.com/isbrick/tools/.gitignore b/vendor/github.com/isbrick/tools/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..722d5e71d93ca0aa0db6fd22452e46be5604a84d --- /dev/null +++ b/vendor/github.com/isbrick/tools/.gitignore @@ -0,0 +1 @@ +.vscode diff --git a/vendor/github.com/isbrick/tools/LICENSE b/vendor/github.com/isbrick/tools/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..534b464b1ac2ded70322085f2ed043a6a144c2be --- /dev/null +++ b/vendor/github.com/isbrick/tools/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 colynn.liu + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/vendor/github.com/isbrick/tools/README.md b/vendor/github.com/isbrick/tools/README.md new file mode 100644 index 0000000000000000000000000000000000000000..add39e32ae4fef737b547b80ba270c1f17daf331 --- /dev/null +++ b/vendor/github.com/isbrick/tools/README.md @@ -0,0 +1,6 @@ +## tools + +![Go](https://github.com/isbrick/tools/workflows/Go/badge.svg) +[![codecov](https://codecov.io/gh/isbrick/tools/branch/master/graph/badge.svg)](https://codecov.io/gh/isbrick/tools) +[![Go Report Card](https://goreportcard.com/badge/github.com/isbrick/tools)](https://goreportcard.com/report/github.com/isbrick/tools) +[![GoDoc](https://godoc.org/github.com/isbrick/tools?status.svg)](https://pkg.go.dev/github.com/isbrick/tools?tab=doc) \ No newline at end of file diff --git a/vendor/github.com/isbrick/tools/absolute-path.go b/vendor/github.com/isbrick/tools/absolute-path.go new file mode 100644 index 0000000000000000000000000000000000000000..8a9c04779a3edaed27d29ff02b4b3d5c44a9f741 --- /dev/null +++ b/vendor/github.com/isbrick/tools/absolute-path.go @@ -0,0 +1,68 @@ +// Copyright 2020 tools authors +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package tools + +import ( + "os" + "os/exec" + "path/filepath" + "sync" +) + +// EnsureAbs prepends the WorkDir to the given path if it is not an absolute path. +func EnsureAbs(path string) string { + if filepath.IsAbs(path) { + return path + } + return filepath.Join(WorkDir(), path) +} + +var ( + workDir string + workDirOnce sync.Once +) + +// WorkDir returns the absolute path of work directory. It reads the value of envrionment +// variable GOGS_WORK_DIR. When not set, it uses the directory where the application's +// binary is located. +func WorkDir() string { + workDirOnce.Do(func() { + workDir = filepath.Dir(AppPath()) + }) + + return workDir +} + +var ( + appPath string + appPathOnce sync.Once +) + +// AppPath returns the absolute path of the application's binary. +func AppPath() string { + appPathOnce.Do(func() { + var err error + appPath, err = exec.LookPath(os.Args[0]) + if err != nil { + panic("look executable path: " + err.Error()) + } + appPath, err = filepath.Abs(appPath) + if err != nil { + panic("get absolute executable path: " + err.Error()) + } + }) + + return appPath +} diff --git a/vendor/github.com/isbrick/tools/convert.go b/vendor/github.com/isbrick/tools/convert.go new file mode 100644 index 0000000000000000000000000000000000000000..03bf3abfa4591a9f9e200244923c6802953d6097 --- /dev/null +++ b/vendor/github.com/isbrick/tools/convert.go @@ -0,0 +1,59 @@ +package tools + +import ( + "strconv" +) + +// Convert string to specify type. +type StrTo string + +func (f StrTo) Exist() bool { + return string(f) != string(rune(0x1E)) +} + +func (f StrTo) Uint8() (uint8, error) { + v, err := strconv.ParseUint(f.String(), 10, 8) + return uint8(v), err +} + +func (f StrTo) Int() (int, error) { + v, err := strconv.ParseInt(f.String(), 10, 0) + return int(v), err +} + +func (f StrTo) Int64() (int64, error) { + v, err := strconv.ParseInt(f.String(), 10, 64) + return int64(v), err +} + +func (f StrTo) Float64() (float64, error) { + v, err := strconv.ParseFloat(f.String(), 64) + return float64(v), err +} + +func (f StrTo) MustUint8() uint8 { + v, _ := f.Uint8() + return v +} + +func (f StrTo) MustInt() int { + v, _ := f.Int() + return v +} + +func (f StrTo) MustInt64() int64 { + v, _ := f.Int64() + return v +} + +func (f StrTo) MustFloat64() float64 { + v, _ := f.Float64() + return v +} + +func (f StrTo) String() string { + if f.Exist() { + return string(f) + } + return "" +} diff --git a/vendor/github.com/isbrick/tools/go.mod b/vendor/github.com/isbrick/tools/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..763df47419169a95246504e4da7efd47533d084f --- /dev/null +++ b/vendor/github.com/isbrick/tools/go.mod @@ -0,0 +1,5 @@ +module github.com/isbrick/tools + +go 1.14 + +require github.com/stretchr/testify v1.6.1 diff --git a/vendor/github.com/isbrick/tools/go.sum b/vendor/github.com/isbrick/tools/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..afe7890c9a1cf745e7e67ad82a70884ee4e206f0 --- /dev/null +++ b/vendor/github.com/isbrick/tools/go.sum @@ -0,0 +1,11 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/github.com/isbrick/tools/slice.go b/vendor/github.com/isbrick/tools/slice.go new file mode 100644 index 0000000000000000000000000000000000000000..e3c9168cd8f6bd3b9d7d0b31f48bb3002ec6ceaf --- /dev/null +++ b/vendor/github.com/isbrick/tools/slice.go @@ -0,0 +1,99 @@ +// Copyright 2020 tools authors +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package tools + +import "strings" + +// IsSliceContainsStr returns true if the string exists in given slice, ignore case. +func IsSliceContainsStr(sl []string, str string) bool { + str = strings.ToLower(str) + for _, s := range sl { + if strings.ToLower(s) == str { + return true + } + } + return false +} + +// IsSliceContainsInt64 returns true if the int64 exists in given slice. +func IsSliceContainsInt64(sl []int64, i int64) bool { + for _, s := range sl { + if s == i { + return true + } + } + return false +} + +// IsSliceContainsInt returns true if the int exists in given slice. +func IsSliceContainsInt(sl []int, i int) bool { + for _, s := range sl { + if s == i { + return true + } + } + return false +} + +// IntSliceDifference int slice difference +func IntSliceDifference(slice1, slice2 []int) []int { + m := make(map[int]int) + nn := make([]int, 0) + inter := IntSliceIntersect(slice1, slice2) + for _, v := range inter { + m[v]++ + } + + for _, value := range slice1 { + times, _ := m[value] + if times == 0 { + nn = append(nn, value) + } + } + return nn +} + +// IntSliceIntersect .. +func IntSliceIntersect(slice1, slice2 []int) []int { + m := make(map[int]int) + nn := make([]int, 0) + for _, v := range slice1 { + m[v]++ + } + + for _, v := range slice2 { + times, _ := m[v] + if times == 1 { + nn = append(nn, v) + } + } + return nn +} + +// IntSliceUnion .. +func IntSliceUnion(slice1, slice2 []int) []int { + m := make(map[int]int) + for _, v := range slice1 { + m[v]++ + } + + for _, v := range slice2 { + times, _ := m[v] + if times == 0 { + slice1 = append(slice1, v) + } + } + return slice1 +} diff --git a/vendor/github.com/isbrick/tools/string.go b/vendor/github.com/isbrick/tools/string.go new file mode 100644 index 0000000000000000000000000000000000000000..2d2aef337f899108d1d84c0c9cc0d834daba0e35 --- /dev/null +++ b/vendor/github.com/isbrick/tools/string.go @@ -0,0 +1,15 @@ +// Copyright 2020 tools authors +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package tools diff --git a/vendor/github.com/isbrick/tools/time.go b/vendor/github.com/isbrick/tools/time.go new file mode 100644 index 0000000000000000000000000000000000000000..a9ece8aec92c041f9a526c8ab7927e5e2a6f5c90 --- /dev/null +++ b/vendor/github.com/isbrick/tools/time.go @@ -0,0 +1,145 @@ +// Copyright 2020 tools authors +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package tools + +import ( + "fmt" + "strconv" + "strings" + "time" +) + +// Date Format unix time int64 to string +// eg format: YYYY-MM-DD HH:mm:SS +func Date(ti int64, format string) string { + t := time.Unix(int64(ti), 0) + return DateT(t, format) +} + +// DateS Format unix time string to string +func DateS(ts string, format string) string { + i, _ := strconv.ParseInt(ts, 10, 64) + return Date(i, format) +} + +// DateT .. +// Format time.Time struct to string +// MM - month - 01 +// M - month - 1, single bit +// DD - day - 02 +// D - day 2 +// YYYY - year - 2006 +// YY - year - 06 +// HH - 24 hours - 03 +// H - 24 hours - 3 +// hh - 12 hours - 03 +// h - 12 hours - 3 +// mm - minute - 04 +// m - minute - 4 +// ss - second - 05 +// s - second = 5 +func DateT(t time.Time, format string) string { + res := strings.Replace(format, "MM", t.Format("01"), -1) + res = strings.Replace(res, "M", t.Format("1"), -1) + res = strings.Replace(res, "DD", t.Format("02"), -1) + res = strings.Replace(res, "D", t.Format("2"), -1) + res = strings.Replace(res, "YYYY", t.Format("2006"), -1) + res = strings.Replace(res, "YY", t.Format("06"), -1) + res = strings.Replace(res, "HH", fmt.Sprintf("%02d", t.Hour()), -1) + res = strings.Replace(res, "H", fmt.Sprintf("%d", t.Hour()), -1) + res = strings.Replace(res, "hh", t.Format("03"), -1) + res = strings.Replace(res, "h", t.Format("3"), -1) + res = strings.Replace(res, "mm", t.Format("04"), -1) + res = strings.Replace(res, "m", t.Format("4"), -1) + res = strings.Replace(res, "ss", t.Format("05"), -1) + res = strings.Replace(res, "s", t.Format("5"), -1) + return res +} + +// ParseStrToDate .. +// timeStr +// format +// locationName, when locationName is "", defaultLocation rely on system env. +func ParseStrToDate(timestr, format, locationName string) (time.Time, error) { + timeFormat := timeFormatParse(format) + loc := gettimeLocation(locationName) + timeValue, err := time.ParseInLocation(timeFormat, timestr, loc) + return timeValue, err +} + +// ParseDateToStr .. +// MM - month - 01 +// M - month - 1, single bit +// DD - day - 02 +// D - day 2 +// YYYY - year - 2006 +// YY - year - 06 +// HH - 24 hours - 03 +// H - 24 hours - 3 +// hh - 12 hours - 03 +// h - 12 hours - 3 +// mm - minute - 04 +// m - minute - 4 +// ss - second - 05 +// s - second = 5 +func ParseDateToStr(timeValue time.Time, format string) string { + formatStr := timeFormatParse(format) + return timeValue.Format(formatStr) +} + +// TimeComparison time +// 0 equal, +// 1 time1 greater than time2 +// 2 time1 less than time2 +func TimeComparison(time1, time2 time.Time) int { + subSeconds := time1.Sub(time2).Seconds() + if subSeconds == 0 { + return 0 + } else if subSeconds > 0 { + return 1 + } else { + return 2 + } +} + +// timeFormatParse .. +func timeFormatParse(formatStr string) string { + res := strings.Replace(formatStr, "MM", "01", -1) + res = strings.Replace(res, "M", "1", -1) + res = strings.Replace(res, "DD", "02", -1) + res = strings.Replace(res, "D", "2", -1) + res = strings.Replace(res, "YYYY", "2006", -1) + res = strings.Replace(res, "YY", "06", -1) + res = strings.Replace(res, "HH", "15", -1) + res = strings.Replace(res, "H", "15", -1) + res = strings.Replace(res, "hh", "03", -1) + res = strings.Replace(res, "h", "3", -1) + res = strings.Replace(res, "mm", "04", -1) + res = strings.Replace(res, "m", "4", -1) + res = strings.Replace(res, "ss", "05", -1) + res = strings.Replace(res, "s", "5", -1) + return res +} + +// gettimeLocation +func gettimeLocation(locationName string) *time.Location { + var loc *time.Location + if locationName == "" { + loc = time.Now().Location() + } else { + loc, _ = time.LoadLocation(locationName) + } + return loc +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 936a199b0bd2f7b2d865944a71aeb646876e6e71..63a4e94efbc933155626aaa904bbc034b94ea70e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -94,6 +94,9 @@ github.com/imdario/mergo github.com/inconshreveable/mousetrap # github.com/isbrick/http-client v0.0.0-20210321135403-0a5df00fdb84 github.com/isbrick/http-client +# github.com/isbrick/tools v0.0.0-20211027093338-a3a0ded37175 +## explicit +github.com/isbrick/tools # github.com/json-iterator/go v1.1.8 github.com/json-iterator/go # github.com/kr/text v0.2.0 diff --git a/web/src/api/backend.js b/web/src/api/backend.js index eb070937bcd1b7a326799d5bc164a910042b6280..f1aa359f6b1d1dae9bea0c3930f9643e54a88310 100644 --- a/web/src/api/backend.js +++ b/web/src/api/backend.js @@ -494,10 +494,6 @@ const backendAPI = { Package.httpMethods('delete', `/atomci/api/v1/groups/${group}/users/${user}`, cb); }, // 删除用户组权限 - 角色 - delGroupRole(group, role, cb) { - Package.httpMethods('delete', `/atomci/api/v1/groups/${group}/roles/${role}`, cb); - }, - // 删除用户组权限 - 角色 delGroupConstraints(group, constraints, cb) { Package.httpMethods( 'delete', @@ -672,12 +668,17 @@ const backendAPI = { }, // 查询角色列表 - getGroupRoleList(group, cb) { - Package.httpMethods('get', `/atomci/api/v1/groups/${group}/roles`, cb); + getGroupRoleList(cb) { + Package.httpMethods('get', `/atomci/api/v1/roles`, cb); }, // 更新组角色 - updateGroupRole(group, role, body, cb) { - Package.httpMethods('put', `/atomci/api/v1/groups/${group}/roles/${role}`, cb, body); + updateGroupRole(role, body, cb) { + Package.httpMethods('put', `/atomci/api/v1/roles/${role}`, cb, body); + }, + + // 删除用户组权限 - 角色 + delGroupRole(group, role, cb) { + Package.httpMethods('delete', `/atomci/api/v1/roles/${role}`, cb); }, // 资源操作 @@ -723,17 +724,25 @@ const backendAPI = { Package.httpMethods('get', `/atomci/api/v1/groups/${group}/users`, cb); }, // 查询角色详情 - getGroupRoleDetail(group, role, cb) { - Package.httpMethods('get', `/atomci/api/v1/groups/${group}/roles/${role}`, cb); + getGroupRoleDetail(role, cb) { + Package.httpMethods('get', `/atomci/api/v1/roles/${role}`, cb); + }, + + // 查询角色操作 + getRoleOperations(role, cb) { + Package.httpMethods('get', `/atomci/api/v1/roles/${role}/operations`, cb); + }, + + // 删除角色操作 + deleteRoleOperation(role, operationID, cb) { + Package.httpMethods('delete', `/atomci/api/v1/roles/${role}/operations/${operationID}`, cb); }, + // 添加角色权限策略 addRolePolicies(group, role, body, cb) { Package.httpMethods('post', `/atomci/api/v1/groups/${group}/roles/${role}/policies`, cb, body); }, - // 删除角色权限策略 - deleteRolePolicies(body, group, role, cb) { - Package.httpMethods('delete', `/atomci/api/v1/groups/${group}/roles/${role}/policies`, cb, body); - }, + // 添加角色绑定用户 addRoleBindUser(group, role, body, cb) { Package.httpMethods('post', `/atomci/api/v1/groups/${group}/roles/${role}/bundling`, cb, body); diff --git a/web/src/components/utils/user/RoleCreate.vue b/web/src/components/utils/user/RoleCreate.vue index 981843e45dcf19fd466a4a4b0ae60458b4c6ab96..ba7e37d82c5e7fd347701c7652e9e7acbf8138d2 100644 --- a/web/src/components/utils/user/RoleCreate.vue +++ b/web/src/components/utils/user/RoleCreate.vue @@ -24,7 +24,7 @@ - + @@ -38,9 +38,9 @@