Feat: add the creating and deleting permission APIs (#4026)

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
This commit is contained in:
barnettZQG
2022-05-27 17:41:29 +08:00
committed by GitHub
parent 39d5ce48dc
commit 6eb7af9aea
10 changed files with 630 additions and 129 deletions
+319 -77
View File
@@ -3910,7 +3910,7 @@
"parameters": [
{
"type": "string",
"description": "identifier of the application ",
"description": "identifier of the environment",
"name": "envName",
"in": "path",
"required": true
@@ -3950,7 +3950,7 @@
"parameters": [
{
"type": "string",
"description": "identifier of the application ",
"description": "identifier of the environment",
"name": "envName",
"in": "path",
"required": true
@@ -4013,7 +4013,7 @@
"tags": [
"rbac"
],
"summary": "list all project level perm policies",
"summary": "list all platform level perm policies",
"operationId": "listPlatformPermissions",
"responses": {
"200": {
@@ -4026,6 +4026,73 @@
}
}
}
},
"post": {
"consumes": [
"application/xml",
"application/json"
],
"produces": [
"application/json",
"application/xml"
],
"tags": [
"rbac"
],
"summary": "create the platform perm policy",
"operationId": "createPlatformPermission",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/v1.CreatePermissionRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/v1.PermissionBase"
}
}
}
}
},
"/api/v1/permissions/{permissionName}": {
"delete": {
"consumes": [
"application/xml",
"application/json"
],
"produces": [
"application/json",
"application/xml"
],
"tags": [
"rbac"
],
"summary": "delete a platform perm policy",
"operationId": "deletePlatformPermission",
"parameters": [
{
"type": "string",
"description": "identifier of the permission",
"name": "permissionName",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/v1.EmptyResponse"
}
}
}
}
},
"/api/v1/projects": {
@@ -4276,6 +4343,85 @@
}
}
}
},
"post": {
"consumes": [
"application/xml",
"application/json"
],
"produces": [
"application/json",
"application/xml"
],
"tags": [
"project"
],
"summary": "create a project level perm policy",
"operationId": "createProjectPermission",
"parameters": [
{
"type": "string",
"description": "identifier of the project",
"name": "projectName",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/v1.PermissionBase"
}
}
}
}
}
},
"/api/v1/projects/{projectName}/permissions/{permissionName}": {
"delete": {
"consumes": [
"application/xml",
"application/json"
],
"produces": [
"application/json",
"application/xml"
],
"tags": [
"project"
],
"summary": "delete a project level perm policy",
"operationId": "deleteProjectPermission",
"parameters": [
{
"type": "string",
"description": "identifier of the project",
"name": "projectName",
"in": "path",
"required": true
},
{
"type": "string",
"description": "identifier of the permission",
"name": "permissionName",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/v1.PermissionBase"
}
}
}
}
}
},
"/api/v1/projects/{projectName}/roles": {
@@ -4990,6 +5136,13 @@
"summary": "update platform level role",
"operationId": "updatePlatformRole",
"parameters": [
{
"type": "string",
"description": "identifier of the role",
"name": "roleName",
"in": "path",
"required": true
},
{
"name": "body",
"in": "body",
@@ -5022,6 +5175,15 @@
],
"summary": "update platform level role",
"operationId": "deletePlatformRole",
"parameters": [
{
"type": "string",
"description": "identifier of the role",
"name": "roleName",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
@@ -6456,20 +6618,34 @@
}
}
},
"common.SubStepsStatus": {
"common.StepStatus": {
"required": [
"id"
],
"properties": {
"mode": {
"firstExecuteTime": {
"type": "string"
},
"stepIndex": {
"type": "integer",
"format": "int32"
"id": {
"type": "string"
},
"steps": {
"type": "array",
"items": {
"$ref": "#/definitions/common.WorkflowSubStepStatus"
}
"lastExecuteTime": {
"type": "string"
},
"message": {
"type": "string"
},
"name": {
"type": "string"
},
"phase": {
"type": "string"
},
"reason": {
"type": "string"
},
"type": {
"type": "string"
}
}
},
@@ -6571,7 +6747,45 @@
"type": "string"
},
"subSteps": {
"$ref": "#/definitions/common.SubStepsStatus"
"type": "array",
"items": {
"$ref": "#/definitions/common.WorkflowSubStepStatus"
}
},
"type": {
"type": "string"
}
}
},
"common.WorkflowSubStep": {
"required": [
"name",
"type"
],
"properties": {
"dependsOn": {
"type": "array",
"items": {
"type": "string"
}
},
"inputs": {
"type": "array",
"items": {
"$ref": "#/definitions/common.inputItem"
}
},
"name": {
"type": "string"
},
"outputs": {
"type": "array",
"items": {
"$ref": "#/definitions/common.outputItem"
}
},
"properties": {
"type": "string"
},
"type": {
"type": "string"
@@ -6583,9 +6797,15 @@
"id"
],
"properties": {
"firstExecuteTime": {
"type": "string"
},
"id": {
"type": "string"
},
"lastExecuteTime": {
"type": "string"
},
"message": {
"type": "string"
},
@@ -6897,8 +7117,8 @@
},
"model.Cluster": {
"required": [
"createTime",
"updateTime",
"createTime",
"name",
"alias",
"description",
@@ -7449,8 +7669,8 @@
},
"v1.AddonStatusResponse": {
"required": [
"name",
"phase",
"name",
"args"
],
"properties": {
@@ -7606,12 +7826,12 @@
},
"v1.ApplicationDeployResponse": {
"required": [
"status",
"note",
"envName",
"triggerType",
"createTime",
"version",
"status"
"envName"
],
"properties": {
"codeInfo": {
@@ -8580,6 +8800,38 @@
}
}
},
"v1.CreatePermissionRequest": {
"required": [
"name",
"alias",
"resources",
"actions",
"effect"
],
"properties": {
"actions": {
"type": "array",
"items": {
"type": "string"
}
},
"alias": {
"type": "string"
},
"effect": {
"type": "string"
},
"name": {
"type": "string"
},
"resources": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"v1.CreatePolicyRequest": {
"required": [
"name",
@@ -8776,11 +9028,11 @@
},
"v1.DetailAddonResponse": {
"required": [
"name",
"version",
"description",
"icon",
"invisible",
"name",
"description",
"version",
"icon",
"schema",
"uiSchema",
"definitions",
@@ -8860,13 +9112,13 @@
},
"v1.DetailApplicationResponse": {
"required": [
"name",
"project",
"description",
"createTime",
"icon",
"alias",
"createTime",
"updateTime",
"name",
"policies",
"envBindings",
"resourceInfo"
@@ -8923,20 +9175,20 @@
},
"v1.DetailClusterResponse": {
"required": [
"kubeConfig",
"name",
"description",
"apiServerURL",
"createTime",
"icon",
"status",
"reason",
"icon",
"provider",
"kubeConfigSecret",
"labels",
"dashboardURL",
"createTime",
"updateTime",
"apiServerURL",
"alias",
"dashboardURL",
"updateTime",
"labels",
"kubeConfig",
"kubeConfigSecret",
"resourceInfo"
],
"properties": {
@@ -8994,14 +9246,14 @@
},
"v1.DetailComponentResponse": {
"required": [
"creator",
"appPrimaryKey",
"alias",
"updateTime",
"name",
"type",
"main",
"createTime",
"appPrimaryKey",
"creator",
"updateTime",
"name",
"definition"
],
"properties": {
@@ -9089,11 +9341,11 @@
},
"v1.DetailDefinitionResponse": {
"required": [
"name",
"status",
"labels",
"alias",
"description",
"status",
"labels",
"name",
"icon",
"schema",
"uiSchema"
@@ -9148,14 +9400,14 @@
},
"v1.DetailPolicyResponse": {
"required": [
"creator",
"properties",
"createTime",
"updateTime",
"envName",
"name",
"type",
"description"
"description",
"creator",
"properties"
],
"properties": {
"createTime": {
@@ -9188,16 +9440,16 @@
},
"v1.DetailRevisionResponse": {
"required": [
"updateTime",
"note",
"triggerType",
"reason",
"envName",
"createTime",
"deployUser",
"updateTime",
"reason",
"appPrimaryKey",
"version",
"status",
"envName",
"deployUser",
"note",
"triggerType",
"workflowName"
],
"properties": {
@@ -9252,10 +9504,10 @@
},
"v1.DetailTargetResponse": {
"required": [
"name",
"createTime",
"updateTime",
"project",
"updateTime"
"name"
],
"properties": {
"alias": {
@@ -9295,11 +9547,11 @@
},
"v1.DetailUserResponse": {
"required": [
"disabled",
"createTime",
"lastLoginTime",
"name",
"email",
"disabled",
"projects",
"roles"
],
@@ -9340,12 +9592,12 @@
},
"v1.DetailWorkflowRecordResponse": {
"required": [
"namespace",
"workflowName",
"workflowAlias",
"applicationRevision",
"status",
"name",
"namespace",
"workflowName",
"workflowAlias",
"deployTime",
"deployUser",
"note",
@@ -9397,14 +9649,14 @@
},
"v1.DetailWorkflowResponse": {
"required": [
"createTime",
"alias",
"description",
"enable",
"updateTime",
"createTime",
"name",
"default",
"envName"
"envName",
"updateTime",
"description"
],
"properties": {
"alias": {
@@ -9599,8 +9851,8 @@
},
"v1.EnvBindingTarget": {
"required": [
"name",
"alias"
"alias",
"name"
],
"properties": {
"alias": {
@@ -9983,11 +10235,11 @@
},
"v1.LoginUserInfoResponse": {
"required": [
"createTime",
"lastLoginTime",
"name",
"email",
"disabled",
"createTime",
"projects",
"platformPermissions",
"projectPermissions"
@@ -10992,6 +11244,12 @@
"properties": {
"type": "string"
},
"subSteps": {
"type": "array",
"items": {
"$ref": "#/definitions/common.WorkflowSubStep"
}
},
"type": {
"type": "string"
}
@@ -11006,22 +11264,6 @@
"$ref": "#/definitions/common.Schematic"
}
}
},
"v1beta2.BaseConfigurationSpec": {
"properties": {
"customRegion": {
"type": "string"
},
"deleteResource": {
"type": "boolean"
},
"providerRef": {
"$ref": "#/definitions/types.Reference"
},
"writeConnectionSecretToRef": {
"$ref": "#/definitions/types.SecretReference"
}
}
}
}
}
+54
View File
@@ -0,0 +1,54 @@
/*
Copyright 2022 The KubeVela 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 repository
import (
"context"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
)
// ListRoles list roles from store
func ListRoles(ctx context.Context, store datastore.DataStore, projectName string, page, pageSize int) ([]*model.Role, int64, error) {
var role = model.Role{
Project: projectName,
}
var filter datastore.FilterOptions
if projectName == "" {
filter.IsNotExist = append(filter.IsNotExist, datastore.IsNotExistQueryOption{
Key: "project",
})
}
entities, err := store.List(ctx, &role, &datastore.ListOptions{FilterOptions: filter, Page: page, PageSize: pageSize, SortBy: []datastore.SortOption{{Key: "createTime", Order: datastore.SortOrderDescending}}})
if err != nil {
return nil, 0, err
}
var roles []*model.Role
for i := range entities {
roles = append(roles, entities[i].(*model.Role))
}
count := int64(len(roles))
if page > 0 && pageSize > 0 {
var err error
count, err = store.Count(ctx, &role, &filter)
if err != nil {
return nil, 0, err
}
}
return roles, count, nil
}
+74 -48
View File
@@ -27,7 +27,9 @@ import (
"github.com/emicklei/go-restful/v3"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/repository"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
assembler "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/assembler/v1"
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
apiserverutils "github.com/oam-dev/kubevela/pkg/apiserver/utils"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
@@ -52,7 +54,7 @@ var defaultProjectPermissionTemplate = []*model.PermissionTemplate{
{
Name: "app-management",
Alias: "App Management",
Resources: []string{"project:{projectName}/application:*/*", "definition:list", "definition:detail"},
Resources: []string{"project:{projectName}/application:*/*"},
Actions: []string{"*"},
Effect: "Allow",
Scope: "project",
@@ -135,7 +137,7 @@ var defaultPlatformPermission = []*model.PermissionTemplate{
{
Name: "integration-management",
Alias: "Integration Management",
Resources: []string{"config:*", "configType:*"},
Resources: []string{"configType:*/*"},
Actions: []string{"*"},
Effect: "Allow",
Scope: "platform",
@@ -222,8 +224,10 @@ var ResourceMaps = map[string]resourceMetadata{
"user": {
pathName: "userName",
},
"role": {},
"permission": {},
"role": {},
"permission": {
pathName: "permissionName",
},
"systemSetting": {},
"definition": {
pathName: "definitionName",
@@ -342,6 +346,7 @@ type RBACService interface {
ListRole(ctx context.Context, projectName string, page, pageSize int) (*apisv1.ListRolesResponse, error)
ListPermissionTemplate(ctx context.Context, projectName string) ([]apisv1.PermissionTemplateBase, error)
ListPermissions(ctx context.Context, projectName string) ([]apisv1.PermissionBase, error)
CreatePermission(ctx context.Context, projectName string, req apisv1.CreatePermissionRequest) (*apisv1.PermissionBase, error)
DeletePermission(ctx context.Context, projectName, permName string) error
InitDefaultRoleAndUsersForProject(ctx context.Context, project *model.Project) error
Init(ctx context.Context) error
@@ -446,9 +451,9 @@ func (p *rbacServiceImpl) GetUserPermissions(ctx context.Context, user *model.Us
return perms, nil
}
func (p *rbacServiceImpl) UpdatePermission(ctx context.Context, projetName string, permissionName string, req *apisv1.UpdatePermissionRequest) (*apisv1.PermissionBase, error) {
func (p *rbacServiceImpl) UpdatePermission(ctx context.Context, projectName string, permissionName string, req *apisv1.UpdatePermissionRequest) (*apisv1.PermissionBase, error) {
perm := &model.Permission{
Project: projetName,
Project: projectName,
Name: permissionName,
}
err := p.Store.Get(ctx, perm)
@@ -556,6 +561,7 @@ func (p *rbacServiceImpl) CheckPerm(resource string, actions ...string) func(req
}
return req.PathParameter(name)
})
ra.SetActions(actions)
// get user's perm list.
projectName := getProjectName()
@@ -603,7 +609,7 @@ func (p *rbacServiceImpl) CreateRole(ctx context.Context, projectName string, re
}
return nil, err
}
return ConvertRole2Model(&role, policies), nil
return assembler.ConvertRole2DTO(&role, policies), nil
}
func (p *rbacServiceImpl) DeleteRole(ctx context.Context, projectName, roleName string) error {
@@ -621,6 +627,19 @@ func (p *rbacServiceImpl) DeleteRole(ctx context.Context, projectName, roleName
}
func (p *rbacServiceImpl) DeletePermission(ctx context.Context, projectName, permName string) error {
roles, _, err := repository.ListRoles(ctx, p.Store, projectName, 0, 0)
if err != nil {
log.Logger.Errorf("fail to list the roles: %s", err.Error())
return bcode.ErrPermissionIsUsed
}
for _, role := range roles {
for _, p := range role.Permissions {
if p == permName {
return bcode.ErrPermissionIsUsed
}
}
}
var perm = model.Permission{
Name: permName,
Project: projectName,
@@ -665,26 +684,17 @@ func (p *rbacServiceImpl) UpdateRole(ctx context.Context, projectName, roleName
if err := p.Store.Put(ctx, &role); err != nil {
return nil, err
}
return ConvertRole2Model(&role, policies), nil
return assembler.ConvertRole2DTO(&role, policies), nil
}
func (p *rbacServiceImpl) ListRole(ctx context.Context, projectName string, page, pageSize int) (*apisv1.ListRolesResponse, error) {
var role = model.Role{
Project: projectName,
}
var filter datastore.FilterOptions
if projectName == "" {
filter.IsNotExist = append(filter.IsNotExist, datastore.IsNotExistQueryOption{
Key: "project",
})
}
entities, err := p.Store.List(ctx, &role, &datastore.ListOptions{FilterOptions: filter, Page: page, PageSize: pageSize, SortBy: []datastore.SortOption{{Key: "createTime", Order: datastore.SortOrderDescending}}})
roles, count, err := repository.ListRoles(ctx, p.Store, projectName, 0, 0)
if err != nil {
return nil, err
}
var policySet = make(map[string]string)
for _, entity := range entities {
for _, p := range entity.(*model.Role).Permissions {
for _, role := range roles {
for _, p := range role.Permissions {
policySet[p] = p
}
}
@@ -698,17 +708,12 @@ func (p *rbacServiceImpl) ListRole(ctx context.Context, projectName string, page
policyMap[policy.Name] = policies[i]
}
var res apisv1.ListRolesResponse
for _, entity := range entities {
role := entity.(*model.Role)
for _, role := range roles {
var rolePolicies []*model.Permission
for _, perm := range role.Permissions {
rolePolicies = append(rolePolicies, policyMap[perm])
}
res.Roles = append(res.Roles, ConvertRole2Model(entity.(*model.Role), rolePolicies))
}
count, err := p.Store.Count(ctx, &role, &filter)
if err != nil {
return nil, err
res.Roles = append(res.Roles, assembler.ConvertRole2DTO(role, rolePolicies))
}
res.Total = count
return &res, nil
@@ -746,11 +751,50 @@ func (p *rbacServiceImpl) ListPermissions(ctx context.Context, projectName strin
return perms, nil
}
func (p *rbacServiceImpl) CreatePermission(ctx context.Context, projectName string, req apisv1.CreatePermissionRequest) (*apisv1.PermissionBase, error) {
if projectName != "" {
var project = model.Project{
Name: projectName,
}
if err := p.Store.Get(ctx, &project); err != nil {
return nil, bcode.ErrProjectIsNotExist
}
}
if len(req.Resources) == 0 {
return nil, bcode.ErrRolePermissionCheckFailure
}
if len(req.Actions) == 0 {
req.Actions = []string{"*"}
}
if req.Effect == "" {
req.Effect = "Allow"
}
var permission = model.Permission{
Name: req.Name,
Alias: req.Alias,
Project: projectName,
Resources: req.Resources,
Actions: req.Actions,
Effect: req.Effect,
}
if err := p.Store.Add(ctx, &permission); err != nil {
if errors.Is(err, datastore.ErrRecordExist) {
return nil, bcode.ErrPermissionIsExist
}
return nil, err
}
return assembler.ConvertPermission2DTO(&permission), nil
}
func (p *rbacServiceImpl) InitDefaultRoleAndUsersForProject(ctx context.Context, project *model.Project) error {
var batchData []datastore.Entity
for _, permissionTemp := range defaultProjectPermissionTemplate {
var rra = RequestResourceAction{}
var formatedResource []string
var formattedResource []string
for _, resource := range permissionTemp.Resources {
rra.SetResourceWithName(resource, func(name string) string {
if name == ResourceMaps["project"].pathName {
@@ -758,13 +802,13 @@ func (p *rbacServiceImpl) InitDefaultRoleAndUsersForProject(ctx context.Context,
}
return ""
})
formatedResource = append(formatedResource, rra.GetResource().String())
formattedResource = append(formattedResource, rra.GetResource().String())
}
batchData = append(batchData, &model.Permission{
Name: permissionTemp.Name,
Alias: permissionTemp.Alias,
Project: project.Name,
Resources: formatedResource,
Resources: formattedResource,
Actions: permissionTemp.Actions,
Effect: permissionTemp.Effect,
})
@@ -791,24 +835,6 @@ func (p *rbacServiceImpl) InitDefaultRoleAndUsersForProject(ctx context.Context,
return p.Store.BatchAdd(ctx, batchData)
}
// ConvertRole2Model convert role model to role base struct
func ConvertRole2Model(role *model.Role, policies []*model.Permission) *apisv1.RoleBase {
return &apisv1.RoleBase{
CreateTime: role.CreateTime,
UpdateTime: role.UpdateTime,
Name: role.Name,
Alias: role.Alias,
Permissions: func() (list []apisv1.NameAlias) {
for _, policy := range policies {
if policy != nil {
list = append(list, apisv1.NameAlias{Name: policy.Name, Alias: policy.Alias})
}
}
return
}(),
}
}
// ResourceName it is similar to ARNs
// <type>:<value>/<type>:<value>
type ResourceName struct {
+19
View File
@@ -51,6 +51,10 @@ var _ = Describe("Test rbac service", func() {
Expect(err).Should(BeNil())
Expect(path).Should(BeEquivalentTo("project:{projectName}/application:{appName}"))
path, err = checkResourcePath("environment")
Expect(err).Should(BeNil())
Expect(path).Should(BeEquivalentTo("project:{projectName}/environment:{envName}"))
_, err = checkResourcePath("applications")
Expect(err).ShouldNot(BeNil())
@@ -263,6 +267,21 @@ func TestRequestResourceActionMatch(t *testing.T) {
ra5.SetActions([]string{"list"})
assert.Equal(t, ra5.Match([]*model.Permission{{Resources: []string{"project:*/application:*"}, Actions: []string{"list"}, Effect: "Allow"}}), true)
ra6 := &RequestResourceAction{}
path, err := checkResourcePath("environment")
assert.Equal(t, err, nil)
ra6.SetResourceWithName(path, func(name string) string {
if name == "projectName" {
return "default"
}
return ""
})
ra6.SetActions([]string{"create"})
assert.Equal(t, ra6.Match([]*model.Permission{{Resources: []string{
"project:*/*", "addon:* addonRegistry:*", "target:*", "cluster:*/namespace:*", "user:*", "role:*", "permission:*", "configType:*/*", "project:*",
"project:default/config:*", "project:default/role:*", "project:default/projectUser:*", "project:default/permission:*", "project:default/environment:*", "project:default/application:*/*", "project:default",
}, Actions: []string{"list", "detail"}, Effect: "Allow"}}), false)
}
func TestRegisterResourceAction(t *testing.T) {
@@ -201,6 +201,40 @@ func ConvertPolicyModelToBase(policy *model.ApplicationPolicy) *apisv1.PolicyBas
return pb
}
// ConvertRole2DTO convert role model to role base struct
func ConvertRole2DTO(role *model.Role, policies []*model.Permission) *apisv1.RoleBase {
return &apisv1.RoleBase{
CreateTime: role.CreateTime,
UpdateTime: role.UpdateTime,
Name: role.Name,
Alias: role.Alias,
Permissions: func() (list []apisv1.NameAlias) {
for _, policy := range policies {
if policy != nil {
list = append(list, apisv1.NameAlias{Name: policy.Name, Alias: policy.Alias})
}
}
return
}(),
}
}
// ConvertPermission2DTO convert permission model to the DTO
func ConvertPermission2DTO(permission *model.Permission) *apisv1.PermissionBase {
if permission == nil {
return nil
}
return &apisv1.PermissionBase{
Name: permission.Name,
Alias: permission.Alias,
Resources: permission.Resources,
Actions: permission.Actions,
Effect: permission.Effect,
CreateTime: permission.CreateTime,
UpdateTime: permission.UpdateTime,
}
}
func convertBool(b *bool) bool {
if b == nil {
return false
+10 -1
View File
@@ -1345,7 +1345,7 @@ type PermissionBase struct {
UpdateTime time.Time `json:"updateTime"`
}
// UpdatePermissionRequest the request body that update permission policy
// UpdatePermissionRequest the request body that updating a permission policy
type UpdatePermissionRequest struct {
Alias string `json:"alias" validate:"checkalias"`
Resources []string `json:"resources"`
@@ -1353,6 +1353,15 @@ type UpdatePermissionRequest struct {
Effect string `json:"effect" validate:"oneof=Allow Deny"`
}
// CreatePermissionRequest the request body that creating a permission policy
type CreatePermissionRequest struct {
Name string `json:"name" validate:"checkname"`
Alias string `json:"alias" validate:"checkalias"`
Resources []string `json:"resources"`
Actions []string `json:"actions"`
Effect string `json:"effect" validate:"oneof=Allow Deny"`
}
// LoginUserInfoResponse the response body of login user info
type LoginUserInfoResponse struct {
UserBase
+2 -2
View File
@@ -70,7 +70,7 @@ func (n *envAPIInterface) GetWebServiceRoute() *restful.WebService {
Doc("update an env").
Metadata(restfulspec.KeyOpenAPITags, tags).
Filter(n.RBACService.CheckPerm("environment", "update")).
Param(ws.PathParameter("envName", "identifier of the application ").DataType("string")).
Param(ws.PathParameter("envName", "identifier of the environment").DataType("string")).
Reads(apis.CreateEnvRequest{}).
Returns(200, "OK", apis.Env{}).
Writes(apis.Env{}))
@@ -80,7 +80,7 @@ func (n *envAPIInterface) GetWebServiceRoute() *restful.WebService {
Doc("delete one env").
Metadata(restfulspec.KeyOpenAPITags, tags).
Filter(n.RBACService.CheckPerm("environment", "delete")).
Param(ws.PathParameter("envName", "identifier of the application ").DataType("string")).
Param(ws.PathParameter("envName", "identifier of the environment").DataType("string")).
Returns(200, "OK", apis.EmptyResponse{}).
Returns(400, "Bad Request", bcode.Bcode{}).
Writes(apis.EmptyResponse{}))
+56
View File
@@ -176,6 +176,23 @@ func (n *projectAPIInterface) GetWebServiceRoute() *restful.WebService {
Returns(200, "OK", []apis.PermissionBase{}).
Writes([]apis.PermissionBase{}))
ws.Route(ws.POST("/{projectName}/permissions").To(n.createProjectPermission).
Doc("create a project level perm policy").
Metadata(restfulspec.KeyOpenAPITags, tags).
Param(ws.PathParameter("projectName", "identifier of the project").DataType("string")).
Filter(n.RbacService.CheckPerm("project/permission", "list")).
Returns(200, "OK", []apis.PermissionBase{}).
Writes([]apis.PermissionBase{}))
ws.Route(ws.DELETE("/{projectName}/permissions/{permissionName}").To(n.deleteProjectPermission).
Doc("delete a project level perm policy").
Metadata(restfulspec.KeyOpenAPITags, tags).
Param(ws.PathParameter("projectName", "identifier of the project").DataType("string")).
Param(ws.PathParameter("permissionName", "identifier of the permission").DataType("string")).
Filter(n.RbacService.CheckPerm("project/permission", "list")).
Returns(200, "OK", []apis.PermissionBase{}).
Writes([]apis.PermissionBase{}))
ws.Route(ws.GET("/{projectName}/configs").To(n.getConfigs).
Doc("get configs which are in a project").
Metadata(restfulspec.KeyOpenAPITags, tags).
@@ -524,6 +541,45 @@ func (n *projectAPIInterface) listProjectPermissions(req *restful.Request, res *
}
}
func (n *projectAPIInterface) createProjectPermission(req *restful.Request, res *restful.Response) {
// Verify the validity of parameters
var createReq apis.CreatePermissionRequest
if err := req.ReadEntity(&createReq); err != nil {
bcode.ReturnError(req, res, err)
return
}
if err := validate.Struct(&createReq); err != nil {
bcode.ReturnError(req, res, err)
return
}
// Call the domain layer code
permissionBase, err := n.RbacService.CreatePermission(req.Request.Context(), req.PathParameter("projectName"), createReq)
if err != nil {
log.Logger.Errorf("create the permission failure %s", err.Error())
bcode.ReturnError(req, res, err)
return
}
// Write back response data
if err := res.WriteEntity(permissionBase); err != nil {
bcode.ReturnError(req, res, err)
return
}
}
func (n *projectAPIInterface) deleteProjectPermission(req *restful.Request, res *restful.Response) {
err := n.RbacService.DeletePermission(req.Request.Context(), req.PathParameter("projectName"), req.PathParameter("permissionName"))
if err != nil {
bcode.ReturnError(req, res, err)
return
}
// Write back response data
if err := res.WriteEntity(apis.EmptyResponse{}); err != nil {
bcode.ReturnError(req, res, err)
return
}
}
func (n *projectAPIInterface) getConfigs(req *restful.Request, res *restful.Response) {
configs, err := n.ProjectService.GetConfigs(req.Request.Context(), req.PathParameter("projectName"), req.QueryParameter("configType"))
if err != nil {
+58 -1
View File
@@ -63,6 +63,7 @@ func (r *rbacAPIInterface) GetWebServiceRoute() *restful.WebService {
ws.Route(ws.PUT("/roles/{roleName}").To(r.updatePlatformRole).
Doc("update platform level role").
Metadata(restfulspec.KeyOpenAPITags, tags).
Param(ws.PathParameter("roleName", "identifier of the role").DataType("string")).
Filter(r.RbacService.CheckPerm("role", "update")).
Reads(apis.UpdateRoleRequest{}).
Returns(200, "OK", apis.RoleBase{}).
@@ -71,17 +72,34 @@ func (r *rbacAPIInterface) GetWebServiceRoute() *restful.WebService {
ws.Route(ws.DELETE("/roles/{roleName}").To(r.deletePlatformRole).
Doc("update platform level role").
Metadata(restfulspec.KeyOpenAPITags, tags).
Param(ws.PathParameter("roleName", "identifier of the role").DataType("string")).
Filter(r.RbacService.CheckPerm("role", "delete")).
Returns(200, "OK", apis.EmptyResponse{}).
Writes(apis.EmptyResponse{}))
ws.Route(ws.GET("/permissions").To(r.listPlatformPermissions).
Doc("list all project level perm policies").
Doc("list all platform level perm policies").
Metadata(restfulspec.KeyOpenAPITags, tags).
Filter(r.RbacService.CheckPerm("permission", "list")).
Returns(200, "OK", []apis.PermissionBase{}).
Writes([]apis.PermissionBase{}))
ws.Route(ws.POST("/permissions").To(r.createPlatformPermission).
Doc("create the platform perm policy").
Metadata(restfulspec.KeyOpenAPITags, tags).
Reads(apis.CreatePermissionRequest{}).
Filter(r.RbacService.CheckPerm("permission", "create")).
Returns(200, "OK", apis.PermissionBase{}).
Writes(apis.PermissionBase{}))
ws.Route(ws.DELETE("/permissions/{permissionName}").To(r.deletePlatformPermission).
Doc("delete a platform perm policy").
Metadata(restfulspec.KeyOpenAPITags, tags).
Param(ws.PathParameter("permissionName", "identifier of the permission").DataType("string")).
Filter(r.RbacService.CheckPerm("permission", "delete")).
Returns(200, "OK", apis.EmptyResponse{}).
Writes(apis.EmptyResponse{}))
ws.Filter(authCheckFilter)
return ws
}
@@ -179,3 +197,42 @@ func (r *rbacAPIInterface) listPlatformPermissions(req *restful.Request, res *re
return
}
}
func (r *rbacAPIInterface) createPlatformPermission(req *restful.Request, res *restful.Response) {
// Verify the validity of parameters
var createReq apis.CreatePermissionRequest
if err := req.ReadEntity(&createReq); err != nil {
bcode.ReturnError(req, res, err)
return
}
if err := validate.Struct(&createReq); err != nil {
bcode.ReturnError(req, res, err)
return
}
// Call the domain layer code
permissionBase, err := r.RbacService.CreatePermission(req.Request.Context(), "", createReq)
if err != nil {
log.Logger.Errorf("create the permission failure %s", err.Error())
bcode.ReturnError(req, res, err)
return
}
// Write back response data
if err := res.WriteEntity(permissionBase); err != nil {
bcode.ReturnError(req, res, err)
return
}
}
func (r *rbacAPIInterface) deletePlatformPermission(req *restful.Request, res *restful.Response) {
err := r.RbacService.DeletePermission(req.Request.Context(), "", req.PathParameter("permissionName"))
if err != nil {
bcode.ReturnError(req, res, err)
return
}
// Write back response data
if err := res.WriteEntity(apis.EmptyResponse{}); err != nil {
bcode.ReturnError(req, res, err)
return
}
}
+4
View File
@@ -25,4 +25,8 @@ var (
ErrRoleIsNotExist = NewBcode(400, 15003, "the role is not exist")
// ErrPermissionNotExist means the permission is not exist
ErrPermissionNotExist = NewBcode(404, 15004, "the permission is not exist")
// ErrPermissionIsExist means the he permission is exist
ErrPermissionIsExist = NewBcode(400, 15005, "the permission name is exist")
// ErrPermissionIsUsed means the permission is bound by role, can not be deleted
ErrPermissionIsUsed = NewBcode(400, 15006, "the permission have been used")
)