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, name string, 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(name, 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 }