package validation import ( "GoMembership/internal/models" "GoMembership/internal/repositories" "GoMembership/pkg/logger" "strings" "time" "github.com/go-playground/validator/v10" passwordvalidator "github.com/wagslane/go-password-validator" "gorm.io/gorm" ) var passwordErrorTranslations = map[string]string{ "insecure password, try ": "", "or using a longer password": "server.validation.longer", "including more special characters": "server.validation.special", "using lowercase letters": "server.validation.lowercase", "using uppercase letters": "server.validation.uppercase", "using numbers": "server.validation.numbers", } func ValidateUserFactory(db *gorm.DB) validator.StructLevelFunc { return func(sl validator.StructLevel) { validateUser(db, sl) } } func validateUser(db *gorm.DB, sl validator.StructLevel) { user := sl.Current().Interface().(models.User) // validate subscriptionModel if user.Membership.SubscriptionModel.Name == "" { sl.ReportError(user.Membership.SubscriptionModel.Name, "subscription.name", "name", "required", "") } else { selectedModel, err := repositories.GetSubscriptionByName(&user.Membership.SubscriptionModel.Name) if err != nil { logger.Error.Printf("Error finding subscription model for user %v: %v", user.Email, err) sl.ReportError(user.Membership.SubscriptionModel.Name, "subscription.name", "name", "invalid", "") } else { user.Membership.SubscriptionModel = *selectedModel } } if user.IsSupporter() { if user.BankAccount.IBAN != "" { validateBankAccount(sl) } return } if user.Password != "" { if err := passwordvalidator.Validate(user.Password, 60); err != nil { sl.ReportError(user.Password, translatePasswordError(err), "password", "insecure", "") } } // Validate User > 18 years old if user.DateOfBirth.After(time.Now().AddDate(-18, 0, 0)) { sl.ReportError(user.DateOfBirth, "user.user", "user.dateofbirth", "age", "") } validateMembership(db, &user, sl) if user.IsAdmin() { return } validateBankAccount(sl) if user.Licence != nil { validateDriverslicence(sl) } } func translatePasswordError(err error) string { errMsg := err.Error() // Translate each part of the error message translatedMsg := errMsg for eng, translated := range passwordErrorTranslations { translatedMsg = strings.Replace(translatedMsg, eng, translated, -1) } return strings.Replace(translatedMsg, ",", "", -1) }