补充鉴权逻辑
This commit is contained in:
parent
9eb977cfbf
commit
298cadf2e2
5
devcloud/mcenter/apps/namespace/const.go
Normal file
5
devcloud/mcenter/apps/namespace/const.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package namespace
|
||||||
|
|
||||||
|
const (
|
||||||
|
DEFAULT_NS_NAME = "default"
|
||||||
|
)
|
31
devcloud/mcenter/apps/namespace/impl/impl.go
Normal file
31
devcloud/mcenter/apps/namespace/impl/impl.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package impl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/namespace"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc/config/datasource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ioc.Controller().Registry(&NameSpaceServiceImpl{})
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ namespace.Service = (*NameSpaceServiceImpl)(nil)
|
||||||
|
|
||||||
|
type NameSpaceServiceImpl struct {
|
||||||
|
ioc.ObjectImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *NameSpaceServiceImpl) Init() error {
|
||||||
|
if datasource.Get().AutoMigrate {
|
||||||
|
err := datasource.DB().AutoMigrate(&namespace.Namespace{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *NameSpaceServiceImpl) Name() string {
|
||||||
|
return namespace.AppName
|
||||||
|
}
|
18
devcloud/mcenter/apps/namespace/impl/impl_test.go
Normal file
18
devcloud/mcenter/apps/namespace/impl/impl_test.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package impl_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/namespace"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
impl namespace.Service
|
||||||
|
ctx = context.Background()
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
test.DevelopmentSetUp()
|
||||||
|
impl = namespace.GetService()
|
||||||
|
}
|
93
devcloud/mcenter/apps/namespace/impl/namespace.go
Normal file
93
devcloud/mcenter/apps/namespace/impl/namespace.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package impl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/namespace"
|
||||||
|
"github.com/infraboard/mcube/v2/exception"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc/config/datasource"
|
||||||
|
"github.com/infraboard/mcube/v2/types"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 创建空间
|
||||||
|
func (i *NameSpaceServiceImpl) CreateNamespace(ctx context.Context, in *namespace.CreateNamespaceRequest) (*namespace.Namespace, error) {
|
||||||
|
if err := in.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ins := namespace.NewNamespace()
|
||||||
|
ins.CreateNamespaceRequest = *in
|
||||||
|
|
||||||
|
if err := datasource.DBFromCtx(ctx).
|
||||||
|
Create(ins).
|
||||||
|
Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ins, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询空间
|
||||||
|
func (i *NameSpaceServiceImpl) QueryNamespace(ctx context.Context, in *namespace.QueryNamespaceRequest) (*types.Set[*namespace.Namespace], error) {
|
||||||
|
set := types.New[*namespace.Namespace]()
|
||||||
|
|
||||||
|
query := datasource.DBFromCtx(ctx).Model(&namespace.Namespace{})
|
||||||
|
err := query.Count(&set.Total).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = query.
|
||||||
|
Order("created_at desc").
|
||||||
|
Offset(int(in.ComputeOffset())).
|
||||||
|
Limit(int(in.PageSize)).
|
||||||
|
Find(&set.Items).
|
||||||
|
Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return set, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询空间详情
|
||||||
|
func (i *NameSpaceServiceImpl) DescribeNamespace(ctx context.Context, in *namespace.DescribeNamespaceRequest) (*namespace.Namespace, error) {
|
||||||
|
query := datasource.DBFromCtx(ctx)
|
||||||
|
|
||||||
|
ins := &namespace.Namespace{}
|
||||||
|
if err := query.Where("id = ?", in.Id).First(ins).Error; err != nil {
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return nil, exception.NewNotFound("namespace %d not found", in.Id)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ins, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新空间
|
||||||
|
func (i *NameSpaceServiceImpl) UpdateNamespace(ctx context.Context, in *namespace.UpdateNamespaceRequest) (*namespace.Namespace, error) {
|
||||||
|
descReq := namespace.NewDescribeNamespaceRequest()
|
||||||
|
descReq.SetId(in.Id)
|
||||||
|
ins, err := i.DescribeNamespace(ctx, descReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ins.CreateNamespaceRequest = in.CreateNamespaceRequest
|
||||||
|
return ins, datasource.DBFromCtx(ctx).Where("id = ?", in.Id).Updates(ins).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除空间
|
||||||
|
func (i *NameSpaceServiceImpl) DeleteNamespace(ctx context.Context, in *namespace.DeleteNamespaceRequest) (*namespace.Namespace, error) {
|
||||||
|
descReq := namespace.NewDescribeNamespaceRequest()
|
||||||
|
descReq.SetId(in.Id)
|
||||||
|
ins, err := i.DescribeNamespace(ctx, descReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ins, datasource.DBFromCtx(ctx).
|
||||||
|
Where("id = ?", in.Id).
|
||||||
|
Delete(&namespace.Namespace{}).
|
||||||
|
Error
|
||||||
|
}
|
28
devcloud/mcenter/apps/namespace/impl/namespace_test.go
Normal file
28
devcloud/mcenter/apps/namespace/impl/namespace_test.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package impl_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/namespace"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestQueryNamespace(t *testing.T) {
|
||||||
|
req := namespace.NewQueryNamespaceRequest()
|
||||||
|
set, err := impl.QueryNamespace(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(set)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateNamespace(t *testing.T) {
|
||||||
|
req := namespace.NewCreateNamespaceRequest()
|
||||||
|
req.Name = namespace.DEFAULT_NS_NAME
|
||||||
|
req.Description = "默认空间"
|
||||||
|
req.OwnerUserId = 1
|
||||||
|
set, err := impl.CreateNamespace(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(set)
|
||||||
|
}
|
90
devcloud/mcenter/apps/namespace/interface.go
Normal file
90
devcloud/mcenter/apps/namespace/interface.go
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
package namespace
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/infraboard/mcube/v2/http/request"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc"
|
||||||
|
"github.com/infraboard/mcube/v2/types"
|
||||||
|
"github.com/infraboard/modules/iam/apps"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AppName = "namespace"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetService() Service {
|
||||||
|
return ioc.Controller().Get(AppName).(Service)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Service interface {
|
||||||
|
// 创建空间
|
||||||
|
CreateNamespace(context.Context, *CreateNamespaceRequest) (*Namespace, error)
|
||||||
|
// 查询空间
|
||||||
|
QueryNamespace(context.Context, *QueryNamespaceRequest) (*types.Set[*Namespace], error)
|
||||||
|
// 查询空间详情
|
||||||
|
DescribeNamespace(context.Context, *DescribeNamespaceRequest) (*Namespace, error)
|
||||||
|
// 更新空间
|
||||||
|
UpdateNamespace(context.Context, *UpdateNamespaceRequest) (*Namespace, error)
|
||||||
|
// 删除空间
|
||||||
|
DeleteNamespace(context.Context, *DeleteNamespaceRequest) (*Namespace, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQueryNamespaceRequest() *QueryNamespaceRequest {
|
||||||
|
return &QueryNamespaceRequest{
|
||||||
|
PageRequest: *request.NewDefaultPageRequest(),
|
||||||
|
NamespaceIds: []uint64{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type QueryNamespaceRequest struct {
|
||||||
|
request.PageRequest
|
||||||
|
NamespaceIds []uint64 `json:"namespace_ids"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *QueryNamespaceRequest) AddNamespaceIds(ids ...uint64) {
|
||||||
|
for _, id := range ids {
|
||||||
|
if !r.HasNamespaceIds(id) {
|
||||||
|
r.NamespaceIds = append(r.NamespaceIds, id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *QueryNamespaceRequest) HasNamespaceIds(namespaceId uint64) bool {
|
||||||
|
for i := range r.NamespaceIds {
|
||||||
|
if r.NamespaceIds[i] == namespaceId {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDescribeNamespaceRequest() *DescribeNamespaceRequest {
|
||||||
|
return &DescribeNamespaceRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeNamespaceRequest struct {
|
||||||
|
apps.GetRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *DescribeNamespaceRequest) SetNamespaceId(id uint64) *DescribeNamespaceRequest {
|
||||||
|
r.Id = id
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUpdateNamespaceRequest() *UpdateNamespaceRequest {
|
||||||
|
return &UpdateNamespaceRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateNamespaceRequest struct {
|
||||||
|
apps.GetRequest
|
||||||
|
CreateNamespaceRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDeleteNamespaceRequest() *DeleteNamespaceRequest {
|
||||||
|
return &DeleteNamespaceRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteNamespaceRequest struct {
|
||||||
|
apps.GetRequest
|
||||||
|
}
|
62
devcloud/mcenter/apps/namespace/model.go
Normal file
62
devcloud/mcenter/apps/namespace/model.go
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package namespace
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/infraboard/mcube/v2/ioc/config/validator"
|
||||||
|
"github.com/infraboard/mcube/v2/tools/pretty"
|
||||||
|
"github.com/infraboard/modules/iam/apps"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewNamespace() *Namespace {
|
||||||
|
return &Namespace{
|
||||||
|
ResourceMeta: *apps.NewResourceMeta(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Namespace struct {
|
||||||
|
// 基础数据
|
||||||
|
apps.ResourceMeta
|
||||||
|
// 空间属性
|
||||||
|
CreateNamespaceRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Namespace) IsOwner(ownerUserId uint64) bool {
|
||||||
|
return n.OwnerUserId == ownerUserId
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Namespace) TableName() string {
|
||||||
|
return "namespaces"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Namespace) String() string {
|
||||||
|
return pretty.ToJSON(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCreateNamespaceRequest() *CreateNamespaceRequest {
|
||||||
|
return &CreateNamespaceRequest{
|
||||||
|
Extras: map[string]string{},
|
||||||
|
Enabled: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateNamespaceRequest struct {
|
||||||
|
// 父Namespace Id
|
||||||
|
ParentId uint64 `json:"parent_id" bson:"parent_id" gorm:"column:parent_id;type:uint;index" description:"父Namespace Id"`
|
||||||
|
// 全局唯一
|
||||||
|
Name string `json:"name" bson:"name" validate:"required" gorm:"column:name;type:varchar(200);not null;uniqueIndex" description:"空间名称" unique:"true"`
|
||||||
|
// 空间负责人
|
||||||
|
OwnerUserId uint64 `json:"owner_user_id" bson:"owner_user_id" gorm:"column:owner_user_id;type:uint;index;not null" description:" 空间负责人Id"`
|
||||||
|
// 禁用项目, 该项目所有人暂时都无法访问
|
||||||
|
Enabled bool `json:"enabled" bson:"enabled" gorm:"column:enabled;type:tinyint(1)" description:"是否启用"`
|
||||||
|
// 空间描述图片
|
||||||
|
Icon string `json:"icon" bson:"icon" gorm:"column:icon;type:varchar(200)" description:"空间图标"`
|
||||||
|
// 空间描述
|
||||||
|
Description string `json:"description" bson:"description" gorm:"column:description;type:text" description:"空间描述"`
|
||||||
|
// 标签
|
||||||
|
Label string `json:"label" gorm:"column:label;type:varchar(200);index" description:"标签"`
|
||||||
|
// 扩展信息
|
||||||
|
Extras map[string]string `json:"extras" bson:"extras" gorm:"column:extras;serializer:json;type:json" description:"扩展信息"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CreateNamespaceRequest) Validate() error {
|
||||||
|
return validator.Validate(r)
|
||||||
|
}
|
38
devcloud/mcenter/apps/policy/impl/impl.go
Normal file
38
devcloud/mcenter/apps/policy/impl/impl.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package impl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/namespace"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/policy"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/role"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc/config/datasource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ioc.Controller().Registry(&PolicyServiceImpl{})
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ policy.Service = (*PolicyServiceImpl)(nil)
|
||||||
|
|
||||||
|
type PolicyServiceImpl struct {
|
||||||
|
ioc.ObjectImpl
|
||||||
|
|
||||||
|
namespace namespace.Service
|
||||||
|
role role.Service
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *PolicyServiceImpl) Init() error {
|
||||||
|
if datasource.Get().AutoMigrate {
|
||||||
|
err := datasource.DB().AutoMigrate(&policy.Policy{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i.namespace = namespace.GetService()
|
||||||
|
i.role = role.GetService()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *PolicyServiceImpl) Name() string {
|
||||||
|
return policy.AppName
|
||||||
|
}
|
18
devcloud/mcenter/apps/policy/impl/impl_test.go
Normal file
18
devcloud/mcenter/apps/policy/impl/impl_test.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package impl_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/policy"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
impl policy.Service
|
||||||
|
ctx = context.Background()
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
test.DevelopmentSetUp()
|
||||||
|
impl = policy.GetService()
|
||||||
|
}
|
107
devcloud/mcenter/apps/policy/impl/permission.go
Normal file
107
devcloud/mcenter/apps/policy/impl/permission.go
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package impl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/endpoint"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/namespace"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/policy"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/role"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/view"
|
||||||
|
"github.com/infraboard/mcube/v2/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 查询用户可以访问的空间
|
||||||
|
func (i *PolicyServiceImpl) QueryNamespace(ctx context.Context, in *policy.QueryNamespaceRequest) (*types.Set[*namespace.Namespace], error) {
|
||||||
|
nsReq := namespace.NewQueryNamespaceRequest()
|
||||||
|
|
||||||
|
policies, err := i.QueryPolicy(ctx,
|
||||||
|
policy.NewQueryPolicyRequest().
|
||||||
|
SetSkipPage(true).
|
||||||
|
SetUserId(in.UserId).
|
||||||
|
SetExpired(false).
|
||||||
|
SetEnabled(true))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
policies.ForEach(func(t *policy.Policy) {
|
||||||
|
if t.NamespaceId != nil {
|
||||||
|
nsReq.AddNamespaceIds(*t.NamespaceId)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return i.namespace.QueryNamespace(ctx, nsReq)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询用户可以访问的Api接口
|
||||||
|
// 找到用户可以访问的角色列表,然后在找出角色对应的Api访问权限
|
||||||
|
func (i *PolicyServiceImpl) QueryEndpoint(ctx context.Context, in *policy.QueryEndpointRequest) (*types.Set[*endpoint.Endpoint], error) {
|
||||||
|
set := types.New[*endpoint.Endpoint]()
|
||||||
|
policies, err := i.QueryPolicy(ctx,
|
||||||
|
policy.NewQueryPolicyRequest().
|
||||||
|
SetSkipPage(true).
|
||||||
|
SetNamespaceId(in.NamespaceId).
|
||||||
|
SetUserId(in.UserId).
|
||||||
|
SetExpired(false).
|
||||||
|
SetEnabled(true))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
roleReq := role.NewQueryMatchedEndpointRequest()
|
||||||
|
policies.ForEach(func(t *policy.Policy) {
|
||||||
|
roleReq.Add(t.RoleId)
|
||||||
|
})
|
||||||
|
|
||||||
|
if policies.Len() > 0 {
|
||||||
|
set, err = role.GetService().QueryMatchedEndpoint(ctx, roleReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return set, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验Api接口权限
|
||||||
|
func (i *PolicyServiceImpl) ValidateEndpointPermission(ctx context.Context, in *policy.ValidateEndpointPermissionRequest) (*policy.ValidateEndpointPermissionResponse, error) {
|
||||||
|
resp := policy.NewValidateEndpointPermissionResponse(*in)
|
||||||
|
|
||||||
|
// 空间Owner有所有权限
|
||||||
|
ns, err := namespace.GetService().DescribeNamespace(ctx, namespace.NewDescribeNamespaceRequest().SetNamespaceId(in.NamespaceId))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if ns.IsOwner(in.UserId) {
|
||||||
|
resp.HasPermission = true
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非空间管理员需要独立鉴权, 查询用户可以访问的API列表
|
||||||
|
endpointReq := policy.NewQueryEndpointRequest()
|
||||||
|
endpointReq.UserId = in.UserId
|
||||||
|
endpointReq.NamespaceId = in.NamespaceId
|
||||||
|
endpointSet, err := i.QueryEndpoint(ctx, endpointReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, item := range endpointSet.Items {
|
||||||
|
if item.IsMatched(in.Service, in.Method, in.Path) {
|
||||||
|
resp.HasPermission = true
|
||||||
|
resp.Endpoint = item
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询用户可以访问的菜单
|
||||||
|
func (i *PolicyServiceImpl) QueryMenu(ctx context.Context, in *policy.QueryMenuRequest) (*types.Set[*view.Menu], error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验Menu视图权限
|
||||||
|
func (i *PolicyServiceImpl) ValidatePagePermission(ctx context.Context, in *policy.ValidatePagePermissionRequest) (*policy.ValidatePagePermissionResponse, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
42
devcloud/mcenter/apps/policy/impl/permission_test.go
Normal file
42
devcloud/mcenter/apps/policy/impl/permission_test.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package impl_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/policy"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestQueryNamespace(t *testing.T) {
|
||||||
|
req := policy.NewQueryNamespaceRequest()
|
||||||
|
req.UserId = 1
|
||||||
|
set, err := impl.QueryNamespace(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(set)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestQueryEndpoint(t *testing.T) {
|
||||||
|
req := policy.NewQueryEndpointRequest()
|
||||||
|
req.UserId = 1
|
||||||
|
req.NamespaceId = 1
|
||||||
|
set, err := impl.QueryEndpoint(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(set)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateEndpointPermission(t *testing.T) {
|
||||||
|
req := policy.NewValidateEndpointPermissionRequest()
|
||||||
|
req.UserId = 1
|
||||||
|
req.NamespaceId = 1
|
||||||
|
req.Service = "devcloud"
|
||||||
|
req.Method = "GET"
|
||||||
|
req.Path = "/api/devcloud/v1/users/"
|
||||||
|
set, err := impl.ValidateEndpointPermission(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(set)
|
||||||
|
}
|
148
devcloud/mcenter/apps/policy/impl/policy.go
Normal file
148
devcloud/mcenter/apps/policy/impl/policy.go
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
package impl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/namespace"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/policy"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/role"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/user"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/view"
|
||||||
|
"github.com/infraboard/mcube/v2/exception"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc/config/datasource"
|
||||||
|
"github.com/infraboard/mcube/v2/types"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 创建策略
|
||||||
|
func (i *PolicyServiceImpl) CreatePolicy(ctx context.Context, in *policy.CreatePolicyRequest) (*policy.Policy, error) {
|
||||||
|
if err := in.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ins := policy.NewPolicy()
|
||||||
|
ins.CreatePolicyRequest = *in
|
||||||
|
|
||||||
|
if err := datasource.DBFromCtx(ctx).
|
||||||
|
Create(ins).
|
||||||
|
Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ins, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询策略列表
|
||||||
|
func (i *PolicyServiceImpl) QueryPolicy(ctx context.Context, in *policy.QueryPolicyRequest) (*types.Set[*policy.Policy], error) {
|
||||||
|
set := types.New[*policy.Policy]()
|
||||||
|
|
||||||
|
query := datasource.DBFromCtx(ctx).Model(&policy.Policy{}).Order("created_at desc")
|
||||||
|
err := query.Count(&set.Total).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !in.SkipPage {
|
||||||
|
query = query.
|
||||||
|
Offset(int(in.ComputeOffset())).
|
||||||
|
Limit(int(in.PageSize))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = query.Find(&set.Items).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if in.WithUser {
|
||||||
|
userReq := user.NewQueryUserRequest()
|
||||||
|
set.ForEach(func(t *policy.Policy) {
|
||||||
|
userReq.AddUser(t.UserId)
|
||||||
|
})
|
||||||
|
userSet, err := user.GetService().QueryUser(ctx, userReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
set.ForEach(func(p *policy.Policy) {
|
||||||
|
p.User = userSet.Filter(func(t *user.User) bool {
|
||||||
|
return p.UserId == t.Id
|
||||||
|
}).First()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if in.WithRole {
|
||||||
|
roleReq := role.NewQueryRoleRequest()
|
||||||
|
set.ForEach(func(t *policy.Policy) {
|
||||||
|
roleReq.AddRoleId(t.RoleId)
|
||||||
|
})
|
||||||
|
roleSet, err := role.GetService().QueryRole(ctx, roleReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
set.ForEach(func(p *policy.Policy) {
|
||||||
|
p.Role = roleSet.Filter(func(t *role.Role) bool {
|
||||||
|
return p.RoleId == t.Id
|
||||||
|
}).First()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if in.WithNamespace {
|
||||||
|
nsReq := namespace.NewQueryNamespaceRequest()
|
||||||
|
set.ForEach(func(t *policy.Policy) {
|
||||||
|
if t.NamespaceId != nil {
|
||||||
|
nsReq.AddNamespaceIds(*t.NamespaceId)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
nsSet, err := namespace.GetService().QueryNamespace(ctx, nsReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
set.ForEach(func(p *policy.Policy) {
|
||||||
|
if p.NamespaceId != nil {
|
||||||
|
p.Namespace = nsSet.Filter(func(t *namespace.Namespace) bool {
|
||||||
|
return *p.NamespaceId == t.Id
|
||||||
|
}).First()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return set, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询详情
|
||||||
|
func (i *PolicyServiceImpl) DescribePolicy(ctx context.Context, in *policy.DescribePolicyRequest) (*policy.Policy, error) {
|
||||||
|
query := datasource.DBFromCtx(ctx)
|
||||||
|
|
||||||
|
ins := &policy.Policy{}
|
||||||
|
if err := query.Where("id =?", in.Id).First(ins).Error; err != nil {
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return nil, exception.NewNotFound("policy %d not found", in.Id)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ins, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新策略
|
||||||
|
func (i *PolicyServiceImpl) UpdatePolicy(ctx context.Context, in *policy.UpdatePolicyRequest) (*policy.Policy, error) {
|
||||||
|
descReq := policy.NewDescribePolicyRequest()
|
||||||
|
descReq.SetId(in.Id)
|
||||||
|
ins, err := i.DescribePolicy(ctx, descReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ins.CreatePolicyRequest = in.CreatePolicyRequest
|
||||||
|
return ins, datasource.DBFromCtx(ctx).Where("id = ?", in.Id).Updates(ins).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除策略
|
||||||
|
func (i *PolicyServiceImpl) DeletePolicy(ctx context.Context, in *policy.DeletePolicyRequest) (*policy.Policy, error) {
|
||||||
|
descReq := policy.NewDescribePolicyRequest()
|
||||||
|
descReq.SetId(in.Id)
|
||||||
|
ins, err := i.DescribePolicy(ctx, descReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ins, datasource.DBFromCtx(ctx).
|
||||||
|
Where("id = ?", in.Id).
|
||||||
|
Delete(&view.Menu{}).
|
||||||
|
Error
|
||||||
|
}
|
31
devcloud/mcenter/apps/policy/impl/policy_test.go
Normal file
31
devcloud/mcenter/apps/policy/impl/policy_test.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package impl_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/policy"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestQueryPolicy(t *testing.T) {
|
||||||
|
req := policy.NewQueryPolicyRequest()
|
||||||
|
req.WithUser = true
|
||||||
|
req.WithRole = true
|
||||||
|
req.WithNamespace = true
|
||||||
|
set, err := impl.QueryPolicy(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(set)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreatePolicy(t *testing.T) {
|
||||||
|
req := policy.NewCreatePolicyRequest()
|
||||||
|
req.SetNamespaceId(1)
|
||||||
|
req.UserId = 1
|
||||||
|
req.RoleId = 1
|
||||||
|
set, err := impl.CreatePolicy(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(set)
|
||||||
|
}
|
233
devcloud/mcenter/apps/policy/interface.go
Normal file
233
devcloud/mcenter/apps/policy/interface.go
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
package policy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/endpoint"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/namespace"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/view"
|
||||||
|
"github.com/infraboard/mcube/v2/http/request"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc"
|
||||||
|
"github.com/infraboard/mcube/v2/tools/pretty"
|
||||||
|
"github.com/infraboard/mcube/v2/types"
|
||||||
|
"github.com/infraboard/modules/iam/apps"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AppName = "policy"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetService() Service {
|
||||||
|
return ioc.Controller().Get(AppName).(Service)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Service interface {
|
||||||
|
// 策略管理
|
||||||
|
PolicyService
|
||||||
|
// 权限查询, 整合用户多个角色的权限合集
|
||||||
|
PermissionService
|
||||||
|
}
|
||||||
|
|
||||||
|
type PolicyService interface {
|
||||||
|
// 创建策略
|
||||||
|
CreatePolicy(context.Context, *CreatePolicyRequest) (*Policy, error)
|
||||||
|
// 查询策略列表
|
||||||
|
QueryPolicy(context.Context, *QueryPolicyRequest) (*types.Set[*Policy], error)
|
||||||
|
// 查询详情
|
||||||
|
DescribePolicy(context.Context, *DescribePolicyRequest) (*Policy, error)
|
||||||
|
// 更新策略
|
||||||
|
UpdatePolicy(context.Context, *UpdatePolicyRequest) (*Policy, error)
|
||||||
|
// 删除策略
|
||||||
|
DeletePolicy(context.Context, *DeletePolicyRequest) (*Policy, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQueryPolicyRequest() *QueryPolicyRequest {
|
||||||
|
return &QueryPolicyRequest{
|
||||||
|
PageRequest: request.NewDefaultPageRequest(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type QueryPolicyRequest struct {
|
||||||
|
*request.PageRequest
|
||||||
|
// 忽略分页
|
||||||
|
SkipPage bool `json:"skip_page"`
|
||||||
|
// 关联用户Id
|
||||||
|
UserId *uint64 `json:"user_id"`
|
||||||
|
// 关联空间
|
||||||
|
NamespaceId *uint64 `json:"namespace_id"`
|
||||||
|
// 没有过期
|
||||||
|
Expired *bool `json:"expired"`
|
||||||
|
// 有没有启动
|
||||||
|
Enabled *bool `json:"active"`
|
||||||
|
// 关联查询出空间对象
|
||||||
|
WithNamespace bool `json:"with_namespace"`
|
||||||
|
// 关联查询出用户对象
|
||||||
|
WithUser bool `json:"with_user"`
|
||||||
|
// 关联查询角色对象
|
||||||
|
WithRole bool `json:"with_role"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *QueryPolicyRequest) SetNamespaceId(nsId uint64) *QueryPolicyRequest {
|
||||||
|
r.NamespaceId = &nsId
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *QueryPolicyRequest) SetUserId(uid uint64) *QueryPolicyRequest {
|
||||||
|
r.UserId = &uid
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *QueryPolicyRequest) SetExpired(v bool) *QueryPolicyRequest {
|
||||||
|
r.Expired = &v
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *QueryPolicyRequest) SetEnabled(v bool) *QueryPolicyRequest {
|
||||||
|
r.Enabled = &v
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *QueryPolicyRequest) SetSkipPage(v bool) *QueryPolicyRequest {
|
||||||
|
r.SkipPage = v
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *QueryPolicyRequest) SetWithRole(v bool) *QueryPolicyRequest {
|
||||||
|
r.WithRole = v
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
func (r *QueryPolicyRequest) SetWithUsers(v bool) *QueryPolicyRequest {
|
||||||
|
r.WithUser = v
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
func (r *QueryPolicyRequest) SetWithUser(v bool) *QueryPolicyRequest {
|
||||||
|
r.WithNamespace = v
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDescribePolicyRequest() *DescribePolicyRequest {
|
||||||
|
return &DescribePolicyRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribePolicyRequest struct {
|
||||||
|
apps.GetRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdatePolicyRequest struct {
|
||||||
|
apps.GetRequest
|
||||||
|
CreatePolicyRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDeletePolicyRequest() *DeletePolicyRequest {
|
||||||
|
return &DeletePolicyRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeletePolicyRequest struct {
|
||||||
|
apps.GetRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
type PermissionService interface {
|
||||||
|
// 查询用户可以访问的空间
|
||||||
|
QueryNamespace(context.Context, *QueryNamespaceRequest) (*types.Set[*namespace.Namespace], error)
|
||||||
|
// 查询用户可以访问的菜单
|
||||||
|
QueryMenu(context.Context, *QueryMenuRequest) (*types.Set[*view.Menu], error)
|
||||||
|
// 查询用户可以访问的Api接口
|
||||||
|
QueryEndpoint(context.Context, *QueryEndpointRequest) (*types.Set[*endpoint.Endpoint], error)
|
||||||
|
// 校验页面权限
|
||||||
|
ValidatePagePermission(context.Context, *ValidatePagePermissionRequest) (*ValidatePagePermissionResponse, error)
|
||||||
|
// 校验接口权限
|
||||||
|
ValidateEndpointPermission(context.Context, *ValidateEndpointPermissionRequest) (*ValidateEndpointPermissionResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ValidatePagePermissionRequest struct {
|
||||||
|
UserId uint64 `json:"user_id" form:"user_id"`
|
||||||
|
NamespaceId uint64 `json:"namespace_id" form:"namespace_id"`
|
||||||
|
Path string `json:"path" form:"path"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewValidatePagePermissionResponse(req ValidatePagePermissionRequest) *ValidatePagePermissionResponse {
|
||||||
|
return &ValidatePagePermissionResponse{
|
||||||
|
ValidatePagePermissionRequest: req,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ValidatePagePermissionResponse struct {
|
||||||
|
ValidatePagePermissionRequest
|
||||||
|
HasPermission bool `json:"has_permission"`
|
||||||
|
Page *view.Page `json:"page"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewValidateEndpointPermissionRequest() *ValidateEndpointPermissionRequest {
|
||||||
|
return &ValidateEndpointPermissionRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ValidateEndpointPermissionRequest struct {
|
||||||
|
UserId uint64 `json:"user_id" form:"user_id"`
|
||||||
|
NamespaceId uint64 `json:"namespace_id" form:"namespace_id"`
|
||||||
|
Service string `json:"service" form:"service"`
|
||||||
|
Path string `json:"path" form:"path"`
|
||||||
|
Method string `json:"method" form:"method"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewValidateEndpointPermissionResponse(req ValidateEndpointPermissionRequest) *ValidateEndpointPermissionResponse {
|
||||||
|
return &ValidateEndpointPermissionResponse{
|
||||||
|
ValidateEndpointPermissionRequest: req,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ValidateEndpointPermissionResponse struct {
|
||||||
|
ValidateEndpointPermissionRequest
|
||||||
|
HasPermission bool `json:"has_permission"`
|
||||||
|
Endpoint *endpoint.Endpoint `json:"endpoint"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ValidateEndpointPermissionResponse) String() string {
|
||||||
|
return pretty.ToJSON(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQueryNamespaceRequest() *QueryNamespaceRequest {
|
||||||
|
return &QueryNamespaceRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type QueryNamespaceRequest struct {
|
||||||
|
UserId uint64 `json:"user_id"`
|
||||||
|
NamespaceId uint64 `json:"namespace_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *QueryNamespaceRequest) SetUserId(v uint64) *QueryNamespaceRequest {
|
||||||
|
r.UserId = v
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *QueryNamespaceRequest) SetNamespaceId(v uint64) *QueryNamespaceRequest {
|
||||||
|
r.NamespaceId = v
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQueryMenuRequest() *QueryMenuRequest {
|
||||||
|
return &QueryMenuRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type QueryMenuRequest struct {
|
||||||
|
UserId uint64 `json:"user_id"`
|
||||||
|
NamespaceId uint64 `json:"namespace_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQueryEndpointRequest() *QueryEndpointRequest {
|
||||||
|
return &QueryEndpointRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type QueryEndpointRequest struct {
|
||||||
|
UserId uint64 `json:"user_id"`
|
||||||
|
NamespaceId uint64 `json:"namespace_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *QueryEndpointRequest) SetUserId(v uint64) *QueryEndpointRequest {
|
||||||
|
r.UserId = v
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *QueryEndpointRequest) SetNamespaceId(v uint64) *QueryEndpointRequest {
|
||||||
|
r.NamespaceId = v
|
||||||
|
return r
|
||||||
|
}
|
80
devcloud/mcenter/apps/policy/model.go
Normal file
80
devcloud/mcenter/apps/policy/model.go
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package policy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/namespace"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/role"
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/user"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc/config/validator"
|
||||||
|
"github.com/infraboard/mcube/v2/tools/pretty"
|
||||||
|
"github.com/infraboard/modules/iam/apps"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewPolicy() *Policy {
|
||||||
|
return &Policy{
|
||||||
|
ResourceMeta: *apps.NewResourceMeta(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Policy struct {
|
||||||
|
// 基础数据
|
||||||
|
apps.ResourceMeta
|
||||||
|
// 策略定义
|
||||||
|
CreatePolicyRequest
|
||||||
|
// 关联空间
|
||||||
|
Namespace *namespace.Namespace `json:"namespace,omitempty" gorm:"-"`
|
||||||
|
// 关联用户
|
||||||
|
User *user.User `json:"user,omitempty" gorm:"-"`
|
||||||
|
// 关联角色
|
||||||
|
Role *role.Role `json:"role,omitempty" gorm:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Policy) TableName() string {
|
||||||
|
return "policy"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Policy) String() string {
|
||||||
|
return pretty.ToJSON(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCreatePolicyRequest() *CreatePolicyRequest {
|
||||||
|
return &CreatePolicyRequest{
|
||||||
|
Extras: map[string]string{},
|
||||||
|
Scope: map[string]string{},
|
||||||
|
Enabled: true,
|
||||||
|
ReadOnly: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreatePolicyRequest struct {
|
||||||
|
// 创建者
|
||||||
|
CreateBy uint64 `json:"create_by" bson:"create_by" gorm:"column:create_by;type:uint" description:"创建者" optional:"true"`
|
||||||
|
// 空间
|
||||||
|
NamespaceId *uint64 `json:"namespace_id" bson:"namespace_id" gorm:"column:namespace_id;type:varchar(200);index" description:"策略生效的空间Id" optional:"true"`
|
||||||
|
// 用户Id
|
||||||
|
UserId uint64 `json:"user_id" bson:"user_id" gorm:"column:user_id;type:uint;not null;index" validate:"required" description:"被授权的用户"`
|
||||||
|
// 角色Id
|
||||||
|
RoleId uint64 `json:"role_id" bson:"role_id" gorm:"column:role_id;type:uint;not null;index" validate:"required" description:"被关联的角色"`
|
||||||
|
// 访问范围, 需要提前定义scope, 比如环境
|
||||||
|
Scope map[string]string `json:"scope" bson:"scope" gorm:"column:scope;serializer:json;type:json" description:"数据访问的范围" optional:"true"`
|
||||||
|
// 策略过期时间
|
||||||
|
ExpiredTime *time.Time `json:"expired_time" bson:"expired_time" gorm:"column:expired_time;type:timestamp;index" description:"策略过期时间" optional:"true"`
|
||||||
|
// 只读策略, 不允许用户修改, 一般用于系统管理
|
||||||
|
ReadOnly bool `json:"read_only" bson:"read_only" gorm:"column:read_only;type:tinyint(1)" description:"只读策略, 不允许用户修改, 一般用于系统管理" optional:"true"`
|
||||||
|
// 该策略是否启用
|
||||||
|
Enabled bool `json:"enabled" bson:"enabled" gorm:"column:enabled;type:tinyint(1)" description:"该策略是否启用" optional:"true"`
|
||||||
|
// 策略标签
|
||||||
|
Label string `json:"label" gorm:"column:label;type:varchar(200);index" description:"策略标签" optional:"true"`
|
||||||
|
// 扩展信息
|
||||||
|
Extras map[string]string `json:"extras" bson:"extras" gorm:"column:extras;serializer:json;type:json" description:"扩展信息" optional:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CreatePolicyRequest) Validate() error {
|
||||||
|
return validator.Validate(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CreatePolicyRequest) SetNamespaceId(namespaceId uint64) *CreatePolicyRequest {
|
||||||
|
r.NamespaceId = &namespaceId
|
||||||
|
return r
|
||||||
|
}
|
@ -7,7 +7,11 @@ import (
|
|||||||
_ "122.51.31.227/go-course/go18/devcloud/mcenter/apps/token/api"
|
_ "122.51.31.227/go-course/go18/devcloud/mcenter/apps/token/api"
|
||||||
_ "122.51.31.227/go-course/go18/devcloud/mcenter/apps/token/impl"
|
_ "122.51.31.227/go-course/go18/devcloud/mcenter/apps/token/impl"
|
||||||
|
|
||||||
|
// 鉴权
|
||||||
_ "122.51.31.227/go-course/go18/devcloud/mcenter/apps/endpoint/impl"
|
_ "122.51.31.227/go-course/go18/devcloud/mcenter/apps/endpoint/impl"
|
||||||
|
_ "122.51.31.227/go-course/go18/devcloud/mcenter/apps/namespace/impl"
|
||||||
|
_ "122.51.31.227/go-course/go18/devcloud/mcenter/apps/policy/impl"
|
||||||
|
_ "122.51.31.227/go-course/go18/devcloud/mcenter/apps/role/impl"
|
||||||
|
|
||||||
// 颁发器
|
// 颁发器
|
||||||
_ "122.51.31.227/go-course/go18/devcloud/mcenter/apps/token/issuers"
|
_ "122.51.31.227/go-course/go18/devcloud/mcenter/apps/token/issuers"
|
||||||
|
@ -1,18 +1,42 @@
|
|||||||
<mxfile host="65bd71144e">
|
<mxfile host="65bd71144e">
|
||||||
<diagram id="prDIldifm9lRc8bqSxY8" name="第 1 页">
|
<diagram id="prDIldifm9lRc8bqSxY8" name="第 1 页">
|
||||||
<mxGraphModel dx="892" dy="476" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
<mxGraphModel dx="892" dy="439" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
<root>
|
<root>
|
||||||
<mxCell id="0"/>
|
<mxCell id="0"/>
|
||||||
<mxCell id="1" parent="0"/>
|
<mxCell id="1" parent="0"/>
|
||||||
<mxCell id="2" value="Role" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="2" value="Role" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="210" y="230" width="120" height="60" as="geometry"/>
|
<mxGeometry x="210" y="230" width="120" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="3" value="Api Permission" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="6" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="5">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="12" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="2">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="3" value="Api Permission<div>mapping</div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="390" y="120" width="120" height="60" as="geometry"/>
|
<mxGeometry x="390" y="120" width="120" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="4" value="Api Permission" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="9" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="4" target="7">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="13" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="2">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="4" value="View Permission<div>mapping</div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="390" y="340" width="120" height="60" as="geometry"/>
|
<mxGeometry x="390" y="340" width="120" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
|
<mxCell id="5" value="Endpont" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="610" y="120" width="120" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="10" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="7" target="8">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="7" value="Menu" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="610" y="340" width="120" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="8" value="Page" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="770" y="340" width="120" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
</root>
|
</root>
|
||||||
</mxGraphModel>
|
</mxGraphModel>
|
||||||
</diagram>
|
</diagram>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user