diff --git a/virtweb_backend/Cargo.lock b/virtweb_backend/Cargo.lock index 42bb251..83c763a 100644 --- a/virtweb_backend/Cargo.lock +++ b/virtweb_backend/Cargo.lock @@ -2159,18 +2159,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-xml-rs" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782" -dependencies = [ - "log", - "serde", - "thiserror", - "xml-rs", -] - [[package]] name = "serde_derive" version = "1.0.193" @@ -2677,7 +2665,6 @@ dependencies = [ "reqwest", "rust-embed", "serde", - "serde-xml-rs", "serde_json", "sysinfo", "tempfile", @@ -2981,12 +2968,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "xml-rs" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" - [[package]] name = "zerocopy" version = "0.7.31" diff --git a/virtweb_backend/Cargo.toml b/virtweb_backend/Cargo.toml index 75caaa4..a5e7125 100644 --- a/virtweb_backend/Cargo.toml +++ b/virtweb_backend/Cargo.toml @@ -22,7 +22,6 @@ actix-web-actors = "4.2.0" actix-http = "3.4.0" serde = { version = "1.0.193", features = ["derive"] } serde_json = "1.0.108" -serde-xml-rs = "0.6.0" quick-xml = { version = "0.31.0", features = ["serialize", "overlapped-lists"] } futures-util = "0.3.28" anyhow = "1.0.75" diff --git a/virtweb_backend/src/controllers/server_controller.rs b/virtweb_backend/src/controllers/server_controller.rs index ba57a7a..ad413ec 100644 --- a/virtweb_backend/src/controllers/server_controller.rs +++ b/virtweb_backend/src/controllers/server_controller.rs @@ -16,7 +16,7 @@ struct StaticConfig { iso_mimetypes: &'static [&'static str], net_mac_prefix: &'static str, constraints: ServerConstraints, - builtin_network_rules: &'static [&'static str], + builtin_nwfilter_rules: &'static [&'static str], } #[derive(serde::Serialize)] @@ -46,7 +46,7 @@ pub async fn static_config(local_auth: LocalAuthEnabled) -> impl Responder { oidc_auth_enabled: !AppConfig::get().disable_oidc, iso_mimetypes: &constants::ALLOWED_ISO_MIME_TYPES, net_mac_prefix: constants::NET_MAC_ADDR_PREFIX, - builtin_network_rules: &constants::BUILTIN_NETWORK_FILTER_RULES, + builtin_nwfilter_rules: &constants::BUILTIN_NETWORK_FILTER_RULES, constraints: ServerConstraints { iso_max_size: constants::ISO_MAX_SIZE, diff --git a/virtweb_frontend/src/App.tsx b/virtweb_frontend/src/App.tsx index 00e7089..580545b 100644 --- a/virtweb_frontend/src/App.tsx +++ b/virtweb_frontend/src/App.tsx @@ -26,6 +26,7 @@ import { BaseAuthenticatedPage } from "./widgets/BaseAuthenticatedPage"; import { BaseLoginPage } from "./widgets/BaseLoginPage"; import { ViewNetworkRoute } from "./routes/ViewNetworkRoute"; import { HomeRoute } from "./routes/HomeRoute"; +import { NetworkFiltersListRoute } from "./routes/NetworkFiltersListRoute"; interface AuthContext { signedIn: boolean; @@ -61,6 +62,8 @@ export function App() { } /> } /> + } /> + } /> } /> diff --git a/virtweb_frontend/src/api/NWFilterApi.ts b/virtweb_frontend/src/api/NWFilterApi.ts index ae6fc4a..1cb9344 100644 --- a/virtweb_frontend/src/api/NWFilterApi.ts +++ b/virtweb_frontend/src/api/NWFilterApi.ts @@ -37,6 +37,10 @@ export interface NWFilter { rules: NWFilterRule[]; } +export function NWFilterURL(n: NWFilter, edit: boolean = false): string { + return `/nwfilter/${n.uuid}${edit ? "/edit" : ""}`; +} + export class NWFilterApi { /** * Get the entire list of networks diff --git a/virtweb_frontend/src/api/NetworksApi.ts b/virtweb_frontend/src/api/NetworksApi.ts index a7f6702..6c86c5d 100644 --- a/virtweb_frontend/src/api/NetworksApi.ts +++ b/virtweb_frontend/src/api/NetworksApi.ts @@ -39,10 +39,6 @@ export function NetworkURL(n: NetworkInfo, edit: boolean = false): string { return `/net/${n.uuid}${edit ? "/edit" : ""}`; } -export function NetworkXMLURL(n: NetworkInfo): string { - return `/net/${n.uuid}/xml`; -} - export class NetworkApi { /** * Create a new network diff --git a/virtweb_frontend/src/api/ServerApi.ts b/virtweb_frontend/src/api/ServerApi.ts index 22a0016..71ea1f7 100644 --- a/virtweb_frontend/src/api/ServerApi.ts +++ b/virtweb_frontend/src/api/ServerApi.ts @@ -7,6 +7,7 @@ export interface ServerConfig { iso_mimetypes: string[]; net_mac_prefix: string; constraints: ServerConstraints; + builtin_nwfilter_rules: string[]; } export interface ServerConstraints { diff --git a/virtweb_frontend/src/api/VMApi.ts b/virtweb_frontend/src/api/VMApi.ts index 12564ef..9f58c46 100644 --- a/virtweb_frontend/src/api/VMApi.ts +++ b/virtweb_frontend/src/api/VMApi.ts @@ -133,10 +133,6 @@ export class VMInfo implements VMInfoInterface { get VNCURL(): string { return `/vm/${this.uuid}/vnc`; } - - get XMLURL(): string { - return `/vm/${this.uuid}/xml`; - } } export class VMApi { diff --git a/virtweb_frontend/src/routes/NetworkFiltersListRoute.tsx b/virtweb_frontend/src/routes/NetworkFiltersListRoute.tsx new file mode 100644 index 0000000..a331857 --- /dev/null +++ b/virtweb_frontend/src/routes/NetworkFiltersListRoute.tsx @@ -0,0 +1,153 @@ +import VisibilityIcon from "@mui/icons-material/Visibility"; +import { + Button, + IconButton, + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + ToggleButton, + ToggleButtonGroup, + Typography, +} from "@mui/material"; +import React from "react"; +import { useNavigate } from "react-router-dom"; +import { NWFilter, NWFilterApi, NWFilterURL } from "../api/NWFilterApi"; +import { AsyncWidget } from "../widgets/AsyncWidget"; +import { RouterLink } from "../widgets/RouterLink"; +import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer"; +import { ServerApi } from "../api/ServerApi"; + +export function NetworkFiltersListRoute(): React.ReactElement { + const [list, setList] = React.useState(); + + const [count] = React.useState(1); + + const load = async () => { + setList(await NWFilterApi.GetList()); + }; + + return ( + } + /> + ); +} + +enum VisibleFilters { + All, + Builtin, + Custom, +} + +function NetworkFiltersListRouteInner(p: { + list: NWFilter[]; +}): React.ReactElement { + const navigate = useNavigate(); + + const [visibleFilters, setVisibleFilters] = React.useState( + VisibleFilters.All + ); + + const filteredList = React.useMemo(() => { + if (visibleFilters === VisibleFilters.All) return p.list; + + const onlyBuiltin = visibleFilters === VisibleFilters.Builtin; + + return p.list.filter( + (f) => + ServerApi.Config.builtin_nwfilter_rules.includes(f.name) === onlyBuiltin + ); + }, [visibleFilters]); + + return ( + + + setVisibleFilters(v)} + aria-label="visible filters" + > + All + Builtin + Custom + + + + + + + + } + > + + + + + Name + Chain + Priority + Referenced filters + # of rules + Actions + + + + {filteredList.map((t) => { + return ( + navigate(NWFilterURL(t))} + > + {t.name} + + {t.chain?.protocol ?? ( + + None + + )} + + + {t.priority ?? ( + + None + + )} + + +
    + {t.join_filters.map((f, n) => ( +
  • {f}
  • + ))} +
