PHP Classes

File: backend/go/handler/auth.go

Recommend this page to a friend!
  Packages of Everton C B Junior   Igreja Aberta   backend/go/handler/auth.go   Download  
File: backend/go/handler/auth.go
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Igreja Aberta
Church activity management application
Author: By
Last change:
Date: 14 days ago
Size: 9,095 bytes
 

Contents

Class file image Download
package handler import ( "net/http" "strings" "time" "github.com/ebarrosjr/igreja-aberta/backend/go/database" "github.com/ebarrosjr/igreja-aberta/backend/go/middleware" "github.com/gin-gonic/gin" ) type loginRequest struct { Email string `json:"email" binding:"required,email"` Password string `json:"password" binding:"required"` } type refreshTokenRequest struct { RefreshToken string `json:"refreshToken" binding:"required"` } type forgotPasswordRequest struct { Email string `json:"email" binding:"required,email"` } type resetPasswordRequest struct { Token string `json:"token" binding:"required"` Password string `json:"password" binding:"required,min=8"` ConfirmPassword string `json:"confirmPassword" binding:"required"` } type logoutRequest struct { RefreshToken string `json:"refreshToken" binding:"required"` } func LoginHandler(c *gin.Context) { var request loginRequest if err := c.ShouldBindJSON(&request); err != nil { c.JSON(http.StatusBadRequest, JSONResponse(http.StatusBadRequest, gin.H{}, "Dados de login invalidos")) return } email := strings.ToLower(strings.TrimSpace(request.Email)) user, err := database.GetUserByEmail(email) if err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao buscar usuario")) return } if user == nil || !database.IsActiveStatus(user.Status) || !database.VerifyPassword(request.Password, user.Password) { c.JSON(http.StatusUnauthorized, JSONResponse(http.StatusUnauthorized, gin.H{}, "Email ou senha invalidos")) return } authResponse, err := issueAuthTokens(user) if err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao gerar autenticacao")) return } now := time.Now().UTC() user.LastLoginAt = &now user.UpdatedAt = now if err := database.DB.Save(user).Error; err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao atualizar usuario")) return } c.JSON(http.StatusOK, JSONResponse(http.StatusOK, gin.H{ "user": newUserResponse(user), "token": authResponse.Token, "expires_at": authResponse.ExpiresAt, "refresh_token": authResponse.RefreshToken, "refresh_token_expires_at": authResponse.RefreshTokenExpiresAt, }, "Logado com sucesso")) } func RefreshTokenHandler(c *gin.Context) { var request refreshTokenRequest if err := c.ShouldBindJSON(&request); err != nil { c.JSON(http.StatusBadRequest, JSONResponse(http.StatusBadRequest, gin.H{}, "Dados de refresh token invalidos")) return } refreshToken := strings.TrimSpace(request.RefreshToken) tokenRecord, err := database.GetValidRefreshToken(refreshToken) if err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao validar refresh token")) return } if tokenRecord == nil { c.JSON(http.StatusUnauthorized, JSONResponse(http.StatusUnauthorized, gin.H{}, "Refresh token invalido")) return } user, err := database.GetUserByID(uint(tokenRecord.UserID)) if err != nil || user == nil || !database.IsActiveStatus(user.Status) { c.JSON(http.StatusUnauthorized, JSONResponse(http.StatusUnauthorized, gin.H{}, "Usuario do refresh token nao encontrado")) return } if err := database.RevokeRefreshToken(tokenRecord); err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao atualizar refresh token")) return } authResponse, err := issueAuthTokens(user) if err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao gerar autenticacao")) return } c.JSON(http.StatusOK, JSONResponse(http.StatusOK, gin.H{ "user": newUserResponse(user), "token": authResponse.Token, "expires_at": authResponse.ExpiresAt, "refresh_token": authResponse.RefreshToken, "refresh_token_expires_at": authResponse.RefreshTokenExpiresAt, }, "Token renovado com sucesso")) } func ForgotPasswordHandler(c *gin.Context) { var request forgotPasswordRequest if err := c.ShouldBindJSON(&request); err != nil { c.JSON(http.StatusBadRequest, JSONResponse(http.StatusBadRequest, gin.H{}, "Dados de recuperacao invalidos")) return } email := strings.ToLower(strings.TrimSpace(request.Email)) user, err := database.GetUserByEmail(email) if err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao processar recuperacao de senha")) return } responseData := gin.H{} if user != nil && database.IsActiveStatus(user.Status) { resetToken, _, err := database.CreatePasswordResetToken(user.Id) if err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao processar recuperacao de senha")) return } // Em ambiente real, este token deve ser enviado por email e nao retornado pela API. responseData["token"] = resetToken } c.JSON(http.StatusOK, JSONResponse(http.StatusOK, responseData, "Se o email existir, enviaremos as instrucoes para redefinicao de senha")) } func ResetPasswordHandler(c *gin.Context) { var request resetPasswordRequest if err := c.ShouldBindJSON(&request); err != nil { c.JSON(http.StatusBadRequest, JSONResponse(http.StatusBadRequest, gin.H{}, "Dados de redefinicao invalidos")) return } if request.Password != request.ConfirmPassword { c.JSON(http.StatusBadRequest, JSONResponse(http.StatusBadRequest, gin.H{}, "As senhas informadas nao conferem")) return } resetToken := strings.TrimSpace(request.Token) tokenRecord, err := database.GetValidPasswordResetToken(resetToken) if err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao validar token de redefinicao")) return } if tokenRecord == nil { c.JSON(http.StatusUnauthorized, JSONResponse(http.StatusUnauthorized, gin.H{}, "Token de redefinicao invalido")) return } user, err := database.GetUserByID(uint(tokenRecord.UserID)) if err != nil || user == nil { c.JSON(http.StatusUnauthorized, JSONResponse(http.StatusUnauthorized, gin.H{}, "Usuario do token de redefinicao nao encontrado")) return } hashedPassword, err := database.HashPassword(request.Password) if err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao redefinir senha")) return } now := time.Now().UTC() user.Password = hashedPassword user.UpdatedAt = now if user.Status == "" { user.Status = database.UserStatusActive } if err := database.DB.Save(user).Error; err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao redefinir senha")) return } if err := database.MarkPasswordResetTokenAsUsed(tokenRecord); err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao atualizar token de redefinicao")) return } if err := database.RevokeAllUserRefreshTokens(user.Id); err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao invalidar sessoes do usuario")) return } c.JSON(http.StatusOK, JSONResponse(http.StatusOK, gin.H{ "user": newUserResponse(user), }, "Senha redefinida com sucesso")) } func LogoutHandler(c *gin.Context) { var request logoutRequest if err := c.ShouldBindJSON(&request); err != nil { c.JSON(http.StatusBadRequest, JSONResponse(http.StatusBadRequest, gin.H{}, "Dados de logout invalidos")) return } authenticatedUser, ok := middleware.GetAuthenticatedUser(c) if !ok || authenticatedUser == nil { c.JSON(http.StatusUnauthorized, JSONResponse(http.StatusUnauthorized, gin.H{}, "Usuario autenticado nao encontrado")) return } refreshToken := strings.TrimSpace(request.RefreshToken) tokenRecord, err := database.GetValidRefreshTokenByUserID(refreshToken, authenticatedUser.Id) if err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao processar logout")) return } if tokenRecord == nil { c.JSON(http.StatusUnauthorized, JSONResponse(http.StatusUnauthorized, gin.H{}, "Refresh token invalido")) return } if err := database.RevokeRefreshToken(tokenRecord); err != nil { c.JSON(http.StatusInternalServerError, JSONResponse(http.StatusInternalServerError, gin.H{}, "Erro ao processar logout")) return } c.JSON(http.StatusOK, JSONResponse(http.StatusOK, gin.H{}, "Logout realizado com sucesso")) } func issueAuthTokens(user *database.User) (*database.AuthResponse, error) { authResponse, err := database.CreateAuthResponse(user) if err != nil { return nil, err } if err := database.CreateRefreshToken(user.Id, authResponse.RefreshToken, authResponse.RefreshTokenExpiresAt); err != nil { return nil, err } return authResponse, nil }