Spaces:
Sleeping
Sleeping
| import React, { useEffect, useState } from 'react'; | |
| import client from '../client'; | |
| import AttacksTableComponent from '../components/AttacksTableComponent'; | |
| import BasicSelect from '../components/BasicSelectComponent'; | |
| import { ToastContainer, toast } from 'react-toastify'; | |
| import InvokeComponent from '../components/InvokeComponent'; | |
| import Box from '@mui/material/Box'; | |
| import Modal from '@mui/material/Modal'; | |
| function AttacksPage() { | |
| const apiUrl = "/attacks"; | |
| const [allAttacks, setAllAttacks] = useState([]); | |
| const [allDataCatalogs, setallDataCatalogs] = useState([]); | |
| const [selectedDataCatalog, setSelectedDataCatalog] = useState(null); | |
| const [allAttackCodes, setAllAttackCodes] = useState([]); | |
| const [selectedAttack, setSelectedAttack] = useState([]); | |
| const [attackOngoing, setAttackOngoing] = useState(false) | |
| const [invokeButtonText, setInvokeButtonText] = useState("Invoke") | |
| // Invoke Button | |
| let invokeButtonColor = attackOngoing ? "bg-gray-100" : (selectedAttack.length > 0 ? "bg-gray-100" : "bg-gray-100 text-gray-300") | |
| // Modal | |
| const [open, setOpen] = React.useState(false); | |
| const handleOpen = () => setOpen(true); | |
| const handleClose = () => setOpen(false); | |
| const style = { | |
| position: 'absolute', | |
| top: '50%', | |
| left: '50%', | |
| transform: 'translate(-50%, -50%)', | |
| width: 400, | |
| bgcolor: 'background.paper', | |
| border: '4px solid #000', | |
| boxShadow: 24, | |
| p: 4, | |
| }; | |
| let modalInvokeButtonColor = selectedDataCatalog !== null ? "bg-gray-100" : "bg-gray-100 text-gray-300" | |
| const InvokeAttack = () => { | |
| handleClose() | |
| const attackId = selectedAttack.length === 1 ? selectedAttack[0].id : "NULL" | |
| if (selectedAttack.length !== 1 || attackOngoing) {console.log("Aborting attack: " + attackId); return} | |
| else { | |
| toast.info("Attack with ID: " + attackId + " is being invoked") | |
| console.log("Invoking attack:" + attackId) | |
| console.log("selectedDataCatalog:", selectedDataCatalog) | |
| setAttackOngoing(true) | |
| setInvokeButtonText("Invoking...") | |
| client.post("/invoke/" + selectedDataCatalog + "?attack_id=" + attackId) | |
| .then((response) => { | |
| setAttackOngoing(false); | |
| setInvokeButtonText("Invoke"); | |
| toast.success("Attack successfully invoked!"); | |
| }) | |
| .catch(error => { | |
| setAttackOngoing(false); | |
| toast.error("Error invoking attack: " + error); | |
| setInvokeButtonText("Invoke"); | |
| }); | |
| } | |
| } | |
| const openChooseDataCatalogModal = () => { | |
| handleOpen() | |
| } | |
| const refreshAttacks = () => { | |
| client.get(apiUrl) | |
| .then(response => { | |
| const modifiedAttacks = response.data.map(attack => { | |
| return { | |
| ...attack, | |
| // mitre_id: allAttackCodes.find((attackCode) => attackCode.tmryk_id === attack.tmryk_id).mitre_atlas_id | |
| mitre_id: "AML.T0043.001" | |
| }; | |
| }); | |
| setAllAttacks(modifiedAttacks); | |
| }) | |
| .catch(() => console.log("error in attacksPage")); | |
| } | |
| useEffect(() => { | |
| refreshAttacks(); | |
| client.get("/datacatalog") | |
| .then(response => { | |
| setallDataCatalogs(response.data); | |
| }) | |
| .catch(() => console.log("Error getting /datacatalog")) | |
| client.get("/attack_code") | |
| .then(response => { | |
| setAllAttackCodes(response.data); | |
| }) | |
| .catch((err) => console.log(err)) | |
| }, []); | |
| return ( | |
| <div className="content"> | |
| <div className="mt-10"> | |
| <AttacksTableComponent | |
| data={allAttacks} | |
| selectedAttack={selectedAttack} | |
| setSelectedAttack={setSelectedAttack} | |
| refreshAttacks={refreshAttacks}/> | |
| <InvokeComponent | |
| text={invokeButtonText} | |
| action={(selectedAttack.length === 1 && !attackOngoing) ? openChooseDataCatalogModal : null} | |
| classNames={`${invokeButtonColor} mt-8` + (selectedAttack.length === 1 ? " cursor-pointer" : "")} /> | |
| </div> | |
| <ToastContainer /> | |
| <div> | |
| <Modal | |
| open={open} | |
| onClose={handleClose} | |
| aria-labelledby="modal-modal-title" | |
| aria-describedby="modal-modal-description"> | |
| <Box sx={style}> | |
| <BasicSelect | |
| label="Choose DataCatalog" | |
| content={selectedAttack.length === 1 ? allDataCatalogs.filter((dc) => dc.model_id == selectedAttack[0].model_id) : []} | |
| styling="" | |
| onChange={setSelectedDataCatalog} /> | |
| <InvokeComponent | |
| text={invokeButtonText} | |
| action={selectedDataCatalog == null ? null : InvokeAttack} | |
| classNames={`${modalInvokeButtonColor} mt-8` + (selectedDataCatalog !== null ? " cursor-pointer" : "")} /> | |
| </Box> | |
| </Modal> | |
| </div> | |
| </div> | |
| ); | |
| } | |
| export default AttacksPage; |