Files
CyberStrikeAI/internal/security/rbac.go
T
2026-07-10 16:51:06 +08:00

113 lines
4.9 KiB
Go

package security
import (
"crypto/sha256"
"crypto/subtle"
"encoding/hex"
"fmt"
"strings"
"golang.org/x/crypto/bcrypt"
)
// Platform permissions use module:action naming. They are intentionally
// separate from AI testing roles under roles/.
var PermissionCatalog = map[string]string{
"auth:self": "Manage own session and password",
"dashboard:read": "View dashboard summaries",
"chat:read": "View conversations",
"chat:write": "Create and update conversations",
"chat:delete": "Delete conversations and turns",
"agent:execute": "Run AI agents and workflows",
"hitl:read": "View HITL queues and logs",
"hitl:write": "Approve, dismiss, and configure HITL",
"tasks:read": "View task queues",
"tasks:write": "Create and run task queues",
"tasks:delete": "Delete task queues",
"project:read": "View projects and project facts",
"project:write": "Create and update projects and facts",
"project:delete": "Delete projects and facts",
"vulnerability:read": "View vulnerabilities",
"vulnerability:write": "Create and update vulnerabilities",
"vulnerability:delete": "Delete vulnerabilities",
"webshell:read": "View WebShell connections",
"webshell:write": "Manage and use WebShell connections",
"webshell:delete": "Delete WebShell connections",
"c2:read": "View C2 listeners, sessions, tasks, events, and profiles",
"c2:write": "Operate C2 listeners, sessions, tasks, payloads, files, and profiles",
"c2:delete": "Delete C2 objects",
"mcp:read": "View MCP status and external MCP configuration",
"mcp:write": "Manage external MCP servers and invoke MCP endpoint",
"knowledge:read": "View knowledge base and retrieval logs",
"knowledge:write": "Create, update, index, and scan knowledge base",
"knowledge:delete": "Delete knowledge items and retrieval logs",
"skills:read": "View skills and skill stats",
"skills:write": "Create and update skills",
"skills:delete": "Delete skills and stats",
"agents:read": "View markdown agents",
"agents:write": "Create and update markdown agents",
"agents:delete": "Delete markdown agents",
"roles:read": "View AI testing roles",
"roles:write": "Create and update AI testing roles",
"roles:delete": "Delete AI testing roles",
"workflow:read": "View workflow definitions and runs",
"workflow:write": "Create, update, validate, run, and resume workflows",
"workflow:delete": "Delete workflows",
"config:read": "View system configuration",
"config:write": "Update and apply system configuration",
"terminal:execute": "Run terminal commands",
"audit:read": "View and export audit logs",
"audit:delete": "Delete audit logs",
"rbac:read": "View users, platform roles, permissions, and assignments",
"rbac:write": "Manage users, platform roles, permissions, and assignments",
"notification:read": "View notifications",
"notification:write": "Mark notifications as read",
"robot:read": "View robot binding status",
"robot:write": "Manage robot bindings and test robot callbacks",
"files:read": "View chat uploads",
"files:write": "Upload, edit, and rename chat files",
"files:delete": "Delete chat files",
"attackchain:read": "View attack chains",
"attackchain:write": "Regenerate attack chains",
"fofa:execute": "Run FOFA searches and query parsing",
"openapi:read": "Read OpenAPI aggregation results",
"group:read": "View conversation groups",
"group:write": "Create and update conversation groups",
"group:delete": "Delete conversation groups",
"monitor:read": "View execution monitor",
"monitor:write": "Cancel monitor executions",
"monitor:delete": "Delete monitor executions",
}
func HashPassword(password string) (string, error) {
password = strings.TrimSpace(password)
if password == "" {
return "", fmt.Errorf("password is empty")
}
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return "", err
}
return string(hash), nil
}
func VerifyPasswordHash(password, encoded string) bool {
if strings.HasPrefix(encoded, "$2a$") || strings.HasPrefix(encoded, "$2b$") || strings.HasPrefix(encoded, "$2y$") {
return bcrypt.CompareHashAndPassword([]byte(encoded), []byte(strings.TrimSpace(password))) == nil
}
parts := strings.Split(encoded, "$")
if len(parts) != 3 || parts[0] != "sha256" {
return false
}
salt, err := hex.DecodeString(parts[1])
if err != nil {
return false
}
expected, err := hex.DecodeString(parts[2])
if err != nil {
return false
}
sum := sha256.Sum256(append(salt, []byte(strings.TrimSpace(password))...))
return subtle.ConstantTimeCompare(sum[:], expected) == 1
}