6bed393c12
Backend Tests / backend-unit-test (push) Has been cancelled
Backend Tests / benchmark-test (push) Has been cancelled
CI@main / Node.js v22 (ubuntu-latest) (push) Has been cancelled
Thrift Syntax Validation / validate-thrift (push) Has been cancelled
License Check / License Check (push) Has been cancelled
125 lines
3.3 KiB
Go
125 lines
3.3 KiB
Go
/*
|
|
* Copyright 2025 coze-dev 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 permission
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
)
|
|
|
|
type ResourcePermissionRequest struct {
|
|
ResourceType ResourceType
|
|
ResourceIDs []int64
|
|
Action Action
|
|
OperatorID int64
|
|
IsDraft *bool
|
|
}
|
|
|
|
type ResourceInfo struct {
|
|
ID int64
|
|
CreatorID int64
|
|
SpaceID *int64
|
|
}
|
|
|
|
type ResourceQueryer interface {
|
|
QueryResourceInfo(ctx context.Context, resourceIDs []int64, isDraft *bool) ([]*ResourceInfo, error)
|
|
|
|
GetResourceType() ResourceType
|
|
}
|
|
|
|
type AuthzChecker struct {
|
|
resourceQueryers map[ResourceType]ResourceQueryer
|
|
}
|
|
|
|
func NewAuthzChecker() *AuthzChecker {
|
|
checker := &AuthzChecker{
|
|
resourceQueryers: make(map[ResourceType]ResourceQueryer),
|
|
}
|
|
|
|
checker.registerResourceQueryers()
|
|
|
|
return checker
|
|
}
|
|
|
|
func (c *AuthzChecker) registerResourceQueryers() {
|
|
|
|
c.resourceQueryers[ResourceTypeWorkspace] = NewWorkspaceResourceQueryer()
|
|
|
|
c.resourceQueryers[ResourceTypeAgent] = NewAgentResourceQueryer()
|
|
|
|
c.resourceQueryers[ResourceTypePlugin] = NewPluginResourceQueryer()
|
|
|
|
c.resourceQueryers[ResourceTypeWorkflow] = NewWorkflowResourceQueryer()
|
|
|
|
c.resourceQueryers[ResourceTypeKnowledge] = NewKnowledgeResourceQueryer()
|
|
c.resourceQueryers[ResourceTypeKnowledgeSlice] = NewKnowledgeSliceResourceQueryer()
|
|
c.resourceQueryers[ResourceTypeKnowledgeDocument] = NewKnowledgeDocumentResourceQueryer()
|
|
|
|
c.resourceQueryers[ResourceTypeDatabase] = NewDatabaseResourceQueryer()
|
|
|
|
c.resourceQueryers[ResourceTypeApp] = NewAppResourceQueryer()
|
|
|
|
}
|
|
|
|
func (c *AuthzChecker) CheckResourcePermission(ctx context.Context, req *ResourcePermissionRequest) (bool, error) {
|
|
|
|
queryeer, exists := c.resourceQueryers[req.ResourceType]
|
|
if !exists {
|
|
return false, fmt.Errorf("unsupported resource type: %d", req.ResourceType)
|
|
}
|
|
|
|
resourceInfos, err := queryeer.QueryResourceInfo(ctx, req.ResourceIDs, req.IsDraft)
|
|
if err != nil {
|
|
return false, fmt.Errorf("failed to query resource info: %w", err)
|
|
}
|
|
|
|
for _, resourceInfo := range resourceInfos {
|
|
allowed := c.checkSingleResourcePermission(req.OperatorID, resourceInfo, req.Action)
|
|
if !allowed {
|
|
return false, nil
|
|
}
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
func (c *AuthzChecker) checkSingleResourcePermission(operatorID int64, resourceInfo *ResourceInfo, action Action) bool {
|
|
|
|
if operatorID == resourceInfo.CreatorID {
|
|
return true
|
|
}
|
|
|
|
switch action {
|
|
case ActionRead:
|
|
return c.checkReadPermission(operatorID, resourceInfo)
|
|
case ActionWrite:
|
|
return c.checkWritePermission(operatorID, resourceInfo)
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func (c *AuthzChecker) checkReadPermission(operatorID int64, resourceInfo *ResourceInfo) bool {
|
|
|
|
return operatorID == resourceInfo.CreatorID
|
|
}
|
|
|
|
func (c *AuthzChecker) checkWritePermission(operatorID int64, resourceInfo *ResourceInfo) bool {
|
|
|
|
return operatorID == resourceInfo.CreatorID
|
|
}
|