5759c1862e
M0-M7 已完成:核心网关(身份/RBAC/TOTP/OIDC/SAML/Provider/配额/路由/内容策略/审计/定价)+ 资源市场(MCP/Skills/数字员工)。 含 22 个 PostgreSQL 迁移、管理端/门户端前端源码、OpenAPI 契约、部署 compose。 Co-Authored-By: Claude <noreply@anthropic.com>
129 lines
4.4 KiB
Go
129 lines
4.4 KiB
Go
package identity
|
|
|
|
import (
|
|
"errors"
|
|
"sort"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
ErrNotFound = errors.New("identity not found")
|
|
ErrUnavailable = errors.New("identity service unavailable")
|
|
)
|
|
|
|
type Kind string
|
|
|
|
const (
|
|
KindAdmin Kind = "admin"
|
|
KindPortal Kind = "portal"
|
|
)
|
|
|
|
type Account struct {
|
|
ID string
|
|
Kind Kind
|
|
Login string
|
|
DisplayName string
|
|
Role string
|
|
Permissions []string
|
|
PasswordHash string
|
|
AuthSource string
|
|
Active bool
|
|
FailedLogins int
|
|
LockedUntil *time.Time
|
|
TOTPEnabled bool
|
|
EncryptedTOTPSecret []byte
|
|
TOTPKekVersion *int
|
|
TOTPLastStep *int64
|
|
TOTPBackupCodes []byte
|
|
DepartmentID *string
|
|
DepartmentName string
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
const (
|
|
PermissionIdentityManage = "identity:manage"
|
|
PermissionProviderRead = "provider:read"
|
|
PermissionProviderManage = "provider:manage"
|
|
PermissionAPIKeyRead = "api_key:read"
|
|
PermissionAPIKeyManage = "api_key:manage"
|
|
PermissionAuditRead = "audit:read"
|
|
PermissionUsageRead = "usage:read"
|
|
PermissionOutboxRead = "outbox:read"
|
|
PermissionOutboxManage = "outbox:manage"
|
|
PermissionContentPolicyRead = "content_policy:read"
|
|
PermissionContentPolicyManage = "content_policy:manage"
|
|
PermissionPricingRead = "pricing:read"
|
|
PermissionPricingManage = "pricing:manage"
|
|
PermissionPromptRead = "prompt:read"
|
|
PermissionPromptManage = "prompt:manage"
|
|
PermissionKnowledgeRead = "knowledge:read"
|
|
PermissionKnowledgeManage = "knowledge:manage"
|
|
PermissionToolRead = "tool:read"
|
|
PermissionToolManage = "tool:manage"
|
|
PermissionApplicationRead = "application:read"
|
|
PermissionApplicationManage = "application:manage"
|
|
PermissionNotificationRead = "notification:read"
|
|
PermissionNotificationManage = "notification:manage"
|
|
PermissionMCPServerRead = "mcp_server:read"
|
|
PermissionMCPServerManage = "mcp_server:manage"
|
|
PermissionSkillRead = "skill:read"
|
|
PermissionSkillManage = "skill:manage"
|
|
PermissionDigitalEmployeeRead = "digital_employee:read"
|
|
PermissionDigitalEmployeeManage = "digital_employee:manage"
|
|
PermissionMarketplaceRead = "marketplace:read"
|
|
PermissionMarketplaceManage = "marketplace:manage"
|
|
)
|
|
|
|
var rolePermissions = map[string][]string{
|
|
"superadmin": {"*"},
|
|
"operator": {
|
|
PermissionProviderRead, PermissionProviderManage,
|
|
PermissionAPIKeyRead, PermissionAPIKeyManage,
|
|
PermissionUsageRead,
|
|
PermissionOutboxRead, PermissionOutboxManage,
|
|
PermissionContentPolicyRead, PermissionContentPolicyManage,
|
|
PermissionPricingRead, PermissionPricingManage,
|
|
PermissionPromptRead, PermissionPromptManage,
|
|
PermissionKnowledgeRead, PermissionKnowledgeManage,
|
|
PermissionToolRead, PermissionToolManage,
|
|
PermissionApplicationRead, PermissionApplicationManage,
|
|
PermissionNotificationRead, PermissionNotificationManage,
|
|
PermissionMCPServerRead, PermissionMCPServerManage,
|
|
PermissionSkillRead, PermissionSkillManage,
|
|
PermissionDigitalEmployeeRead, PermissionDigitalEmployeeManage,
|
|
PermissionMarketplaceRead, PermissionMarketplaceManage,
|
|
},
|
|
"auditor": {PermissionProviderRead, PermissionAPIKeyRead, PermissionAuditRead, PermissionUsageRead, PermissionOutboxRead, PermissionContentPolicyRead, PermissionPricingRead, PermissionPromptRead, PermissionKnowledgeRead, PermissionToolRead, PermissionApplicationRead, PermissionNotificationRead, PermissionMCPServerRead, PermissionSkillRead, PermissionDigitalEmployeeRead, PermissionMarketplaceRead},
|
|
"member": {},
|
|
}
|
|
|
|
func EffectivePermissions(account Account) []string {
|
|
seen := make(map[string]struct{})
|
|
result := make([]string, 0, len(account.Permissions)+4)
|
|
for _, permissions := range [][]string{rolePermissions[account.Role], account.Permissions} {
|
|
for _, permission := range permissions {
|
|
if _, exists := seen[permission]; exists {
|
|
continue
|
|
}
|
|
seen[permission] = struct{}{}
|
|
result = append(result, permission)
|
|
}
|
|
}
|
|
sort.Strings(result)
|
|
return result
|
|
}
|
|
|
|
func HasPermission(account Account, required string) bool {
|
|
for _, permission := range EffectivePermissions(account) {
|
|
if permission == "*" || permission == required {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (a Account) Locked(now time.Time) bool {
|
|
return a.LockedUntil != nil && a.LockedUntil.After(now)
|
|
}
|