access_token.go

 1package backend
 2
 3import (
 4	"context"
 5	"errors"
 6	"time"
 7
 8	"github.com/charmbracelet/soft-serve/pkg/db"
 9	"github.com/charmbracelet/soft-serve/pkg/proto"
10	"github.com/charmbracelet/soft-serve/pkg/utils"
11)
12
13// CreateAccessToken creates an access token for user.
14func (b *Backend) CreateAccessToken(ctx context.Context, user proto.User, name string, expiresAt time.Time) (string, error) {
15	token := GenerateToken()
16	tokenHash := HashToken(token)
17	name = utils.Sanitize(name)
18
19	if err := b.db.TransactionContext(ctx, func(tx *db.Tx) error {
20		_, err := b.store.CreateAccessToken(ctx, tx, name, user.ID(), tokenHash, expiresAt)
21		if err != nil {
22			return db.WrapError(err)
23		}
24
25		return nil
26	}); err != nil {
27		return "", err
28	}
29
30	return token, nil
31}
32
33// DeleteAccessToken deletes an access token for a user.
34func (b *Backend) DeleteAccessToken(ctx context.Context, user proto.User, id int64) error {
35	err := b.db.TransactionContext(ctx, func(tx *db.Tx) error {
36		_, err := b.store.GetAccessToken(ctx, tx, id)
37		if err != nil {
38			return db.WrapError(err)
39		}
40
41		if err := b.store.DeleteAccessTokenForUser(ctx, tx, user.ID(), id); err != nil {
42			return db.WrapError(err)
43		}
44		return nil
45	})
46	if err != nil {
47		if errors.Is(err, db.ErrRecordNotFound) {
48			return proto.ErrTokenNotFound
49		}
50		return err
51	}
52
53	return nil
54}
55
56// ListAccessTokens lists access tokens for a user.
57func (b *Backend) ListAccessTokens(ctx context.Context, user proto.User) ([]proto.AccessToken, error) {
58	accessTokens, err := b.store.GetAccessTokensByUserID(ctx, b.db, user.ID())
59	if err != nil {
60		return nil, db.WrapError(err)
61	}
62
63	var tokens []proto.AccessToken
64	for _, t := range accessTokens {
65		token := proto.AccessToken{
66			ID:        t.ID,
67			Name:      t.Name,
68			TokenHash: t.Token,
69			UserID:    t.UserID,
70			CreatedAt: t.CreatedAt,
71		}
72		if t.ExpiresAt.Valid {
73			token.ExpiresAt = t.ExpiresAt.Time
74		}
75
76		tokens = append(tokens, token)
77	}
78
79	return tokens, nil
80}