added auth service to go backend
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"actatempus_backend/internal/application/services/dto"
|
||||
"actatempus_backend/internal/domain/app_error"
|
||||
"actatempus_backend/internal/domain/entities"
|
||||
"actatempus_backend/internal/domain/repository"
|
||||
"actatempus_backend/internal/infrastructure/data"
|
||||
"net/http"
|
||||
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// AuthService handles authentication-related HTTP requests.
|
||||
type AuthService struct {
|
||||
authRepository repository.AuthRepository
|
||||
userRepository repository.UserRepository
|
||||
}
|
||||
|
||||
// NewAuthService creates a new instance of AuthService.
|
||||
func NewAuthService(authRepo repository.AuthRepository,
|
||||
userRepository repository.UserRepository) *AuthService {
|
||||
return &AuthService{
|
||||
authRepository: authRepo,
|
||||
userRepository: userRepository,
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterRoutes registers the authentication-related routes.
|
||||
func (s *AuthService) RegisterRoutes(router *gin.RouterGroup) {
|
||||
router.POST("/login", s.Login)
|
||||
router.POST("/validate", s.Validate)
|
||||
router.POST("/revoke", s.Revoke)
|
||||
}
|
||||
|
||||
// Login handles user login and token generation.
|
||||
func (s *AuthService) Login(c *gin.Context) {
|
||||
var loginRequest dto.LoginRequestDTO
|
||||
if err := c.ShouldBindJSON(&loginRequest); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
F.Pipe4(
|
||||
loginRequest.Email,
|
||||
s.userRepository.FindByEmail(c.Request.Context()),
|
||||
E.Chain[error](
|
||||
func(user entities.User) E.Either[error, entities.User] {
|
||||
hashedPassword := data.GenerateSecureHash(loginRequest.Password)
|
||||
if user.Password != hashedPassword {
|
||||
return E.Left[entities.User, error](app_error.NewAuthError("Invalid password"))
|
||||
}
|
||||
return E.Right[error](user)
|
||||
},
|
||||
),
|
||||
E.Chain(func(user entities.User) E.Either[error, dto.TokenResponseDTO] {
|
||||
return F.Pipe2(
|
||||
user.ID,
|
||||
s.authRepository.GenerateToken(c.Request.Context()),
|
||||
E.Map[error](func(token string) dto.TokenResponseDTO {
|
||||
return dto.TokenResponseDTO{
|
||||
Token: token,
|
||||
UserID: user.ID,
|
||||
}
|
||||
}),
|
||||
)
|
||||
}),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[dto.TokenResponseDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// Validate handles token validation.
|
||||
func (s *AuthService) Validate(c *gin.Context) {
|
||||
var tokenRequest dto.TokenRequestDTO
|
||||
if err := c.ShouldBindJSON(&tokenRequest); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
F.Pipe2(
|
||||
s.authRepository.ValidateToken(c.Request.Context())(tokenRequest.Token),
|
||||
E.Map[error](func(userID string) dto.TokenResponseDTO {
|
||||
return dto.TokenResponseDTO{
|
||||
Token: tokenRequest.Token,
|
||||
UserID: userID,
|
||||
}
|
||||
}),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[dto.TokenResponseDTO](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// Revoke handles token revocation.
|
||||
func (s *AuthService) Revoke(c *gin.Context) {
|
||||
var tokenRequest dto.TokenRequestDTO
|
||||
if err := c.ShouldBindJSON(&tokenRequest); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
F.Pipe2(
|
||||
s.authRepository.RevokeToken(c.Request.Context())(tokenRequest.Token),
|
||||
E.Map[error](func(userID string) gin.H {
|
||||
return gin.H{"message": "Token revoked", "user_id": userID}
|
||||
}),
|
||||
E.Fold(
|
||||
HandleError(c),
|
||||
HandleSuccess[gin.H](c, http.StatusOK),
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dto
|
||||
|
||||
// TokenResponseDTO represents the response for a token generation or validation.
|
||||
type TokenResponseDTO struct {
|
||||
Token string `json:"token"`
|
||||
UserID string `json:"user_id"`
|
||||
}
|
||||
|
||||
// TokenRequestDTO represents a request for operations involving tokens.
|
||||
type TokenRequestDTO struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// LoginRequestDTO represents the login request.
|
||||
type LoginRequestDTO struct {
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
Reference in New Issue
Block a user