Autosuggestion for network interfaces ips

This commit is contained in:
DomySh
2022-07-20 00:21:22 +02:00
parent da2cebfabd
commit 1266aebe0e
12 changed files with 66 additions and 18 deletions
+10 -1
View File
@@ -11,7 +11,7 @@ from passlib.context import CryptContext
from fastapi_socketio import SocketManager from fastapi_socketio import SocketManager
from modules import SQLite, FirewallManager from modules import SQLite, FirewallManager
from modules.firewall import STATUS from modules.firewall import STATUS
from utils import ip_parse, refactor_name, gen_service_id from utils import get_interfaces, ip_parse, refactor_name, gen_service_id
ON_DOCKER = len(sys.argv) > 1 and sys.argv[1] == "DOCKER" ON_DOCKER = len(sys.argv) > 1 and sys.argv[1] == "DOCKER"
DEBUG = len(sys.argv) > 1 and sys.argv[1] == "DEBUG" DEBUG = len(sys.argv) > 1 and sys.argv[1] == "DEBUG"
@@ -365,6 +365,15 @@ async def add_new_service(form: ServiceAddForm, auth: bool = Depends(is_loggined
await refresh_frontend() await refresh_frontend()
return {'status': 'ok', 'service_id': srv_id} return {'status': 'ok', 'service_id': srv_id}
class IpInterface(BaseModel):
addr: str
name: str
@app.get('/api/interfaces', response_model=List[IpInterface])
async def get_ip_interfaces(auth: bool = Depends(is_loggined)):
"""Get a list of ip and ip6 interfaces"""
return get_interfaces()
async def frontend_debug_proxy(path): async def frontend_debug_proxy(path):
httpc = httpx.AsyncClient() httpc = httpx.AsyncClient()
req = httpc.build_request("GET",f"http://127.0.0.1:{os.getenv('F_PORT','3000')}/"+path) req = httpc.build_request("GET",f"http://127.0.0.1:{os.getenv('F_PORT','3000')}/"+path)
+1
View File
@@ -2,6 +2,7 @@ fastapi[all]
httpx httpx
uvicorn[standard] uvicorn[standard]
passlib[bcrypt] passlib[bcrypt]
psutil
python-jose[cryptography] python-jose[cryptography]
fastapi-socketio fastapi-socketio
git+https://salsa.debian.org/pkg-netfilter-team/pkg-nftables#egg=nftables&subdirectory=py git+https://salsa.debian.org/pkg-netfilter-team/pkg-nftables#egg=nftables&subdirectory=py
+9 -1
View File
@@ -1,5 +1,5 @@
from ipaddress import ip_interface from ipaddress import ip_interface
import os, socket, secrets import os, socket, secrets, psutil
LOCALHOST_IP = socket.gethostbyname(os.getenv("LOCALHOST_IP","127.0.0.1")) LOCALHOST_IP = socket.gethostbyname(os.getenv("LOCALHOST_IP","127.0.0.1"))
@@ -20,3 +20,11 @@ def ip_parse(ip:str):
def ip_family(ip:str): def ip_family(ip:str):
return "ip6" if ip_interface(ip).version == 6 else "ip" return "ip6" if ip_interface(ip).version == 6 else "ip"
def get_interfaces():
def _get_interfaces():
for int_name, interfs in psutil.net_if_addrs().items():
for interf in interfs:
if interf.family in [socket.AF_INET, socket.AF_INET6]:
yield {"name": int_name, "addr":interf.address}
return list(_get_interfaces())
+3 -3
View File
@@ -1,13 +1,13 @@
{ {
"files": { "files": {
"main.css": "/static/css/main.08225a85.css", "main.css": "/static/css/main.08225a85.css",
"main.js": "/static/js/main.6bded0d7.js", "main.js": "/static/js/main.10378d73.js",
"index.html": "/index.html", "index.html": "/index.html",
"main.08225a85.css.map": "/static/css/main.08225a85.css.map", "main.08225a85.css.map": "/static/css/main.08225a85.css.map",
"main.6bded0d7.js.map": "/static/js/main.6bded0d7.js.map" "main.10378d73.js.map": "/static/js/main.10378d73.js.map"
}, },
"entrypoints": [ "entrypoints": [
"static/css/main.08225a85.css", "static/css/main.08225a85.css",
"static/js/main.6bded0d7.js" "static/js/main.10378d73.js"
] ]
} }
+1 -1
View File
@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="manifest" href="/site.webmanifest"><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#FFFFFFFF"/><meta name="description" content="Firegex by Pwnzer0tt1"/><title>Firegex</title><script defer="defer" src="/static/js/main.6bded0d7.js"></script><link href="/static/css/main.08225a85.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html> <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="manifest" href="/site.webmanifest"><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#FFFFFFFF"/><meta name="description" content="Firegex by Pwnzer0tt1"/><title>Firegex</title><script defer="defer" src="/static/js/main.10378d73.js"></script><link href="/static/css/main.08225a85.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+26 -5
View File
@@ -1,7 +1,7 @@
import { Button, Group, NumberInput, Space, TextInput, Notification, Modal, Switch, SegmentedControl } from '@mantine/core'; import { Button, Group, NumberInput, Space, TextInput, Notification, Modal, Switch, SegmentedControl, SelectItemProps, Autocomplete, AutocompleteItem } from '@mantine/core';
import { useForm } from '@mantine/hooks'; import { useForm } from '@mantine/hooks';
import React, { useState } from 'react'; import React, { useEffect, useState } from 'react';
import { addservice, okNotify, startservice, regex_ipv4, regex_ipv6 } from '../js/utils'; import { addservice, okNotify, startservice, regex_ipv4, regex_ipv6, getipinterfaces } from '../js/utils';
import { ImCross } from "react-icons/im" import { ImCross } from "react-icons/im"
type ServiceAddForm = { type ServiceAddForm = {
@@ -12,13 +12,23 @@ type ServiceAddForm = {
autostart: boolean, autostart: boolean,
} }
interface ItemProps extends AutocompleteItem {
label: string;
}
const AutoCompleteItem = React.forwardRef<HTMLDivElement, ItemProps>(
({ label, value, ...props }: ItemProps, ref) => <div ref={ref} {...props}>
( <b>{label}</b> ) -{">"} <b>{value}</b>
</div>
);
function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void }) { function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void }) {
const form = useForm({ const form = useForm({
initialValues: { initialValues: {
name:"", name:"",
port:8080, port:8080,
ip_int:"127.0.0.1", ip_int:"",
proto:"tcp", proto:"tcp",
autostart: true autostart: true
}, },
@@ -30,6 +40,14 @@ function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void })
} }
}) })
const [ipInterfaces, setIpInterfaces] = useState<AutocompleteItem[]>([]);
useEffect(()=>{
getipinterfaces().then(data => {
setIpInterfaces(data.map(item => ({label:item.name, value:item.addr})));
})
},[])
const close = () =>{ const close = () =>{
onClose() onClose()
form.reset() form.reset()
@@ -57,6 +75,7 @@ function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void })
}) })
} }
return <Modal size="xl" title="Add a new service" opened={opened} onClose={close} closeOnClickOutside={false} centered> return <Modal size="xl" title="Add a new service" opened={opened} onClose={close} closeOnClickOutside={false} centered>
<form onSubmit={form.onSubmit(submitRequest)}> <form onSubmit={form.onSubmit(submitRequest)}>
<TextInput <TextInput
@@ -66,9 +85,11 @@ function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void })
/> />
<Space h="md" /> <Space h="md" />
<TextInput <Autocomplete
label="Public IP Interface (ipv4/ipv6 + CIDR allowed)" label="Public IP Interface (ipv4/ipv6 + CIDR allowed)"
placeholder="10.1.1.0/24" placeholder="10.1.1.0/24"
itemComponent={AutoCompleteItem}
data={ipInterfaces}
{...form.getInputProps('ip_int')} {...form.getInputProps('ip_int')}
/> />
+5
View File
@@ -75,3 +75,8 @@ export type RegexAddForm = {
mode:string, // C->S S->C BOTH, mode:string, // C->S S->C BOTH,
active: boolean active: boolean
} }
export type IpInterface = {
name:string,
addr:string
}
+5 -1
View File
@@ -1,7 +1,7 @@
import { showNotification } from "@mantine/notifications"; import { showNotification } from "@mantine/notifications";
import { ImCross } from "react-icons/im"; import { ImCross } from "react-icons/im";
import { TiTick } from "react-icons/ti" import { TiTick } from "react-icons/ti"
import { GeneralStats, Service, ServiceAddForm, ServerResponse, RegexFilter, RegexAddForm, ServerStatusResponse, PasswordSend, ChangePassword, LoginResponse, ServerResponseToken, ServiceAddResponse } from "./models"; import { GeneralStats, Service, ServiceAddForm, ServerResponse, RegexFilter, RegexAddForm, ServerStatusResponse, PasswordSend, ChangePassword, LoginResponse, ServerResponseToken, ServiceAddResponse, IpInterface } from "./models";
var Buffer = require('buffer').Buffer var Buffer = require('buffer').Buffer
@@ -54,6 +54,10 @@ export function fireUpdateRequest(){
window.dispatchEvent(new Event(eventUpdateName)) window.dispatchEvent(new Event(eventUpdateName))
} }
export async function getipinterfaces(){
return await getapi("interfaces") as IpInterface[];
}
export async function getstatus(){ export async function getstatus(){
return await getapi(`status`) as ServerStatusResponse; return await getapi(`status`) as ServerStatusResponse;
} }