Files
softplayer-backend/internal/controllers/accounts.go
Nikolai Rodionov 14ad203f63
All checks were successful
ci/woodpecker/push/build Pipeline was successful
Structure code a wee bit better
Signed-off-by: Nikolai Rodionov <allanger@badhouseplants.net>
2026-05-17 20:07:31 +02:00

104 lines
2.6 KiB
Go

package controllers
import (
"context"
"database/sql"
"errors"
"time"
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/helpers/hash"
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/helpers/logger"
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/repository"
"github.com/google/uuid"
"github.com/redis/go-redis/v9"
)
var (
ErrEmailUsed = errors.New("email is already used")
ErrUserNotFound = errors.New("user not found")
ErrWrongPassword = errors.New("wrong password")
)
type AccountController struct {
DB *sql.DB
Redis *redis.Client
DevMode bool
HashCost int16
AccessTokenTTL time.Duration
RefreshTokenTTL time.Duration
JWTSecret []byte
}
type JWT struct {
RefreshToken string
AccessToken string
}
type AccountParams struct{}
type AccountData struct {
Password string
Email string
UUID string
}
// Create a new account
func (c *AccountController) Create(ctx context.Context, data *AccountData) (string, error) {
log := logger.FromContext(ctx).WithValues("email", data.Email)
log.V(2).Info("Creating a user")
data.UUID = uuid.New().String()
passwordHash, err := hash.HashPassword(data.Password, int(c.HashCost))
if err != nil {
log.Error(err, "Couldn't crate the password hash")
return "", ErrServerError
}
queryData := &repository.AccountData{
UUID: data.UUID,
Email: data.Email,
PasswordHash: passwordHash,
}
if err := repository.CreateAccount(ctx, c.DB, queryData); err != nil {
if errors.Is(err, repository.ErrAlreadyExists) {
return "", ErrEmailUsed
}
log.Error(err, "Couldn't create a user")
return "", ErrServerError
}
return data.UUID, nil
}
// Login into an existing account (check password and email)
func (c *AccountController) Login(ctx context.Context, email, password string) (string, error) {
log := logger.FromContext(ctx).WithValues("email", email)
log.V(2).Info("Trying to verify user login")
passwordHash, err := repository.GetPasswordHashForEmail(ctx, c.DB, email)
if err != nil {
if errors.Is(err, repository.ErrNotFound) {
return "", ErrUserNotFound
}
log.Error(err, "Couldn't get the password hash")
return "", ErrServerError
}
if err := hash.CheckPasswordHash(password, passwordHash); err != nil {
return "", ErrWrongPassword
}
uuid, err := repository.GetUUIDForEmail(ctx, c.DB, email)
if err != nil {
if errors.Is(err, repository.ErrNotFound) {
return "", ErrUserNotFound
}
log.Error(err, "Couldn't get tha password hash")
return "", ErrServerError
}
return uuid, nil
}