Commands for everything a dashboard can do
- /music skip, pause, resume, stop, repeat, remove, move (DJ role) - /config view, clear, toggletwitch, streamers, beta-features (server owner) - /slvl status, remove-reward; /moderation bans, timeouts; /security history - /beta is now the bot owner's DM-only command: set, off, servers, remove-server, status - betasettings service and repo methods, with integration tests Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
1 parent
acdb5ead35
commit
132a2cd986
26 files changed
+1062
-65
No files matched your search
@@ -509,11 +509,12 @@ func (r *Repo) DeleteLockdown(ctx context.Context, guildID, channelID int64) err
|
||||
// ---- Events ----
|
||||
|
||||
type Event struct {
|
||||
GuildID int64
|
||||
Kind string
|
||||
ActorID int64
|
||||
TargetID int64
|
||||
Detail string
|
||||
GuildID int64
|
||||
Kind string
|
||||
ActorID int64
|
||||
TargetID int64
|
||||
Detail string
|
||||
CreatedAt time.Time // set when read
|
||||
}
|
||||
|
||||
// Event kinds.
|
||||
@@ -716,3 +717,26 @@ func (r *Repo) GuildsDueForSnapshot(ctx context.Context, maxAge time.Duration) (
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
// ListEvents returns a server's most recent security events, newest first.
|
||||
func (r *Repo) ListEvents(ctx context.Context, guildID int64, limit int) ([]Event, error) {
|
||||
if limit < 1 || limit > 100 {
|
||||
limit = 20
|
||||
}
|
||||
rows, err := r.db.QueryContext(ctx, `
|
||||
SELECT kind, COALESCE(actor_id, 0), COALESCE(target_id, 0), detail, created_at
|
||||
FROM security_events WHERE guild_id = $1 ORDER BY id DESC LIMIT $2`, guildID, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var out []Event
|
||||
for rows.Next() {
|
||||
e := Event{GuildID: guildID}
|
||||
if err := rows.Scan(&e.Kind, &e.ActorID, &e.TargetID, &e.Detail, &e.CreatedAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, e)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
@@ -229,3 +229,27 @@ func TestRaidsSnapshotsAndHeatSettings(t *testing.T) {
|
||||
t.Error("with a zero max age every anti-nuke guild is due")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListEvents(t *testing.T) {
|
||||
r, g := testRepo(t)
|
||||
ctx := context.Background()
|
||||
for _, kind := range []string{"settings", "raid_started", "quarantine"} {
|
||||
if err := r.AddEvent(ctx, Event{GuildID: g, Kind: kind, ActorID: 5, Detail: "d"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := r.AddEvent(ctx, Event{GuildID: g + 1, Kind: "other server"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { _, _ = r.db.Exec(`DELETE FROM security_events WHERE guild_id = $1`, g+1) })
|
||||
got, err := r.ListEvents(ctx, g, 2)
|
||||
if err != nil || len(got) != 2 || got[0].Kind != "quarantine" || got[1].Kind != "raid_started" {
|
||||
t.Fatalf("newest first, limited: %+v %v", got, err)
|
||||
}
|
||||
if got[0].CreatedAt.IsZero() || got[0].ActorID != 5 || got[0].TargetID != 0 {
|
||||
t.Errorf("fields: %+v", got[0])
|
||||
}
|
||||
if all, _ := r.ListEvents(ctx, g, 0); len(all) != 3 {
|
||||
t.Errorf("only this server's events: %v", all)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user