feat: service/controller prototype
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"easywish/internal/models"
|
||||
"easywish/internal/services"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -28,9 +30,28 @@ func RegistrationComplete(c *gin.Context) {
|
||||
// @Tags Auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body models.LoginRequest true "desc"
|
||||
// @Success 200 {object} models.LoginResponse "desc"
|
||||
// @Router /auth/login [post]
|
||||
func Login(c *gin.Context) {
|
||||
c.Status(http.StatusNotImplemented)
|
||||
|
||||
var request models.LoginRequest
|
||||
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
c.Status(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
auths := services.NewAuthService()
|
||||
|
||||
result, err := auths.Login(request)
|
||||
|
||||
if err != nil {
|
||||
c.Status(http.StatusTeapot)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusFound, result)
|
||||
}
|
||||
|
||||
// @Summary Receive new tokens via refresh token
|
||||
|
||||
@@ -15,7 +15,7 @@ type HealthStatus struct {
|
||||
// @Tags Service
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} HealthStatus "desc"
|
||||
// @Success 200 {object} HealthStatus "Says whether it's healthy or not"
|
||||
// @Router /service/health [get]
|
||||
func HealthCheck(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"healthy": true})
|
||||
|
||||
@@ -546,12 +546,12 @@ WHERE
|
||||
users.verified IS TRUE AND -- Verified
|
||||
users.deleted IS FALSE AND -- Not deleted
|
||||
banned.user_id IS NULL AND -- Not banned
|
||||
linfo.password_hash = crypt($2, linfo.password_hash)
|
||||
linfo.password_hash = crypt($2::text, linfo.password_hash)
|
||||
`
|
||||
|
||||
type GetUserByLoginCredentialsParams struct {
|
||||
Username string
|
||||
Crypt string
|
||||
Password string
|
||||
}
|
||||
|
||||
type GetUserByLoginCredentialsRow struct {
|
||||
@@ -562,7 +562,7 @@ type GetUserByLoginCredentialsRow struct {
|
||||
}
|
||||
|
||||
func (q *Queries) GetUserByLoginCredentials(ctx context.Context, arg GetUserByLoginCredentialsParams) (GetUserByLoginCredentialsRow, error) {
|
||||
row := q.db.QueryRow(ctx, getUserByLoginCredentials, arg.Username, arg.Crypt)
|
||||
row := q.db.QueryRow(ctx, getUserByLoginCredentials, arg.Username, arg.Password)
|
||||
var i GetUserByLoginCredentialsRow
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
|
||||
9
backend/internal/errors/auth.go
Normal file
9
backend/internal/errors/auth.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUnauthorized = errors.New("User is not authorized")
|
||||
)
|
||||
11
backend/internal/errors/general.go
Normal file
11
backend/internal/errors/general.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNotImplemented = errors.New("Feature is not implemented")
|
||||
ErrBadRequest = errors.New("Bad request")
|
||||
)
|
||||
|
||||
24
backend/internal/models/auth.go
Normal file
24
backend/internal/models/auth.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package models
|
||||
|
||||
type Tokens struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
||||
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
TOTP *string `json:"totp"`
|
||||
}
|
||||
|
||||
type LoginResponse struct {
|
||||
Tokens
|
||||
}
|
||||
|
||||
type RefreshRequest struct {
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
||||
|
||||
type RefreshResponse struct {
|
||||
Tokens
|
||||
}
|
||||
50
backend/internal/services/auth.go
Normal file
50
backend/internal/services/auth.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"easywish/internal/database"
|
||||
"easywish/internal/errors"
|
||||
errs "easywish/internal/errors"
|
||||
"easywish/internal/models"
|
||||
"easywish/internal/utils"
|
||||
)
|
||||
|
||||
type AuthService interface {
|
||||
Login(request models.LoginRequest) (*models.LoginResponse, error)
|
||||
Refresh(request models.RefreshRequest) (*models.RefreshResponse, error)
|
||||
}
|
||||
|
||||
type authServiceImpl struct {
|
||||
|
||||
}
|
||||
|
||||
func NewAuthService() AuthService {
|
||||
return &authServiceImpl{}
|
||||
}
|
||||
|
||||
func (a *authServiceImpl) Login(request models.LoginRequest) (*models.LoginResponse, error) {
|
||||
conn, ctx, err := utils.GetDbConn()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close(ctx)
|
||||
|
||||
queries := database.New(conn)
|
||||
|
||||
user, err := queries.GetUserByLoginCredentials(ctx, database.GetUserByLoginCredentialsParams{
|
||||
Username: request.Username,
|
||||
Password: request.Password,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, errs.ErrUnauthorized
|
||||
}
|
||||
|
||||
accessToken, refreshToken, err := utils.GenerateTokens(user.Username)
|
||||
|
||||
return &models.LoginResponse{Tokens: models.Tokens{AccessToken: accessToken, RefreshToken: refreshToken}}, nil
|
||||
}
|
||||
|
||||
|
||||
func (a *authServiceImpl) Refresh(request models.RefreshRequest) (*models.RefreshResponse, error) {
|
||||
return nil, errors.ErrNotImplemented
|
||||
}
|
||||
18
backend/internal/utils/db.go
Normal file
18
backend/internal/utils/db.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"easywish/config"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
func GetDbConn() (*pgx.Conn, context.Context, error) {
|
||||
ctx := context.Background()
|
||||
conn, err := pgx.Connect(ctx, config.GetConfig().DatabaseUrl)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return conn, ctx, nil
|
||||
}
|
||||
Reference in New Issue
Block a user