auth.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package handlers
  2. import (
  3. "net/http"
  4. "git.linuxforward.com/byop/byop-engine/auth"
  5. "git.linuxforward.com/byop/byop-engine/dbstore"
  6. "github.com/gin-gonic/gin"
  7. "golang.org/x/crypto/bcrypt"
  8. )
  9. // AuthHandler handles authentication-related operations
  10. type AuthHandler struct {
  11. authService auth.Service
  12. userStore *dbstore.UserStore
  13. }
  14. // NewAuthHandler creates a new AuthHandler
  15. func NewAuthHandler(authService auth.Service, userStore *dbstore.UserStore) *AuthHandler {
  16. return &AuthHandler{
  17. authService: authService,
  18. userStore: userStore,
  19. }
  20. }
  21. // Login handles user authentication
  22. func (h *AuthHandler) Login(c *gin.Context) {
  23. var credentials struct {
  24. Email string `json:"email"`
  25. Password string `json:"password"`
  26. }
  27. if err := c.ShouldBindJSON(&credentials); err != nil {
  28. c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
  29. return
  30. }
  31. // Validate user credentials
  32. user, err := h.userStore.GetUserByEmail(credentials.Email)
  33. if err != nil {
  34. c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch user"})
  35. return
  36. }
  37. if user == nil {
  38. c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid email"})
  39. return
  40. }
  41. // Check password using bcrypt
  42. if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(credentials.Password)); err != nil {
  43. c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid password"})
  44. return
  45. }
  46. // Generate token for authentication
  47. tokenResp, err := h.authService.GenerateToken(c, credentials.Email, string(user.Role))
  48. if err != nil {
  49. c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"})
  50. return
  51. }
  52. // Construct the new response format
  53. response := map[string]interface{}{
  54. "token": tokenResp.AccessToken,
  55. "refreshToken": tokenResp.RefreshToken,
  56. "user": map[string]interface{}{
  57. "id": user.ID,
  58. "username": user.Username,
  59. "email": user.Email,
  60. "role": user.Role,
  61. "preferences": map[string]interface{}{
  62. "theme": user.Preferences.Theme,
  63. "notifications": user.Preferences.Notifications,
  64. },
  65. },
  66. }
  67. c.JSON(http.StatusOK, response)
  68. }
  69. // RefreshToken handles token refresh
  70. func (h *AuthHandler) RefreshToken(c *gin.Context) {
  71. var refreshRequest struct {
  72. RefreshToken string `json:"refresh_token" binding:"required"`
  73. }
  74. if err := c.ShouldBindJSON(&refreshRequest); err != nil {
  75. c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
  76. return
  77. }
  78. // Validate refresh token and generate new access token
  79. resp, err := h.authService.RefreshToken(c, refreshRequest.RefreshToken)
  80. if err != nil {
  81. c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid or expired refresh token"})
  82. return
  83. }
  84. c.JSON(http.StatusOK, resp)
  85. }
  86. // Logout handles user logout
  87. func (h *AuthHandler) Logout(c *gin.Context) {
  88. // TODO: Implement logout logic
  89. c.Status(http.StatusNoContent)
  90. }