+
+ {t.rules.length} + + + + + + + +
+ ); + })} +
+
+
+
+ ); +} diff --git a/virtweb_frontend/src/utils/DebugUtils.ts b/virtweb_frontend/src/utils/DebugUtils.ts new file mode 100644 index 0000000..f6497d9 --- /dev/null +++ b/virtweb_frontend/src/utils/DebugUtils.ts @@ -0,0 +1,5 @@ +export function isDebug(): boolean { + return ( + !import.meta.env.NODE_ENV || import.meta.env.NODE_ENV === "development" + ); +} diff --git a/virtweb_frontend/src/widgets/BaseAuthenticatedPage.tsx b/virtweb_frontend/src/widgets/BaseAuthenticatedPage.tsx index 4a91996..9664591 100644 --- a/virtweb_frontend/src/widgets/BaseAuthenticatedPage.tsx +++ b/virtweb_frontend/src/widgets/BaseAuthenticatedPage.tsx @@ -3,7 +3,9 @@ import { mdiDisc, mdiHome, mdiInformation, - mdiLan + mdiLan, + mdiSecurity, + mdiSecurityNetwork, } from "@mdi/js"; import Icon from "@mdi/react"; import { @@ -17,6 +19,7 @@ import { import { Outlet, useLocation } from "react-router-dom"; import { RouterLink } from "./RouterLink"; import { VirtWebAppBar } from "./VirtWebAppBar"; +import { isDebug } from "../utils/DebugUtils"; export function BaseAuthenticatedPage(): React.ReactElement { return ( @@ -60,6 +63,14 @@ export function BaseAuthenticatedPage(): React.ReactElement { uri="/net" icon={} /> + {/* TODO : remove debug marker */} + {isDebug() && ( + } + /> + )}