From 2f403be1236a514bc23fafba9b072683e2c69161 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 19 Feb 2024 09:52:55 +0100 Subject: [PATCH] Cleanup expired tokens and codes from DB Closes: https://todo.sr.ht/~emersion/sinwon/4 --- db.go | 21 +++++++++++++++++++++ entity.go | 4 +++- main.go | 17 +++++++++++++++++ diff --git a/db.go b/db.go index 9198db2582880a8b5a2c1562c69bbb9ebe656f75..19b39fecd70e62a8764522ac94ee6b76fca8a1b0 100644 --- a/db.go +++ b/db.go @@ -5,6 +5,7 @@ "context" "database/sql" _ "embed" "fmt" + "time" _ "github.com/mattn/go-sqlite3" ) @@ -167,6 +168,26 @@ } var authCode AuthCode err = scanRow(&authCode, rows) return &authCode, err +} + +func (db *DB) Maintain(ctx context.Context) error { + _, err := db.db.ExecContext(ctx, ` + DELETE FROM AccessToken + WHERE timediff('now', expires_at) > 0 + `) + if err != nil { + return err + } + + _, err = db.db.ExecContext(ctx, ` + DELETE FROM AuthCode + WHERE timediff(?, created_at) > 0 + `, time.Now().Add(-authCodeExpiration)) + if err != nil { + return err + } + + return nil } func scan(e entity, rows *sql.Rows) error { diff --git a/entity.go b/entity.go index 2958f9b7c433741ae3992289b24f8719a955c4c6..219ed6b0df2ba388f9a7d440891a17ef89de437c 100644 --- a/entity.go +++ b/entity.go @@ -15,6 +15,8 @@ "golang.org/x/crypto/bcrypt" ) +const authCodeExpiration = 10 * time.Minute + type entity interface { columns() map[string]interface{} } @@ -210,7 +212,7 @@ } } func (code *AuthCode) VerifySecret(secret string) bool { - return verifyHash(code.Hash, secret) && verifyExpiration(code.CreatedAt.Add(10*time.Minute)) + return verifyHash(code.Hash, secret) && verifyExpiration(code.CreatedAt.Add(authCodeExpiration)) } func UnmarshalSecret[T entity](s string) (id ID[T], secret string, err error) { diff --git a/main.go b/main.go index ff4ff48af3f448e145907c0f6db49a1e937eaced..fa22cc8900fc27c0133a302a3afac8eb408a9b2e 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ "html/template" "log" "net" "net/http" + "time" "github.com/go-chi/chi/v5" ) @@ -58,6 +59,8 @@ mux.HandleFunc("/user/{id}", updateUser) mux.HandleFunc("/authorize", authorize) mux.Post("/token", exchangeToken) + go maintainDBLoop(db) + server := http.Server{ Addr: listenAddr, Handler: loginTokenMiddleware(mux), @@ -75,3 +78,17 @@ func httpError(w http.ResponseWriter, err error) { log.Print(err) http.Error(w, "Internal server error", http.StatusInternalServerError) } + +func maintainDBLoop(db *DB) { + ticker := time.NewTicker(15 * time.Minute) + defer ticker.Stop() + + for range ticker.C { + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, 30*time.Second) + if err := db.Maintain(ctx); err != nil { + log.Printf("Failed to perform database maintenance: %v", err) + } + cancel() + } +} -- 2.48.1