moved to struct validation;

This commit is contained in:
Alex
2024-11-04 17:21:55 +01:00
parent 0fa57bfe75
commit fa10a0a507
15 changed files with 246 additions and 275 deletions

View File

@@ -1,13 +1,27 @@
package validation
import (
"GoMembership/internal/models"
"strconv"
"time"
"github.com/go-playground/validator/v10"
)
func ValidateLicence(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
func validateDriverslicence(sl validator.StructLevel) {
dl := sl.Current().Interface().(models.User).Licence
if !validateLicence(dl.Number) {
sl.ReportError(dl.Number, "licence_number", "", "invalid", "")
}
if dl.IssuedDate.After(time.Now()) {
sl.ReportError(dl.IssuedDate, "issued_date", "", "invalid", "")
}
if dl.ExpirationDate.Before(time.Now().AddDate(0, 0, 3)) {
sl.ReportError(dl.ExpirationDate, "expiration_date", "", "too_soon", "")
}
}
func validateLicence(fieldValue string) bool {
if len(fieldValue) != 11 {
return false
}

View File

@@ -1,19 +1,27 @@
package validation
import (
"GoMembership/internal/models"
"github.com/go-playground/validator/v10"
"github.com/jbub/banking/iban"
"github.com/jbub/banking/swift"
)
func IBANValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
func validateBankAccount(sl validator.StructLevel) {
ba := sl.Current().Interface().(models.User).BankAccount
if !ibanValidator(ba.IBAN) {
sl.ReportError(ba.IBAN, "IBAN", "BankAccount.IBAN", "required", "")
}
if ba.BIC != "" && !bicValidator(ba.BIC) {
sl.ReportError(ba.IBAN, "IBAN", "BankAccount.IBAN", "required", "")
}
}
func ibanValidator(fieldValue string) bool {
return iban.Validate(fieldValue) == nil
}
func BICValidator(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String()
func bicValidator(fieldValue string) bool {
return swift.Validate(fieldValue) == nil
}

View File

@@ -3,28 +3,40 @@ package validation
import (
"GoMembership/internal/models"
"GoMembership/internal/repositories"
"GoMembership/pkg/errors"
"GoMembership/pkg/logger"
"github.com/go-playground/validator/v10"
)
func validateMembership(sl validator.StructLevel, membership models.Membership) {
func validateMembership(sl validator.StructLevel) {
membership := sl.Current().Interface().(models.User).Membership
if membership.SubscriptionModel.RequiredMembershipField != "" {
switch membership.SubscriptionModel.RequiredMembershipField {
case "ParentMembershipID":
if membership.ParentMembershipID == 0 {
if err := CheckParentMembershipID(membership); err != nil {
logger.Error.Printf(err.Error())
sl.ReportError(membership.ParentMembershipID, membership.SubscriptionModel.RequiredMembershipField,
"RequiredMembershipField", "required", "")
} else {
_, err := repositories.GetUserByID(&membership.ParentMembershipID)
if err != nil {
sl.ReportError(membership.ParentMembershipID, membership.SubscriptionModel.RequiredMembershipField,
"RequiredMembershipField", "user_id_not_found", "")
}
"RequiredMembershipField", "invalid", "")
}
default:
logger.Error.Printf(errors.ErrInvalidValue.Error())
sl.ReportError(membership.ParentMembershipID, membership.SubscriptionModel.RequiredMembershipField,
"RequiredMembershipField", "not_implemented", "")
}
}
}
func CheckParentMembershipID(membership models.Membership) error {
if membership.ParentMembershipID == 0 {
return errors.ValErrParentIDNotSet
} else {
_, err := repositories.GetUserByID(&membership.ParentMembershipID)
if err != nil {
return errors.ValErrParentIDNotFound
}
}
return nil
}

View File

@@ -12,9 +12,6 @@ func SetupValidators() {
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
// Register custom validators
v.RegisterValidation("safe_content", ValidateSafeContent)
v.RegisterValidation("iban", IBANValidator)
v.RegisterValidation("bic", BICValidator)
v.RegisterValidation("euDriversLicence", ValidateLicence)
// Register struct-level validations
v.RegisterStructValidation(validateUser, models.User{})

View File

@@ -16,7 +16,7 @@ func ValidateSubscription(sl validator.StructLevel) {
}
if sl.Parent().Type().Name() == "MembershipData" {
// This is subscription only operation
// This is modifying a subscription directly
if subscription.Details == "" {
sl.ReportError(subscription.Details, "Details", "details", "required", "")
}
@@ -40,7 +40,7 @@ func ValidateSubscription(sl validator.StructLevel) {
// This is a nested probably user struct. We are only checking if the model exists
existingSubscription, err := repositories.GetModelByName(&subscription.Name)
if err != nil || existingSubscription == nil {
sl.ReportError(subscription.Name, "Name", "name", "exists", "")
sl.ReportError(subscription.Name, "Subscription_Name", "name", "exists", "")
}
}
}

View File

@@ -1,6 +1,7 @@
package validation
import (
"GoMembership/internal/constants"
"GoMembership/internal/models"
"GoMembership/internal/repositories"
"GoMembership/pkg/logger"
@@ -12,10 +13,12 @@ import (
func validateUser(sl validator.StructLevel) {
user := sl.Current().Interface().(models.User)
if user.DateOfBirth.After(time.Now().AddDate(-18, 0, 0)) {
isSuper := user.RoleID >= constants.Roles.Admin
// 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
if user.Membership.SubscriptionModel.Name == "" {
sl.ReportError(user.Membership.SubscriptionModel.Name, "SubscriptionModel.Name", "name", "required", "")
} else {
@@ -27,25 +30,12 @@ func validateUser(sl validator.StructLevel) {
user.Membership.SubscriptionModel = *selectedModel
}
}
validateMembership(sl, user.Membership)
validateMembership(sl)
if !isSuper {
validateBankAccount(sl)
if user.Licence != nil {
validateDriverslicence(sl)
}
}
}
// func RequiredIfNotAdmin(fl validator.FieldLevel) bool {
// // Traverse up the struct hierarchy to find the IsAdmin field
// current := fl.Parent()
// // Check multiple levels of nesting to find userRole
// for current.IsValid() {
// if isRoleIDField := current.FieldByName("RoleID"); isRoleIDField.IsValid() {
// // If IsAdmin is found and is true, skip validation
// if isRoleIDField.Interface().(int8) == constants.Roles.Admin{
// return true
// }
// break
// }
// current = current.Parent() // Move to the next parent level
// }
// If not an admin, enforce that the field must have a non-zero value
// return !fl.Field().IsZero()
// }