From c1d5e472f2eb89ad960e3dfbb9954d3a3d735374 Mon Sep 17 00:00:00 2001 From: William Perron Date: Sun, 17 Dec 2023 16:43:35 -0500 Subject: [PATCH] add last flush to /info command --- audit_log.go | 14 +++++++------- cmd/themis-server/main.go | 22 +++++++++++++++++++++- errors.go | 1 + store_test.go | 8 ++++---- 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/audit_log.go b/audit_log.go index 63b9eb2..2abce19 100644 --- a/audit_log.go +++ b/audit_log.go @@ -81,10 +81,10 @@ func (s *Store) Audit(ev *AuditableEvent) { } type AuditEvent struct { - id int - userId string - eventType EventType - timestamp time.Time + Id int + UserId string + EventType EventType + Timestamp time.Time } func (s *Store) LastOf(ctx context.Context, t EventType) (AuditEvent, error) { @@ -98,15 +98,15 @@ func (s *Store) LastOf(ctx context.Context, t EventType) (AuditEvent, error) { ev := AuditEvent{} var rawEventType string - err = row.Scan(&ev.id, &ev.userId, &rawEventType, &ev.timestamp) + err = row.Scan(&ev.Id, &ev.UserId, &rawEventType, &ev.Timestamp) if err == sql.ErrNoRows { - return AuditEvent{}, errors.New("no rows found") + return AuditEvent{}, ErrNever } if err != nil { return AuditEvent{}, fmt.Errorf("failed to scan row: %w", err) } - ev.eventType, err = EventTypeFromString(rawEventType) + ev.EventType, err = EventTypeFromString(rawEventType) if err != nil { return AuditEvent{}, fmt.Errorf("failed to parse event type %s: %w", rawEventType, err) } diff --git a/cmd/themis-server/main.go b/cmd/themis-server/main.go index 8380606..b7438cc 100644 --- a/cmd/themis-server/main.go +++ b/cmd/themis-server/main.go @@ -231,10 +231,30 @@ func main() { } } + ev, err := store.LastOf(ctx, themis.EventFlush) + var lastFlush string + if err != nil { + if err != themis.ErrNever { + log.Error().Err(err).Msg("failed get last flush event") + err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseChannelMessageWithSource, + Data: &discordgo.InteractionResponseData{ + Content: "Oops, something went wrong! :(", + }, + }) + if err != nil { + log.Error().Err(err).Msg("failed to respond to interaction") + } + } + lastFlush = "never" + } else { + lastFlush = ev.Timestamp.Format(time.DateTime) + } + err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseChannelMessageWithSource, Data: &discordgo.InteractionResponseData{ - Content: fmt.Sprintf("Server has been up for %s, has %d claims from %d unique players", uptime, claimCount, uniquePlayers), + Content: fmt.Sprintf("Server has been up for %s, has %d claims from %d unique players.\nThe last time claims were flushed was: %s.", uptime, claimCount, uniquePlayers, lastFlush), }, }) if err != nil { diff --git a/errors.go b/errors.go index 3e906d8..f1319fa 100644 --- a/errors.go +++ b/errors.go @@ -6,6 +6,7 @@ import ( ) var ErrNoSuchClaim = errors.New("no such claim") +var ErrNever = errors.New("event never occured") type ErrConflict struct { Conflicts []Conflict diff --git a/store_test.go b/store_test.go index be92bbd..2316a13 100644 --- a/store_test.go +++ b/store_test.go @@ -99,8 +99,8 @@ func TestStore_Claim(t *testing.T) { ae, err := store.LastOf(context.TODO(), EventClaim) require.NoError(t, err) - assert.Greater(t, ae.id, lastAudit) - lastAudit = ae.id + assert.Greater(t, ae.Id, lastAudit) + lastAudit = ae.Id }) } } @@ -173,7 +173,7 @@ func TestDeleteClaim(t *testing.T) { ae, err := store.LastOf(context.TODO(), EventUnclaim) require.NoError(t, err) - last := ae.id + last := ae.Id err = store.DeleteClaim(context.TODO(), barId, "000000000000000001") assert.Error(t, err) @@ -181,7 +181,7 @@ func TestDeleteClaim(t *testing.T) { ae, err = store.LastOf(context.TODO(), EventUnclaim) require.NoError(t, err) - assert.Equal(t, last, ae.id) // no new audit log was added + assert.Equal(t, last, ae.Id) // no new audit log was added } func TestDescribeClaim(t *testing.T) {