Files
Memoh/internal/command/access.go
T
Acbox d46269de89 feat(command): improve slash command UX (#361)
Make slash commands easier to navigate in chat by splitting help into levels, compacting list output, and surfacing current selections for model, search, memory, and browser settings. Also route /status to the active conversation session and add an access inspector so users can understand their current command and ACL context.
2026-04-13 12:37:12 +08:00

79 lines
2.1 KiB
Go

package command
import (
"fmt"
"strings"
"github.com/memohai/memoh/internal/acl"
)
func (h *Handler) buildAccessGroup() *CommandGroup {
g := newCommandGroup("access", "Inspect identity and permission context")
g.DefaultAction = "show"
g.Register(SubCommand{
Name: "show",
Usage: "show - Show current identity, write access, and chat ACL context",
Handler: func(cc CommandContext) (string, error) {
writeAccess := "no"
if cc.Role == "owner" {
writeAccess = "yes"
}
pairs := []kv{
{"Channel Identity", fallbackValue(cc.ChannelIdentityID)},
{"Linked User", fallbackValue(cc.UserID)},
{"Bot Role", fallbackValue(cc.Role)},
{"Write Commands", writeAccess},
{"Channel", fallbackValue(cc.ChannelType)},
{"Conversation Type", fallbackValue(cc.ConversationType)},
{"Conversation ID", fallbackValue(cc.ConversationID)},
{"Thread ID", fallbackValue(cc.ThreadID)},
}
if strings.TrimSpace(cc.RouteID) != "" {
pairs = append(pairs, kv{"Route ID", cc.RouteID})
}
if strings.TrimSpace(cc.SessionID) != "" {
pairs = append(pairs, kv{"Session ID", cc.SessionID})
}
aclStatus := "unavailable"
if h.aclEvaluator != nil && strings.TrimSpace(cc.ChannelType) != "" {
allowed, err := h.aclEvaluator.Evaluate(cc.Ctx, acl.EvaluateRequest{
BotID: cc.BotID,
ChannelIdentityID: cc.ChannelIdentityID,
ChannelType: cc.ChannelType,
SourceScope: acl.SourceScope{
ConversationType: cc.ConversationType,
ConversationID: cc.ConversationID,
ThreadID: cc.ThreadID,
},
})
switch {
case err != nil:
aclStatus = "error: " + err.Error()
case allowed:
aclStatus = "allow"
default:
aclStatus = "deny"
}
}
pairs = append(pairs, kv{"Chat ACL", aclStatus})
return formatKV(pairs), nil
},
})
return g
}
func fallbackValue(value string) string {
value = strings.TrimSpace(value)
if value == "" {
return "(none)"
}
return value
}
func formatChangedValue(label, before, after string) string {
return fmt.Sprintf("%s: %s -> %s", label, fallbackValue(before), fallbackValue(after))
}