diff --git a/internal/controller/httpapi/v1/profiles.go b/internal/controller/httpapi/v1/profiles.go index 958c9928..442815e4 100644 --- a/internal/controller/httpapi/v1/profiles.go +++ b/internal/controller/httpapi/v1/profiles.go @@ -27,6 +27,7 @@ func NewProfileRoutes(handler *gin.RouterGroup, t profiles.Feature, l logger.Int if v, ok := binding.Validator.Engine().(*validator.Validate); ok { _ = v.RegisterValidation("genpasswordwone", dto.ValidateAMTPassOrGenRan) _ = v.RegisterValidation("ciraortls", dto.ValidateCIRAOrTLS) + _ = v.RegisterValidation("wifidhcp", dto.ValidateWiFiDHCP) } } diff --git a/internal/entity/dto/v1/profile.go b/internal/entity/dto/v1/profile.go index 2b837641..8c371f3b 100644 --- a/internal/entity/dto/v1/profile.go +++ b/internal/entity/dto/v1/profile.go @@ -21,7 +21,7 @@ type Profile struct { DHCPEnabled bool `json:"dhcpEnabled" example:"true"` IPSyncEnabled bool `json:"ipSyncEnabled" example:"true"` LocalWiFiSyncEnabled bool `json:"localWifiSyncEnabled" example:"true"` - WiFiConfigs []ProfileWiFiConfigs `json:"wifiConfigs,omitempty" binding:"excluded_if=DHCPEnabled false,dive"` + WiFiConfigs []ProfileWiFiConfigs `json:"wifiConfigs,omitempty" binding:"wifidhcp,dive"` TenantID string `json:"tenantId" example:"abc123"` TLSMode int `json:"tlsMode,omitempty" binding:"omitempty,min=1,max=4,ciraortls" example:"1"` TLSCerts *TLSCerts `json:"tlsCerts,omitempty"` @@ -66,6 +66,18 @@ var ValidateUserConsent validator.Func = func(fl validator.FieldLevel) bool { return userConsent == "none" || userConsent == "kvm" || userConsent == "all" } +var ValidateWiFiDHCP validator.Func = func(fl validator.FieldLevel) bool { + dhcpEnabled := fl.Parent().FieldByName("DHCPEnabled").Bool() + wifiConfigs := fl.Field() + + // If WiFiConfigs has items and DHCP is disabled, fail validation + if wifiConfigs.Len() > 0 && !dhcpEnabled { + return false + } + + return true +} + type ProfileCountResponse struct { Count int `json:"totalCount"` Data []Profile `json:"data"` diff --git a/internal/entity/dto/v1/profile_test.go b/internal/entity/dto/v1/profile_test.go new file mode 100644 index 00000000..42d03190 --- /dev/null +++ b/internal/entity/dto/v1/profile_test.go @@ -0,0 +1,123 @@ +package dto + +import ( + "testing" + + "github.com/go-playground/validator/v10" + "github.com/stretchr/testify/assert" +) + +func TestValidateWiFiDHCP(t *testing.T) { + t.Parallel() + + validate := validator.New() + err := validate.RegisterValidation("wifidhcp", ValidateWiFiDHCP) + assert.NoError(t, err) + + tests := []struct { + name string + dhcpEnabled bool + wifiConfigs []ProfileWiFiConfigs + wantErr bool + }{ + { + name: "valid with WiFi configs and DHCP enabled", + dhcpEnabled: true, + wifiConfigs: []ProfileWiFiConfigs{ + { + Priority: 1, + WirelessProfileName: "MyWiFiProfile", + ProfileName: "MyProfile", + TenantID: "tenant1", + }, + }, + wantErr: false, + }, + { + name: "invalid with WiFi configs and DHCP disabled", + dhcpEnabled: false, + wifiConfigs: []ProfileWiFiConfigs{ + { + Priority: 1, + WirelessProfileName: "MyWiFiProfile", + ProfileName: "MyProfile", + TenantID: "tenant1", + }, + }, + wantErr: true, + }, + { + name: "valid with no WiFi configs and DHCP enabled", + dhcpEnabled: true, + wifiConfigs: []ProfileWiFiConfigs{}, + wantErr: false, + }, + { + name: "valid with no WiFi configs and DHCP disabled", + dhcpEnabled: false, + wifiConfigs: []ProfileWiFiConfigs{}, + wantErr: false, + }, + { + name: "valid with multiple WiFi configs and DHCP enabled", + dhcpEnabled: true, + wifiConfigs: []ProfileWiFiConfigs{ + { + Priority: 1, + WirelessProfileName: "WiFiProfile1", + ProfileName: "Profile1", + TenantID: "tenant1", + }, + { + Priority: 2, + WirelessProfileName: "WiFiProfile2", + ProfileName: "Profile2", + TenantID: "tenant1", + }, + }, + wantErr: false, + }, + { + name: "invalid with multiple WiFi configs and DHCP disabled", + dhcpEnabled: false, + wifiConfigs: []ProfileWiFiConfigs{ + { + Priority: 1, + WirelessProfileName: "WiFiProfile1", + ProfileName: "Profile1", + TenantID: "tenant1", + }, + { + Priority: 2, + WirelessProfileName: "WiFiProfile2", + ProfileName: "Profile2", + TenantID: "tenant1", + }, + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + type testStruct struct { + DHCPEnabled bool `validate:"omitempty"` + WiFiConfigs []ProfileWiFiConfigs `validate:"wifidhcp"` + } + + s := testStruct{ + DHCPEnabled: tt.dhcpEnabled, + WiFiConfigs: tt.wifiConfigs, + } + err := validate.Struct(s) + + if tt.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +}