add token service, sqlite driver and test

This commit is contained in:
2025-12-18 09:46:57 +02:00
parent 8836ea2673
commit cdde811e72
4 changed files with 139 additions and 0 deletions

30
internal/token/service.go Normal file
View File

@@ -0,0 +1,30 @@
package token
import (
"fmt"
"time"
)
type TokenStore interface {
revoke(tokenID string, expiresAt time.Time) error
isRevoked(tokenID string) (bool, error)
}
type TokenService struct {
store TokenStore
}
func NewTokenService(store TokenStore) (*TokenService, error) {
if store == nil {
return nil, fmt.Errorf("store is nil")
}
return &TokenService{store: store}, nil
}
func (s *TokenService) Revoke(jti string, exp time.Time) error {
return s.store.revoke(jti, exp)
}
func (s *TokenService) IsRevoked(jti string) (bool, error) {
return s.store.isRevoked(jti)
}

View File

@@ -0,0 +1,42 @@
package token
import (
"fmt"
"time"
"gorm.io/gorm"
)
type SQLiteTokenStore struct {
db *gorm.DB
}
type Token struct {
TokenID string `gorm:"primaryKey"`
Expiration time.Time `gorm:"index"`
}
func NewSQLiteTokenStore(db *gorm.DB) (*SQLiteTokenStore, error) {
if db == nil {
return nil, fmt.Errorf("db is nil")
}
return &SQLiteTokenStore{
db: db,
}, nil
}
func (s *SQLiteTokenStore) revoke(tokenID string, expiresAt time.Time) error {
return s.db.Create(&Token{
TokenID: tokenID,
Expiration: expiresAt,
}).Error
}
func (s *SQLiteTokenStore) isRevoked(tokenID string) (bool, error) {
var count int64
err := s.db.Model(&Token{}).Where("token_id = ?", tokenID).Count(&count).Error
if err != nil {
return false, err
}
return count > 0, nil
}

View File

@@ -0,0 +1,67 @@
package token
import (
"os"
"path/filepath"
"testing"
"time"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
func setupTestDB(t *testing.T) *gorm.DB {
t.Helper()
dbPath := filepath.Join("testdata", "tokens.db")
_ = os.Remove(dbPath)
db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{})
if err != nil {
t.Fatalf("failed to open db: %v", err)
}
if err := db.AutoMigrate(&Token{}); err != nil {
t.Fatalf("failed to migrate: %v", err)
}
return db
}
func TestSQLiteTokenStore_RevokeAndCheck(t *testing.T) {
db := setupTestDB(t)
store, err := NewSQLiteTokenStore(db)
if err != nil {
t.Fatalf("failed to create store: %v", err)
}
service, err := NewTokenService(store)
if err != nil {
t.Fatalf("failed to create service: %v", err)
}
jti := "test-token-123"
exp := time.Now().Add(time.Hour)
revoked, err := service.IsRevoked(jti)
if err != nil {
t.Fatalf("isRevoked failed: %v", err)
}
if revoked {
t.Fatalf("token should NOT be revoked initially")
}
if err := service.Revoke(jti, exp); err != nil {
t.Fatalf("revoke failed: %v", err)
}
revoked, err = service.IsRevoked(jti)
if err != nil {
t.Fatalf("isRevoked failed: %v", err)
}
if !revoked {
t.Fatalf("token should be revoked")
}
}

BIN
internal/token/testdata/tokens.db vendored Normal file

Binary file not shown.