Skip to content

Commit

Permalink
[ui] Add OutputBlock support
Browse files Browse the repository at this point in the history
  • Loading branch information
lts-rad committed Nov 4, 2024
1 parent 38d5c67 commit 94166d0
Show file tree
Hide file tree
Showing 2 changed files with 268 additions and 0 deletions.
150 changes: 150 additions & 0 deletions frontend/src/components/Firewall/AddOutputBlock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import React, { useContext } from 'react'
import PropTypes from 'prop-types'

import ClientSelect from 'components/ClientSelect'
import { firewallAPI } from 'api'
import { AlertContext } from 'AppContext'

import {
Button,
ButtonText,
FormControl,
FormControlHelper,
FormControlHelperText,
FormControlLabel,
FormControlLabelText,
Input,
InputField,
HStack,
VStack
} from '@gluestack-ui/themed'

import ProtocolRadio from 'components/Form/ProtocolRadio'

class AddOutputBlockImpl extends React.Component {
state = {
SrcIP: '0.0.0.0/0',
DstIP: '',
DstPort: '',
Protocol: 'tcp'
}

constructor(props) {
super(props)

this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}

handleChange(name, value) {
//TODO verify IP && port
this.setState({ [name]: value })
}

handleSubmit(event) {
event.preventDefault()

let block = {
SrcIP: this.state.SrcIP,
DstIP: this.state.DstIP,
DstPort: this.state.DstPort,
Protocol: this.state.Protocol
}

const done = (res) => {
if (this.props.notifyChange) {
this.props.notifyChange('forward_block')
}
}

firewallAPI
.addOutputBLock(block)
.then(done)
.catch((err) => {
this.props.alertContext.error('Firewall API Failure', err)
})
}

componentDidMount() {}

render() {
return (
<VStack space="md">
<FormControl isRequired>
<FormControlLabel>
<FormControlLabelText>Source IP Address</FormControlLabelText>
</FormControlLabel>
<Input size="md" variant="underlined">
<InputField
value={this.state.SrcIP}
onChangeText={(value) => this.handleChange('SrcIP', value)}
/>
</Input>
<FormControlHelper>
<FormControlHelperText>IP address or CIDR</FormControlHelperText>
</FormControlHelper>
</FormControl>
<FormControl isRequired>
<FormControlLabel>
<FormControlLabelText>Destination IP Address</FormControlLabelText>
</FormControlLabel>
<Input size="md" variant="underlined">
<InputField
value={this.state.DstIP}
onChangeText={(value) => this.handleChange('DstIP', value)}
/>
</Input>
<FormControlHelper>
<FormControlHelperText>IP address or CIDR</FormControlHelperText>
</FormControlHelper>
</FormControl>

<FormControl>
<FormControlLabel>
<FormControlLabelText>Destination Port</FormControlLabelText>
</FormControlLabel>
<Input size="md" variant="underlined">
<InputField
value={this.state.DstPort}
onChangeText={(value) => this.handleChange('DstPort', value)}
/>
</Input>
<FormControlHelper>
<FormControlHelperText>
Optional port or port range, leave empty for all ports
</FormControlHelperText>
</FormControlHelper>
</FormControl>

<FormControl>
<FormControlLabel>
<FormControlLabelText>Protocol</FormControlLabelText>
</FormControlLabel>

<ProtocolRadio
value={this.state.Protocol}
onChange={(value) => this.handleChange('Protocol', value)}
/>
</FormControl>

<Button action="primary" size="md" onPress={this.handleSubmit}>
<ButtonText>Save</ButtonText>
</Button>
</VStack>
)
}
}

AddOutputBlockImpl.propTypes = {
notifyChange: PropTypes.func
}

export default function AddOutputBlock(props) {
let alertContext = useContext(AlertContext)
return (
<AddOutputBlockImpl
notifyChange={props.notifyChange}
alertContext={alertContext}
></AddOutputBlockImpl>
)
}
118 changes: 118 additions & 0 deletions frontend/src/components/Firewall/OutputBlockList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import React, { useRef } from 'react'
import PropTypes from 'prop-types'

import { firewallAPI } from 'api'
import ModalForm from 'components/ModalForm'
import AddOutputBlock from './AddOutputBlock'

import {
Badge,
BadgeText,
Button,
ButtonText,
ButtonIcon,
Box,
FlatList,
VStack,
Text,
AddIcon,
CloseIcon
} from '@gluestack-ui/themed'

import { ListHeader, ListItem } from 'components/List'

const OutputBlockList = (props) => {
let list = props.list || []
let title = props.title || `BlockList:`

let refModal = useRef(null)

const deleteListItem = (item) => {
const done = (res) => {
props.notifyChange('block')
}

firewallAPI.deleteOutputBlock(item).then(done)
}

const notifyChange = (t) => {
refModal.current()
props.notifyChange('block')
}

return (
<VStack>
<ListHeader
title={title}
description="Block SPR outbound traffic to the internet"
>
<ModalForm
title={`Add IP Block`}
triggerText="Add IP Block"
triggerProps={{
sx: {
'@base': { display: 'none' },
'@md': { display: list.length ? 'flex' : 'flex' }
}
}}
modalRef={refModal}
>
<AddOutputBlock notifyChange={notifyChange} />
</ModalForm>
</ListHeader>

<FlatList
data={list}
renderItem={({ item }) => (
<ListItem>
<Badge action="muted" variant="outline">
<BadgeText>{item.Protocol}</BadgeText>
</Badge>

<Text>{item.SrcIP}</Text>
<Text>{item.DstIP}</Text>

<Button
alignSelf="center"
size="sm"
action="negative"
variant="link"
onPress={() => deleteListItem(item)}
>
<ButtonIcon as={CloseIcon} color="$red700" />
</Button>
</ListItem>
)}
keyExtractor={(item) => `${item.Protocol}${item.SrcIP}${item.DstIP}`}
/>

{!list.length ? (
<Text
bg="$backgroundCardLight"
sx={{ _dark: { bg: '$backgroundCardDark' } }}
p="$4"
flexWrap="wrap"
>
Block SPR outbound traffic to the internet
</Text>
) : null}

<Button
sx={{ '@md': { display: list.length ? 'none' : 'none' } }}
action="primary"
variant="solid"
rounded="$none"
onPress={() => refModal.current()}
>
<ButtonText>Add IP Block</ButtonText>
<ButtonIcon as={AddIcon} />
</Button>
</VStack>
)
}

OutputBlockList.propTypes = {
notifyChange: PropTypes.func.isRequired
}

export default OutputBlockList

0 comments on commit 94166d0

Please sign in to comment.