87 lines
1.5 KiB
Go
87 lines
1.5 KiB
Go
package memory
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"time"
|
|
|
|
"source.toby3d.me/toby3d/auth/internal/domain"
|
|
"source.toby3d.me/toby3d/auth/internal/ticket"
|
|
)
|
|
|
|
type (
|
|
Ticket struct {
|
|
CreatedAt time.Time
|
|
domain.Ticket
|
|
}
|
|
|
|
memoryTicketRepository struct {
|
|
config domain.Config
|
|
mutex *sync.RWMutex
|
|
tickets map[string]Ticket
|
|
}
|
|
)
|
|
|
|
func NewMemoryTicketRepository(config domain.Config) ticket.Repository {
|
|
return &memoryTicketRepository{
|
|
config: config,
|
|
mutex: new(sync.RWMutex),
|
|
tickets: make(map[string]Ticket),
|
|
}
|
|
}
|
|
|
|
func (repo *memoryTicketRepository) Create(_ context.Context, t domain.Ticket) error {
|
|
repo.mutex.Lock()
|
|
defer repo.mutex.Unlock()
|
|
|
|
repo.tickets[t.Ticket] = Ticket{
|
|
CreatedAt: time.Now().UTC(),
|
|
Ticket: t,
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repo *memoryTicketRepository) GetAndDelete(_ context.Context, t string) (*domain.Ticket, error) {
|
|
repo.mutex.RLock()
|
|
|
|
out, ok := repo.tickets[t]
|
|
if !ok {
|
|
repo.mutex.RUnlock()
|
|
|
|
return nil, ticket.ErrNotExist
|
|
}
|
|
|
|
repo.mutex.RUnlock()
|
|
repo.mutex.Lock()
|
|
delete(repo.tickets, t)
|
|
repo.mutex.Unlock()
|
|
|
|
return &out.Ticket, nil
|
|
}
|
|
|
|
func (repo *memoryTicketRepository) GC() {
|
|
ticker := time.NewTicker(time.Second)
|
|
defer ticker.Stop()
|
|
|
|
for ts := range ticker.C {
|
|
ts := ts.UTC()
|
|
|
|
repo.mutex.RLock()
|
|
|
|
for _, t := range repo.tickets {
|
|
if t.CreatedAt.Add(repo.config.Code.Expiry).After(ts) {
|
|
continue
|
|
}
|
|
|
|
repo.mutex.RUnlock()
|
|
repo.mutex.Lock()
|
|
delete(repo.tickets, t.Ticket.Ticket)
|
|
repo.mutex.Unlock()
|
|
repo.mutex.RLock()
|
|
}
|
|
|
|
repo.mutex.RUnlock()
|
|
}
|
|
}
|