// Voir factory/doc/adr/20260509-telegram-gateway-auth.md package main import ( "strconv" "strings" ) // Allowlist filters incoming Telegram updates by `from.id`. Empty raw value // means "open to all" (back-compat with Phase 1). When non-empty, only IDs // in the set are allowed through ; everything else is silently dropped // upstream of the auth gate (so unknown users don't even know the bot exists). type Allowlist struct { ids map[int64]struct{} open bool } // NewAllowlist parses a comma-separated list of int64 user IDs. Whitespace // around items and empty items are ignored. Invalid items are skipped (with // the caller responsible for logging if it cares). func NewAllowlist(raw string) Allowlist { raw = strings.TrimSpace(raw) if raw == "" { return Allowlist{open: true} } ids := make(map[int64]struct{}) for _, s := range strings.Split(raw, ",") { s = strings.TrimSpace(s) if s == "" { continue } id, err := strconv.ParseInt(s, 10, 64) if err != nil { continue } ids[id] = struct{}{} } if len(ids) == 0 { // CSV provided but every entry was unparseable → treat as closed for safety. return Allowlist{ids: ids, open: false} } return Allowlist{ids: ids, open: false} } func (a Allowlist) IsAllowed(userID int64) bool { if a.open { return true } _, ok := a.ids[userID] return ok } func (a Allowlist) Open() bool { return a.open } func (a Allowlist) Size() int { return len(a.ids) }