package users import ( "context" "fmt" "github.com/eko/gocache/cache" "go.uber.org/zap" ) type Service struct { logger *zap.Logger cache *cache.Cache repository Repository passwordHasher PasswordHasher } func NewService(l *zap.Logger, ur Repository, c *cache.Cache) *Service { return &Service{ logger: l, repository: ur, cache: c, passwordHasher: NewPlainTextPasswordHasher(), } } func (s *Service) Create(email string, password string) (int, error) { createUser, err := NewCreateUser(email, password, s.passwordHasher) if err != nil { return -1, err } var userId int userId, err = s.repository.Create(context.Background(), createUser) if err != nil { s.logger.Warn("Could not create user in service") return 0, err } return userId, nil } func (s *Service) Authenticate(ctx context.Context, email string, password string) (*User, error) { loadFunc := func(key interface{}) (interface{}, error) { s.logger.Debug("getting user from cache", zap.String("email", email)) return s.repository.GetByEmail(ctx, email, s.passwordHasher.HashPassword(password)) } get, err := cache.NewLoadable(loadFunc, s.cache).Get(fmt.Sprintf("user_email_%s", email)) if err != nil { return nil, err } return get.(*User), nil }