sessions/internal/service/api_key.go

79 lines
1.9 KiB
Go

package service
import (
"context"
"errors"
"fmt"
"gitea.dwysokinski.me/twhelp/sessions/internal/domain"
"github.com/google/uuid"
)
//counterfeiter:generate -o internal/mock/api_key_repository.gen.go . APIKeyRepository
type APIKeyRepository interface {
Create(ctx context.Context, params domain.CreateAPIKeyParams) (domain.APIKey, error)
Get(ctx context.Context, key string) (domain.APIKey, error)
}
//counterfeiter:generate -o internal/mock/user_getter.gen.go . UserGetter
type UserGetter interface {
Get(ctx context.Context, id int64) (domain.User, error)
}
type APIKey struct {
repo APIKeyRepository
userSvc UserGetter
}
func NewAPIKey(repo APIKeyRepository, userSvc UserGetter) *APIKey {
return &APIKey{repo: repo, userSvc: userSvc}
}
func (a *APIKey) Create(ctx context.Context, userID int64) (domain.APIKey, error) {
user, err := a.userSvc.Get(ctx, userID)
if err != nil {
if errors.Is(err, domain.UserNotFoundError{ID: userID}) {
return domain.APIKey{}, domain.UserDoesNotExistError{ID: userID}
}
return domain.APIKey{}, fmt.Errorf("UserService.Get: %w", err)
}
key, err := uuid.NewRandom()
if err != nil {
return domain.APIKey{}, fmt.Errorf("couldn't generate api key: %w", err)
}
params, err := domain.NewCreateAPIKeyParams(key.String(), user.ID)
if err != nil {
return domain.APIKey{}, err
}
apiKey, err := a.repo.Create(ctx, params)
if err != nil {
return domain.APIKey{}, fmt.Errorf("APIKeyRepository.Create: %w", err)
}
return apiKey, nil
}
func (a *APIKey) Verify(ctx context.Context, keyStr string) (domain.User, error) {
key, err := uuid.Parse(keyStr)
if err != nil {
return domain.User{}, domain.APIKeyNotFoundError{
Key: keyStr,
}
}
ak, err := a.repo.Get(ctx, key.String())
if err != nil {
return domain.User{}, fmt.Errorf("APIKeyRepository.Get: %w", err)
}
user, err := a.userSvc.Get(ctx, ak.UserID)
if err != nil {
return domain.User{}, fmt.Errorf("UserService.Get: %w", err)
}
return user, nil
}