106 lines
2.7 KiB
Go
106 lines
2.7 KiB
Go
package fleet
|
||
|
||
import "fmt"
|
||
|
||
// Clearance levels gate remote operator actions (L0–L4).
|
||
const (
|
||
ClearanceL0 = 0 // view-only
|
||
ClearanceL1 = 1 // status queries, fleet list
|
||
ClearanceL2 = 2 // pause/resume mining
|
||
ClearanceL3 = 3 // reboot, screenshot
|
||
ClearanceL4 = 4 // shell exec, court verdicts, crucible batch
|
||
)
|
||
|
||
// Action names used by API and dashboard.
|
||
const (
|
||
ActionView = "view"
|
||
ActionStatus = "status"
|
||
ActionPause = "pause"
|
||
ActionResume = "resume"
|
||
ActionReboot = "reboot"
|
||
ActionScreenshot = "screenshot"
|
||
ActionShell = "shell"
|
||
ActionCourt = "court"
|
||
ActionCrucible = "crucible"
|
||
)
|
||
|
||
// minClearance maps each action to the minimum operator clearance required.
|
||
var minClearance = map[string]int{
|
||
ActionView: ClearanceL0,
|
||
ActionStatus: ClearanceL1,
|
||
ActionPause: ClearanceL2,
|
||
ActionResume: ClearanceL2,
|
||
ActionReboot: ClearanceL3,
|
||
ActionScreenshot: ClearanceL3,
|
||
ActionShell: ClearanceL4,
|
||
ActionCourt: ClearanceL4,
|
||
ActionCrucible: ClearanceL4,
|
||
}
|
||
|
||
// RequiredClearance returns the minimum clearance for an action.
|
||
func RequiredClearance(action string) (int, bool) {
|
||
level, ok := minClearance[action]
|
||
return level, ok
|
||
}
|
||
|
||
// RequiredClearanceOrZero returns required level or 0 if unknown.
|
||
func RequiredClearanceOrZero(action string) int {
|
||
level, _ := minClearance[action]
|
||
return level
|
||
}
|
||
|
||
// CanPerform checks whether operator clearance satisfies the action gate.
|
||
func CanPerform(operatorClearance int, action string) bool {
|
||
required, ok := minClearance[action]
|
||
if !ok {
|
||
return false
|
||
}
|
||
return operatorClearance >= required
|
||
}
|
||
|
||
// ClearanceError describes a denied action.
|
||
type ClearanceError struct {
|
||
Action string
|
||
Required int
|
||
OperatorClearance int
|
||
}
|
||
|
||
func (e ClearanceError) Error() string {
|
||
return fmt.Sprintf("action %q requires clearance L%d (operator has L%d)",
|
||
e.Action, e.Required, e.OperatorClearance)
|
||
}
|
||
|
||
// CheckAction returns ClearanceError when the operator lacks clearance.
|
||
func CheckAction(operatorClearance int, action string) error {
|
||
required, ok := minClearance[action]
|
||
if !ok {
|
||
return fmt.Errorf("unknown action %q", action)
|
||
}
|
||
if operatorClearance < required {
|
||
return ClearanceError{
|
||
Action: action,
|
||
Required: required,
|
||
OperatorClearance: operatorClearance,
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// ClearanceLabel returns a human-readable label for a level.
|
||
func ClearanceLabel(level int) string {
|
||
switch level {
|
||
case ClearanceL0:
|
||
return "L0 View"
|
||
case ClearanceL1:
|
||
return "L1 Status"
|
||
case ClearanceL2:
|
||
return "L2 Control"
|
||
case ClearanceL3:
|
||
return "L3 Host Ops"
|
||
case ClearanceL4:
|
||
return "L4 Root"
|
||
default:
|
||
return fmt.Sprintf("L%d", level)
|
||
}
|
||
}
|