From 183e4da7f4dc0ccc5ee0fcb1c6a332d5d9fdfe03 Mon Sep 17 00:00:00 2001 From: Alex <$(pass /github/email)> Date: Thu, 16 Jan 2025 14:24:21 +0100 Subject: [PATCH] Backend:Real world movement --- internal/controllers/user_controller.go | 11 +++++++- internal/models/user.go | 8 +++--- internal/repositories/user_repository.go | 33 +++++++----------------- internal/routes/routes.go | 1 + internal/validation/user_validation.go | 9 +++++++ 5 files changed, 34 insertions(+), 28 deletions(-) diff --git a/internal/controllers/user_controller.go b/internal/controllers/user_controller.go index 1a207e8..e3d4211 100644 --- a/internal/controllers/user_controller.go +++ b/internal/controllers/user_controller.go @@ -51,6 +51,13 @@ func (uc *UserController) GetAllUsers(c *gin.Context) { return } + // Create a slice to hold the safe user representations + safeUsers := make([]map[string]interface{}, len(*users)) + + // Convert each user to its safe representation + for i, user := range *users { + safeUsers[i] = user.Safe() + } c.JSON(http.StatusOK, gin.H{ "users": users, }) @@ -65,10 +72,12 @@ func (uc *UserController) UpdateHandler(c *gin.Context) { } var user models.User - if err := c.ShouldBindJSON(&user); err != nil { + var updateData RegistrationData + if err := c.ShouldBindJSON(&updateData); err != nil { utils.HandleValidationError(c, err) return } + user = updateData.User if !utils.HasPrivilige(requestUser, constants.Priviliges.Update) && user.ID != requestUser.ID { utils.RespondWithError(c, errors.ErrNotAuthorized, "Not allowed to update user", http.StatusForbidden, "user", "server.error.unauthorized") diff --git a/internal/models/user.go b/internal/models/user.go index 2c05cce..eb246d4 100644 --- a/internal/models/user.go +++ b/internal/models/user.go @@ -9,13 +9,16 @@ import ( ) type User struct { - gorm.Model + ID uint `gorm:"primarykey" json:"id"` + CreatedAt time.Time + UpdatedAt time.Time + DeletedAt *time.Time `gorm:"index"` DateOfBirth time.Time `gorm:"not null" json:"date_of_birth" binding:"required,safe_content"` Company string `json:"company" binding:"omitempty,omitnil,safe_content"` Phone string `json:"phone" binding:"omitempty,omitnil,safe_content"` Notes string `json:"notes" binding:"safe_content"` FirstName string `gorm:"not null" json:"first_name" binding:"required,safe_content"` - Password string `json:"password" binding:"required_unless=RoleID 0,safe_content"` + Password string `json:"password" binding:"safe_content"` Email string `gorm:"unique;not null" json:"email" binding:"required,email,safe_content"` LastName string `gorm:"not null" json:"last_name" binding:"required,safe_content"` ProfilePicture string `json:"profile_picture" binding:"omitempty,omitnil,image,safe_content"` @@ -31,7 +34,6 @@ type User struct { MembershipID uint Licence *Licence `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"licence"` LicenceID uint - ID uint `json:"id"` PaymentStatus int8 `json:"payment_status"` Status int8 `json:"status"` RoleID int8 `json:"role_id"` diff --git a/internal/repositories/user_repository.go b/internal/repositories/user_repository.go index 65f44f9..10e18ee 100644 --- a/internal/repositories/user_repository.go +++ b/internal/repositories/user_repository.go @@ -25,6 +25,15 @@ type UserRepositoryInterface interface { type UserRepository struct{} +func PasswordExists(userID *uint) (bool, error) { + var user models.User + result := database.DB.Select("password").First(&user, userID) + if result.Error != nil { + return false, result.Error + } + return user.Password != "", nil +} + func (ur *UserRepository) CreateUser(user *models.User) (uint, error) { result := database.DB.Create(user) if result.Error != nil { @@ -57,30 +66,6 @@ func (ur *UserRepository) UpdateUser(user *models.User) (*models.User, error) { return errors.ErrNoRowsAffected } - // Handle the update or creation of Licence and its Categories - // if user.Licence != nil { - // if existingUser.Licence == nil { - // // Create new Licence if it doesn't exist - // logger.Error.Printf("Licence creation: %+v", user.Licence) - // if err := tx.Create(user.Licence).Error; err != nil { - // return err - // } - // // Update user with new licence ID - // // if err := tx.Model(&existingUser).Update("licence_id", user.Licence.ID).Error; err != nil { - // // return err - // // } - // } else { - // // Update existing licence - // if err := tx.Model(&existingUser.Licence).Updates(user.Licence).Error; err != nil { - // return err - // } - // } - // // Replace the Categories with the new list - // if err := tx.Model(&existingUser.Licence).Association("Categories").Replace(user.Licence.Categories); err != nil { - // return err - // } - // } - // Update the Membership if provided if user.Membership.ID != 0 { if err := tx.Model(&existingUser.Membership).Updates(user.Membership).Error; err != nil { diff --git a/internal/routes/routes.go b/internal/routes/routes.go index 95bb2ba..cd6b0f8 100644 --- a/internal/routes/routes.go +++ b/internal/routes/routes.go @@ -27,6 +27,7 @@ func RegisterRoutes(router *gin.Engine, userController *controllers.UserControll userRouter.GET("/current", userController.CurrentUserHandler) userRouter.POST("/logout", userController.LogoutHandler) userRouter.PATCH("/update", userController.UpdateHandler) + userRouter.POST("/update", userController.RegisterUser) userRouter.GET("/all", userController.GetAllUsers) } diff --git a/internal/validation/user_validation.go b/internal/validation/user_validation.go index aac625e..3c9fbe1 100644 --- a/internal/validation/user_validation.go +++ b/internal/validation/user_validation.go @@ -14,11 +14,20 @@ func validateUser(sl validator.StructLevel) { user := sl.Current().Interface().(models.User) isSuper := user.RoleID >= constants.Roles.Admin + + if user.RoleID > constants.Roles.Member && user.Password == "" { + passwordExists, err := repositories.PasswordExists(&user.ID) + if err != nil || !passwordExists { + logger.Error.Printf("Error checking password exists for user %v: %v", user.Email, err) + sl.ReportError(user.Password, "Password", "password", "required", "") + } + } // Validate User > 18 years old if !isSuper && user.DateOfBirth.After(time.Now().AddDate(-18, 0, 0)) { sl.ReportError(user.DateOfBirth, "DateOfBirth", "date_of_birth", "age", "") } // validate subscriptionModel + logger.Error.Printf("User: %#v", user) if user.Membership.SubscriptionModel.Name == "" { sl.ReportError(user.Membership.SubscriptionModel.Name, "SubscriptionModel.Name", "name", "required", "") } else {