package handlers import ( "fmt" "net/http" "os" "time" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" "golang.org/x/crypto/bcrypt" "fishfish/database" "fishfish/models" ) func Login(c *gin.Context) { jwtKey := []byte(os.Getenv("JWT_SECRET")) var input struct { Username string `json:"username"` Password string `json:"password"` } if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Неверный ввод"}) return } var user models.User err := database.DB.Where("username = ?", input.Username).First(&user).Error if err != nil { fmt.Printf("[LOGIN ERROR] Пользователь %s не найден в БД: Ошибка") c.JSON(http.StatusUnauthorized, gin.H{"error": "Неверный логин или пароль"}) } passErr := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(input.Password)) if passErr != nil { fmt.Printf("[LOGIN ERROR] Пароль для пароля %s не совпал с хешем в базе данных") c.JSON(http.StatusUnauthorized, gin.H{"error": "Неверный логин или пароль"}) return } token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "user_id": user.ID, "role": user.Role, "exp": time.Now().Add(time.Hour * 24).Unix(), }) tokenString, _ := token.SignedString(jwtKey) c.JSON(http.StatusOK, gin.H{"token": tokenString, "user": gin.H{ "id": user.ID, "first_name": user.FirstName, "last_name": user.LastName, "phone": user.Phone, "role": user.Role, }}) } func Register(c *gin.Context) { var input struct { Username string `json:"username" binding:"required"` Password string `json:"password" binding:"required,min=8"` FirstName string `json:"first_name" binding:"required"` LastName string `json:"last_name" binding:"required"` Phone string `json:"phone"` } if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Ошибка валидации ", "details": err.Error()}) return } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(input.Password), bcrypt.DefaultCost) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Ошибка при шифровании пароля"}) return } // 3. Создаем объект пользователя user := models.User{ Username: input.Username, Password: string(hashedPassword), FirstName: input.FirstName, LastName: input.LastName, Phone: input.Phone, Role: "customer", } // 4. Сохраняем в базу через GORM if err := database.DB.Create(&user).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Ошибка при регистрации пользователя", "details": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Пользователь успешно зарегистрирован"}) } func RegisterAdmin(c *gin.Context) { var input struct { Username string `json:"username" binding:"required"` Password string `json:"password" binding:"required,min=8"` FirstName string `json:"first_name" binding:"required"` LastName string `json:"last_name" binding:"required"` Phone string `json:"phone"` Role string `json:"role"` } if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Ошибка валидации ", "details": err.Error()}) return } if input.Role != "Рабочий" && input.Role != "Админ" { c.JSON(http.StatusForbidden, gin.H{"error": "Недопустимая роль"}) return } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(input.Password), bcrypt.DefaultCost) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Ошибка при шифровании пароля"}) return } user := models.User{ Username: input.Username, Password: string(hashedPassword), FirstName: input.FirstName, LastName: input.LastName, Phone: input.Phone, Role: input.Role, } if err := database.DB.Create(&user).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Ошибка при регистрации пользователя", "details": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Пользователь успешно зарегистрирован"}) } func UpdateProfile(c *gin.Context) { var input models.UpdateUserInput if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } userID := c.MustGet("user_id") if err := database.DB.Model(&models.User{}).Where("id = ?", userID).Updates(models.User{ FirstName: input.FirstName, LastName: input.LastName, Phone: input.Phone, Role: input.Role, }).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Не удалось обновить данные", "details": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Данные успешно обновлены"}) }