Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ import {
validatePortListOrRange,
validateRequired,
validateRequiredOption,
validateAnyOf
validateAnyOf,
validateMacAddress
} from '@/lib/validation'
import NeMultiTextInput from '../../NeMultiTextInput.vue'
import { useObjects, type ObjectReference } from '@/composables/useObjects'
Expand Down Expand Up @@ -68,11 +69,14 @@ const firewallConfig = useFirewallStore()
const isRuleEnabled = ref(true)
const name = ref('')
const nameRef = ref()
const sourceType = ref<'source_address' | 'source_object' | 'source_any'>('source_address')
const sourceType = ref<'source_address' | 'source_object' | 'source_any' | 'source_mac_address'>(
'source_address'
)
const destinationType = ref<'destination_address' | 'destination_object' | 'destination_any'>(
'destination_address'
)
const sourceAddresses = ref<string[]>([''])
const sourceMACAddresses = ref<string[]>([''])
const destinationAddresses = ref<string[]>([''])
const sourceAddressObject = ref('')
const destinationAddressObject = ref('')
Expand All @@ -98,6 +102,7 @@ const tags: Ref<NeComboboxOption[]> = ref([])
const isLoggingEnabled = ref(false)
const errorBag = ref(new MessageBag())
const sourceAddressesErrors = ref<string[]>([])
const sourceMACAddressesErrors = ref<string[]>([])
const destinationAddressesErrors = ref<string[]>([])

