package elevate import ( "fmt" "net" "sync/atomic" "time" ) // Resolution is the outcome of a pending request. type Resolution int const ( ResolvePending Resolution = iota ResolveApprove ResolveDeny ResolvePersist // approve + add to session policy ResolveTimeout ) func (r Resolution) String() string { switch r { case ResolveApprove: return "approve" case ResolveDeny: return "deny" case ResolvePersist: return "persist" case ResolveTimeout: return "timeout" default: return "pending" } } // Request represents a pending elevation request. type Request struct { ID string Cmd string Cwd string Env map[string]string SessionID string // ollie session that made the request (from SO_PEERCRED mapping) Sudo bool // requires sudo credential after approval CreatedAt time.Time // Resolution channel — exactly one value sent when resolved. resolved chan Resolution conn net.Conn // the elevate client connection (held open until resolved) } // Resolved returns the channel that receives the resolution. func (r *Request) Resolved() <-chan Resolution { return r.resolved } // Summary returns a human-readable description for notifications. func (r *Request) Summary() string { sess := r.SessionID if sess == "" { sess = "unknown" } return fmt.Sprintf("[%s] %s\ncwd: %s", sess, r.Cmd, r.Cwd) } var requestCounter atomic.Uint64 func nextRequestID() string { n := requestCounter.Add(1) return fmt.Sprintf("%d", n) }