9501751792
三轮审查修复(60+ 项),相对远端 main(b536672)的关键变更:
- 安全: 数据面 SSRF 拨号防护(防 DNS rebinding)/上游凭据剥离/登录防枚举
与锁定态统一/可信代理(X-Forwarded-For)限流加固/会话版本失效机制/
撤销即时传播/弱密钥拒绝启动/脱敏字节级重写(保签名契约)
- 业务逻辑: 裸 body 上传 panic/bootstrap 审计管线卡死/定价通配符优先级/
全局工具可见性/调度器停机补跑/TOTP 挑战令牌消费顺序/熔断探针语义/
>4MB 响应 token 计量/管理员重置密码作废会话 等
- 前端: 新 logo(语枢 AI 网关主题)/Provider 凭据异常警示/删除入口/
后端错误消息透传/localStorage 敏感数据收敛
- 部署: CREDENTIAL_MASTER_KEY 持久化与弱值拒绝/Provider DELETE 接口/
nginx 安全头/worker 内存限制
- 新增迁移 000029(key_hash 索引)/000030(usage_daily 币种维度)
143 lines
5.2 KiB
Go
143 lines
5.2 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"
|
|
PermissionFileRead = "file:read"
|
|
PermissionFileManage = "file:manage"
|
|
PermissionInboxRead = "inbox:read"
|
|
PermissionInboxManage = "inbox:manage"
|
|
PermissionScheduledTaskRead = "scheduled_task:read"
|
|
PermissionScheduledTaskManage = "scheduled_task:manage"
|
|
PermissionTraceRead = "trace:read"
|
|
PermissionAgentNodeRead = "agent_node:read"
|
|
PermissionAgentNodeManage = "agent_node: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,
|
|
PermissionFileRead, PermissionFileManage,
|
|
PermissionInboxRead, PermissionInboxManage,
|
|
PermissionScheduledTaskRead, PermissionScheduledTaskManage,
|
|
PermissionTraceRead,
|
|
PermissionAgentNodeRead, PermissionAgentNodeManage,
|
|
},
|
|
"auditor": {PermissionProviderRead, PermissionAPIKeyRead, PermissionAuditRead, PermissionUsageRead, PermissionOutboxRead, PermissionContentPolicyRead, PermissionPricingRead, PermissionPromptRead, PermissionKnowledgeRead, PermissionToolRead, PermissionApplicationRead, PermissionNotificationRead, PermissionMCPServerRead, PermissionSkillRead, PermissionDigitalEmployeeRead, PermissionMarketplaceRead, PermissionFileRead, PermissionInboxRead, PermissionScheduledTaskRead, PermissionTraceRead, PermissionAgentNodeRead},
|
|
"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)
|
|
}
|