internal/store/pushtokens.go

bd5cf5d7d1f34fa780660fd7562b9ffd9746ee27
gitbay/internal/store/pushtokens.go history · blame · raw

52 lines · 1514 bytes

 1package store
 2
 3import (
 4	"database/sql"
 5	"errors"
 6	"time"
 7)
 8
 9// PushToken is the receive-pack a hook request speaks for.
10type PushToken struct {
11	RepoID int64
12	UserID int64
13	Scope  string
14}
15
16// pushTokenTTL bounds a row whose receive-pack died before deleting it.
17const pushTokenTTL = 24 * time.Hour
18
19// CreatePushToken records a token for one receive-pack and returns it.
20func (s *Store) CreatePushToken(repoID, userID int64, scope string) (string, error) {
21	token, hash, err := NewToken()
22	if err != nil {
23		return "", err
24	}
25	_, err = s.DB.Exec(
26		"INSERT INTO push_tokens (token_hash, repo_id, user_id, scope, expires_at) VALUES (?, ?, ?, ?, ?)",
27		hash, repoID, userID, scope, fmtTime(time.Now().Add(pushTokenTTL)))
28	if err != nil {
29		return "", err
30	}
31	return token, nil
32}
33
34// PushTokenByHash looks up a live token by its stored hash. ErrNotFound
35// covers both an absent row and one that has expired.
36func (s *Store) PushTokenByHash(hash string) (PushToken, error) {
37	var t PushToken
38	err := s.DB.QueryRow(
39		"SELECT repo_id, user_id, scope FROM push_tokens WHERE token_hash = ? AND expires_at > ?",
40		hash, fmtTime(time.Now())).Scan(&t.RepoID, &t.UserID, &t.Scope)
41	if errors.Is(err, sql.ErrNoRows) {
42		return PushToken{}, ErrNotFound
43	}
44	return t, err
45}
46
47// DeletePushToken removes a token by its raw value, once its receive-pack
48// is done with it.
49func (s *Store) DeletePushToken(token string) error {
50	_, err := s.DB.Exec("DELETE FROM push_tokens WHERE token_hash = ?", HashToken(token))
51	return err
52}