const actionOptions = computed(() => {
Expand Down Expand Up @@ -149,6 +154,10 @@ const sourceTypeOptions = ref([
{
id: 'source_any',
label: t('standalone.firewall_rules.any_source_address')
},
{
id: 'source_mac_address',
label: t('standalone.firewall_rules.mac_address')
}
])

Expand Down Expand Up @@ -280,6 +289,7 @@ watch(
destinationType.value = 'destination_address'
sourceAddresses.value = ['']
sourceAddressObject.value = ''
sourceMACAddresses.value = ['']
destinationAddresses.value = ['']
destinationAddressObject.value = ''
sourceZone.value = '*'
Expand Down Expand Up @@ -337,6 +347,8 @@ watch(
)

function mapSourceAddressesToUi(rule: FirewallRule) {
sourceMACAddresses.value = rule.src_mac?.length ? [...rule.src_mac] : ['']

if (!rule.src_ip) {
return []
}
Expand All @@ -346,6 +358,8 @@ function mapSourceAddressesToUi(rule: FirewallRule) {
// source address is an object
sourceType.value = 'source_object'
sourceAddressObject.value = rule.ns_src
} else if (rule.src_mac?.length) {
sourceType.value = 'source_mac_address'
} else {
if (rule.src_ip.length) {
sourceType.value = 'source_address'
Expand Down Expand Up @@ -526,6 +540,8 @@ function validate() {
sourceAddressesErrors.value.push('')
})

sourceMACAddressesErrors.value = sourceMACAddresses.value.map(() => '')

destinationAddressesErrors.value = []
destinationAddresses.value.forEach(() => {
destinationAddressesErrors.value.push('')
Expand Down Expand Up @@ -580,6 +596,18 @@ function validate() {
isValidationOk = false
focusElement(sourceAddressObjectRef)
}
} else if (sourceType.value === 'source_mac_address') {
for (const [index, sourceMACAddress] of sourceMACAddresses.value.entries()) {
let sourceMACAddressValidation = validateRequired(sourceMACAddress)
if (sourceMACAddressValidation.valid) {
sourceMACAddressValidation = validateMacAddress(sourceMACAddress)
}

if (!sourceMACAddressValidation.valid) {
sourceMACAddressesErrors.value[index] = t(sourceMACAddressValidation.errMessage as string)
isValidationOk = false
}
}
}

// source zone
Expand Down Expand Up @@ -708,6 +736,7 @@ async function saveRule() {
enabled: isRuleEnabled.value,
src_ip: [],
ns_src: '',
src_mac: [],
src: '',
dest_ip: [],
ns_dst: '',
Expand Down Expand Up @@ -741,6 +770,12 @@ async function saveRule() {
} else if (sourceType.value === 'source_object') {
// source address object
ruleData.ns_src = sourceAddressObject.value
} else if (sourceType.value === 'source_mac_address') {
ruleData.src_mac = [
...new Set(
sourceMACAddresses.value.map((macAddress) => macAddress.toLowerCase().replace(/-/g, ':'))
)
]
}

// source zone
Expand Down Expand Up @@ -894,6 +929,18 @@ async function saveRule() {
:selected-label="t('ne_combobox.selected')"
:user-input-label="t('ne_combobox.user_input_label')"
/>
<!-- source MAC addresses -->
<NeMultiTextInput
v-show="sourceType === 'source_mac_address'"
v-model="sourceMACAddresses"
:disable-inputs="loading.saveRule"
:title="t('standalone.firewall_rules.source_mac_addresses')"
:add-item-label="t('standalone.firewall_rules.add_source_mac_address')"
:invalid-messages="sourceMACAddressesErrors"
:general-invalid-message="t(errorBag.getFirstFor('src_mac'))"
required
:placeholder="t('standalone.firewall_rules.mac_address_placeholder')"
/>
<!-- source zone -->
<NeCombobox
ref="sourceZoneRef"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ function searchStringInRule(rule: FirewallRule, queryText: string) {
}

// search in array attributes
found = ['proto', 'dest_port', 'ns_tag'].some((attrName) => {
found = ['src_mac', 'proto', 'dest_port', 'ns_tag'].some((attrName) => {
const attrValue = rule[attrName as keyof FirewallRule] as string[]

return attrValue?.some((value) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ function searchStringInRule(rule: FirewallRule, queryText: string) {
}

// search in array attributes
found = ['proto', 'dest_port', 'ns_tag'].some((attrName) => {
found = ['src_mac', 'proto', 'dest_port', 'ns_tag'].some((attrName) => {
const attrValue = rule[attrName as keyof FirewallRule] as string[]

return attrValue?.some((value) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ const domainSetObject = computed(() => {

const addresses = computed(() => {
if (props.columnType === 'source') {
if (props.rule.src_mac?.length) {
return props.rule.src_mac.map((macAddress) => ({ value: macAddress, label: '', type: 'mac' }))
}
return props.rule.src_ip as RuleHost[]
} else {
return props.rule.dest_ip as RuleHost[]
Expand Down
6 changes: 5 additions & 1 deletion src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1715,7 +1715,11 @@
"inactive": "Inactive",
"zone_no_longer_exists": "This rule is inactive because it uses a zone that no longer exists",
"disabled_rule": "This rule has been manually disabled, but can be re-enabled",
"logging_enabled": "Logging enabled"
"logging_enabled": "Logging enabled",
"mac_address": "MAC address",
"add_source_mac_address": "Add source MAC address",
"source_mac_addresses": "Source MAC addresses",
"mac_address_placeholder": "e.g. 00:1A:2B:3C:4D:5E"
},
"firewall": {
"title": "Firewall"
Expand Down
6 changes: 5 additions & 1 deletion src/i18n/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -2177,7 +2177,11 @@
"inactive": "Inattiva",
"zone_no_longer_exists": "Questa regola è stata disattivata perché utilizza una zona che non esiste più",
"disabled_rule": "Questa regola è stata disabilitata manualmente, ma può essere riattivata",
"logging_enabled": "Logging abilitato"
"logging_enabled": "Logging abilitato",
"mac_address": "Indirizzo MAC",
"add_source_mac_address": "Aggiungi indirizzo MAC sorgente",
"source_mac_addresses": "Indirizzi MAC sorgente",
"mac_address_placeholder": "es. 00:1A:2B:3C:4D:5E"
},
"certificates": {
"title": "Certificati",
Expand Down
1 change: 1 addition & 0 deletions src/stores/standalone/firewall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export interface FirewallRule {
src?: string // source zone
src_ip?: string[] | RuleHost[] // source addresses
ns_src?: string // source address object
src_mac?: string[] // source MAC addresses
dest?: string // destination zone
dest_ip?: string[] | RuleHost[] // destination addresses
ns_dst?: string // destination address object
Expand Down
Loading