add & moved to validations folder; del validator/v10
This commit is contained in:
38
internal/validation/DriversLicence_validation.go
Normal file
38
internal/validation/DriversLicence_validation.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
func ValidateDriversLicence(fl validator.FieldLevel) bool {
|
||||
fieldValue := fl.Field().String()
|
||||
if len(fieldValue) != 11 {
|
||||
return false
|
||||
}
|
||||
|
||||
id, tenthChar := string(fieldValue[:9]), string(fieldValue[9])
|
||||
|
||||
if tenthChar == "X" {
|
||||
tenthChar = "10"
|
||||
}
|
||||
tenthValue, _ := strconv.ParseInt(tenthChar, 10, 8)
|
||||
|
||||
// for readability
|
||||
weights := []int{9, 8, 7, 6, 5, 4, 3, 2, 1}
|
||||
sum := 0
|
||||
|
||||
for i := 0; i < 9; i++ {
|
||||
char := string(id[i])
|
||||
value, _ := strconv.ParseInt(char, 36, 64)
|
||||
sum += int(value) * weights[i]
|
||||
}
|
||||
|
||||
calcCheckDigit := sum % 11
|
||||
if calcCheckDigit != int(tenthValue) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
19
internal/validation/bankAccount_validation.go
Normal file
19
internal/validation/bankAccount_validation.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"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()
|
||||
|
||||
return iban.Validate(fieldValue) == nil
|
||||
}
|
||||
|
||||
func BICValidator(fl validator.FieldLevel) bool {
|
||||
fieldValue := fl.Field().String()
|
||||
|
||||
return swift.Validate(fieldValue) == nil
|
||||
}
|
||||
34
internal/validation/general_validation.go
Normal file
34
internal/validation/general_validation.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
var xssPatterns = []*regexp.Regexp{
|
||||
regexp.MustCompile(`(?i)<script`),
|
||||
regexp.MustCompile(`(?i)javascript:`),
|
||||
regexp.MustCompile(`(?i)on\w+\s*=`),
|
||||
regexp.MustCompile(`(?i)(vbscript|data):`),
|
||||
regexp.MustCompile(`(?i)<(iframe|object|embed|applet)`),
|
||||
regexp.MustCompile(`(?i)expression\s*\(`),
|
||||
regexp.MustCompile(`(?i)url\s*\(`),
|
||||
regexp.MustCompile(`(?i)<\?`),
|
||||
regexp.MustCompile(`(?i)<%`),
|
||||
regexp.MustCompile(`(?i)<!\[CDATA\[`),
|
||||
regexp.MustCompile(`(?i)<(svg|animate)`),
|
||||
regexp.MustCompile(`(?i)<(audio|video|source)`),
|
||||
regexp.MustCompile(`(?i)base64`),
|
||||
}
|
||||
|
||||
func ValidateSafeContent(fl validator.FieldLevel) bool {
|
||||
input := strings.ToLower(fl.Field().String())
|
||||
for _, pattern := range xssPatterns {
|
||||
if pattern.MatchString(input) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
30
internal/validation/membership_validation.go
Normal file
30
internal/validation/membership_validation.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"GoMembership/internal/models"
|
||||
"GoMembership/internal/repositories"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
func validateMembership(sl validator.StructLevel, membership models.Membership) {
|
||||
if membership.SubscriptionModel.RequiredMembershipField != "" {
|
||||
switch membership.SubscriptionModel.RequiredMembershipField {
|
||||
case "ParentMembershipID":
|
||||
if membership.ParentMembershipID == 0 {
|
||||
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", "")
|
||||
}
|
||||
}
|
||||
default:
|
||||
sl.ReportError(membership.ParentMembershipID, membership.SubscriptionModel.RequiredMembershipField,
|
||||
"RequiredMembershipField", "not_implemented", "")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
23
internal/validation/setup.go
Normal file
23
internal/validation/setup.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"GoMembership/internal/models"
|
||||
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
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", ValidateDriversLicence)
|
||||
|
||||
// Register struct-level validations
|
||||
v.RegisterStructValidation(validateUser, models.User{})
|
||||
v.RegisterStructValidation(ValidateSubscription, models.SubscriptionModel{})
|
||||
}
|
||||
}
|
||||
46
internal/validation/subscription_validation.go
Normal file
46
internal/validation/subscription_validation.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"GoMembership/internal/models"
|
||||
"GoMembership/internal/repositories"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
// ValidateNewSubscription validates a new subscription model being created
|
||||
func ValidateSubscription(sl validator.StructLevel) {
|
||||
subscription := sl.Current().Interface().(models.SubscriptionModel)
|
||||
|
||||
if subscription.Name == "" {
|
||||
sl.ReportError(subscription.Name, "Name", "name", "required", "")
|
||||
}
|
||||
|
||||
if sl.Parent().Type().Name() == "MembershipData" {
|
||||
// This is subscription only operation
|
||||
if subscription.Details == "" {
|
||||
sl.ReportError(subscription.Details, "Details", "details", "required", "")
|
||||
}
|
||||
|
||||
if subscription.MonthlyFee < 0 {
|
||||
sl.ReportError(subscription.MonthlyFee, "MonthlyFee", "monthly_fee", "gte", "0")
|
||||
}
|
||||
|
||||
if subscription.HourlyRate < 0 {
|
||||
sl.ReportError(subscription.HourlyRate, "HourlyRate", "hourly_rate", "gte", "0")
|
||||
}
|
||||
|
||||
if subscription.IncludedPerYear < 0 {
|
||||
sl.ReportError(subscription.IncludedPerYear, "IncludedPerYear", "included_hours_per_year", "gte", "0")
|
||||
}
|
||||
|
||||
if subscription.IncludedPerMonth < 0 {
|
||||
sl.ReportError(subscription.IncludedPerMonth, "IncludedPerMonth", "included_hours_per_month", "gte", "0")
|
||||
}
|
||||
} else {
|
||||
// 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", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
51
internal/validation/user_validation.go
Normal file
51
internal/validation/user_validation.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"GoMembership/internal/models"
|
||||
"GoMembership/internal/repositories"
|
||||
"GoMembership/pkg/logger"
|
||||
"time"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
func validateUser(sl validator.StructLevel) {
|
||||
user := sl.Current().Interface().(models.User)
|
||||
|
||||
if user.DateOfBirth.After(time.Now().AddDate(-18, 0, 0)) {
|
||||
sl.ReportError(user.DateOfBirth, "DateOfBirth", "date_of_birth", "age", "")
|
||||
}
|
||||
|
||||
if user.Membership.SubscriptionModel.Name == "" {
|
||||
sl.ReportError(user.Membership.SubscriptionModel.Name, "SubscriptionModel.Name", "name", "required", "")
|
||||
} else {
|
||||
selectedModel, err := repositories.GetModelByName(&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, "SubscriptionModel.Name", "name", "invalid", "")
|
||||
} else {
|
||||
user.Membership.SubscriptionModel = *selectedModel
|
||||
}
|
||||
}
|
||||
validateMembership(sl, user.Membership)
|
||||
}
|
||||
|
||||
// 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()
|
||||
// }
|
||||
Reference in New Issue
Block a user