mirror of
https://github.com/speatzle/nfsense.git
synced 2025-05-10 18:38:22 +00:00
ImplementConfig Referencing System
This commit is contained in:
parent
c2f1845c36
commit
4f7ab04fce
8 changed files with 172 additions and 65 deletions
|
@ -1,6 +1,8 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
|
||||
use super::object::{AddressReference, ServiceReference};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Default, Debug)]
|
||||
pub struct Firewall {
|
||||
pub forward_rules: Vec<ForwardRule>,
|
||||
|
@ -11,9 +13,9 @@ pub struct Firewall {
|
|||
#[derive(Serialize, Deserialize, Clone, Validate, Debug)]
|
||||
pub struct ForwardRule {
|
||||
pub name: String,
|
||||
pub services: Vec<String>,
|
||||
pub source_addresses: Vec<String>,
|
||||
pub destination_addresses: Vec<String>,
|
||||
pub services: Vec<ServiceReference>,
|
||||
pub source_addresses: Vec<AddressReference>,
|
||||
pub destination_addresses: Vec<AddressReference>,
|
||||
pub comment: String,
|
||||
pub counter: bool,
|
||||
pub verdict: Verdict,
|
||||
|
@ -22,21 +24,21 @@ pub struct ForwardRule {
|
|||
#[derive(Serialize, Deserialize, Clone, Validate, Debug)]
|
||||
pub struct DestinationNATRule {
|
||||
pub name: String,
|
||||
pub services: Vec<String>,
|
||||
pub source_addresses: Vec<String>,
|
||||
pub destination_addresses: Vec<String>,
|
||||
pub services: Vec<ServiceReference>,
|
||||
pub source_addresses: Vec<AddressReference>,
|
||||
pub destination_addresses: Vec<AddressReference>,
|
||||
pub comment: String,
|
||||
pub counter: bool,
|
||||
pub dnat_address: Option<String>,
|
||||
pub dnat_service: Option<String>,
|
||||
pub dnat_address: Option<AddressReference>,
|
||||
pub dnat_service: Option<ServiceReference>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Debug)]
|
||||
pub struct SourceNATRule {
|
||||
pub name: String,
|
||||
pub services: Vec<String>,
|
||||
pub source_addresses: Vec<String>,
|
||||
pub destination_addresses: Vec<String>,
|
||||
pub services: Vec<ServiceReference>,
|
||||
pub source_addresses: Vec<AddressReference>,
|
||||
pub destination_addresses: Vec<AddressReference>,
|
||||
pub comment: String,
|
||||
pub counter: bool,
|
||||
pub snat_type: SNATType,
|
||||
|
@ -54,8 +56,8 @@ pub enum Verdict {
|
|||
#[serde(rename_all = "lowercase")]
|
||||
pub enum SNATType {
|
||||
SNAT {
|
||||
address: Option<String>,
|
||||
service: Option<String>,
|
||||
address: Option<AddressReference>,
|
||||
service: Option<ServiceReference>,
|
||||
},
|
||||
Masquerade,
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use self::config::Config;
|
||||
|
||||
pub mod config;
|
||||
pub mod firewall;
|
||||
pub mod network;
|
||||
|
@ -6,16 +8,49 @@ pub mod service;
|
|||
pub mod system;
|
||||
pub mod vpn;
|
||||
|
||||
pub trait Referenceable<T> {
|
||||
fn named_get(&self, name: String) -> T;
|
||||
fn named_exists(&self, name: String) -> bool;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! get_thing {
|
||||
($out:ty, $n:ident) => {
|
||||
pub fn $n(list: Vec<$out>, name: String) -> Option<$out> {
|
||||
for e in list {
|
||||
if e.name == name {
|
||||
return Some(e);
|
||||
macro_rules! impl_referenceable_trait {
|
||||
($typ:ty, $ele:ty) => {
|
||||
impl Referenceable<$ele> for $typ {
|
||||
fn named_get(&self, name: String) -> $ele {
|
||||
let index = self.iter().position(|e| *e.name == name);
|
||||
|
||||
match index {
|
||||
Some(i) => self[i].clone(),
|
||||
// This is fine since the config always has to validated before commiting
|
||||
None => panic!("Referenced Thing: '{:?}' does not exist ", name),
|
||||
}
|
||||
}
|
||||
None
|
||||
|
||||
fn named_exists(&self, name: String) -> bool {
|
||||
let index = self.iter().position(|e| *e.name == name);
|
||||
index.is_some()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub trait References<T> {
|
||||
fn get_ref(&self, config: Config) -> T;
|
||||
fn ref_exists(&self, config: Config) -> bool;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_references_trait {
|
||||
($thing:ty, $referenced:ty, $( $path:ident ).+) => {
|
||||
impl References<$referenced> for $thing {
|
||||
fn get_ref(&self, config: Config) -> $referenced {
|
||||
config.$($path).+.named_get(self.clone())
|
||||
}
|
||||
|
||||
fn ref_exists(&self, config: Config) -> bool {
|
||||
config.$($path).+.named_exists(self.clone())
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,14 +3,29 @@ use serde::{Deserialize, Serialize};
|
|||
use std::net::IpAddr;
|
||||
use validator::Validate;
|
||||
|
||||
use crate::get_thing;
|
||||
use crate::definitions::Referenceable;
|
||||
use crate::{impl_referenceable_trait, impl_references_trait};
|
||||
|
||||
use super::config::Config;
|
||||
use super::object::AddressReference;
|
||||
use super::References;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Default, Debug)]
|
||||
pub struct Network {
|
||||
pub interfaces: Vec<NetworkInterface>,
|
||||
pub interfaces: NetworkInterfaces,
|
||||
pub static_routes: Vec<StaticRoute>,
|
||||
}
|
||||
|
||||
type NetworkInterfaces = Vec<NetworkInterface>;
|
||||
impl_referenceable_trait!(NetworkInterfaces, NetworkInterface);
|
||||
|
||||
pub type NetworkInterfaceReference = String;
|
||||
impl_references_trait!(
|
||||
NetworkInterfaceReference,
|
||||
NetworkInterface,
|
||||
network.interfaces
|
||||
);
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Debug)]
|
||||
pub struct NetworkInterface {
|
||||
pub name: String,
|
||||
|
@ -20,29 +35,38 @@ pub struct NetworkInterface {
|
|||
pub addressing_mode: AddressingMode,
|
||||
}
|
||||
|
||||
get_thing!(NetworkInterface, get_network_interface);
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum NetworkInterfaceType {
|
||||
Hardware { device: String },
|
||||
Vlan { id: i32, parent: String },
|
||||
Bond { members: Vec<String> },
|
||||
Bridge { members: Vec<String> },
|
||||
// TODO figure out how to validate the device since it needs to soft fail
|
||||
Hardware {
|
||||
device: String,
|
||||
},
|
||||
Vlan {
|
||||
id: i32,
|
||||
parent: NetworkInterfaceReference,
|
||||
},
|
||||
Bond {
|
||||
members: Vec<NetworkInterfaceReference>,
|
||||
},
|
||||
Bridge {
|
||||
members: Vec<NetworkInterfaceReference>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AddressingMode {
|
||||
None,
|
||||
Static { address: String },
|
||||
Static { address: AddressReference },
|
||||
DHCP,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Debug)]
|
||||
pub struct StaticRoute {
|
||||
pub name: String,
|
||||
pub interface: String,
|
||||
pub interface: NetworkInterfaceReference,
|
||||
// TODO make this a Address Object Reference?
|
||||
pub gateway: IpAddr,
|
||||
pub destination: IpNet,
|
||||
pub metric: u64,
|
||||
|
|
|
@ -3,14 +3,24 @@ use serde::{Deserialize, Serialize};
|
|||
use std::net::IpAddr;
|
||||
use validator::Validate;
|
||||
|
||||
use crate::get_thing;
|
||||
// Referencing
|
||||
use crate::definitions::config::Config;
|
||||
use crate::definitions::Referenceable;
|
||||
use crate::definitions::References;
|
||||
use crate::{impl_referenceable_trait, impl_references_trait};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Default, Debug)]
|
||||
pub struct Object {
|
||||
pub addresses: Vec<Address>,
|
||||
pub services: Vec<Service>,
|
||||
pub addresses: Addresses,
|
||||
pub services: Services,
|
||||
}
|
||||
|
||||
type Addresses = Vec<Address>;
|
||||
impl_referenceable_trait!(Addresses, Address);
|
||||
|
||||
pub type AddressReference = String;
|
||||
impl_references_trait!(AddressReference, Address, object.addresses);
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Debug)]
|
||||
pub struct Address {
|
||||
pub name: String,
|
||||
|
@ -18,17 +28,21 @@ pub struct Address {
|
|||
pub comment: String,
|
||||
}
|
||||
|
||||
get_thing!(Address, get_address);
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AddressType {
|
||||
Host { address: String },
|
||||
Host { address: IpAddr },
|
||||
Range { range: IpAddr },
|
||||
Network { network: IpNet },
|
||||
Group { members: Vec<String> },
|
||||
Group { members: Vec<AddressReference> },
|
||||
}
|
||||
|
||||
type Services = Vec<Service>;
|
||||
impl_referenceable_trait!(Services, Service);
|
||||
|
||||
pub type ServiceReference = String;
|
||||
impl_references_trait!(ServiceReference, Service, object.services);
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Debug)]
|
||||
pub struct Service {
|
||||
pub name: String,
|
||||
|
@ -36,8 +50,6 @@ pub struct Service {
|
|||
pub comment: String,
|
||||
}
|
||||
|
||||
get_thing!(Service, get_service);
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum ServiceType {
|
||||
|
@ -53,7 +65,7 @@ pub enum ServiceType {
|
|||
code: u8,
|
||||
},
|
||||
Group {
|
||||
members: Vec<String>,
|
||||
members: Vec<ServiceReference>,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use core::time;
|
||||
use macaddr::MacAddr8;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::net::IpAddr;
|
||||
use validator::Validate;
|
||||
|
||||
use super::{network::NetworkInterfaceReference, object::AddressReference};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Default, Debug)]
|
||||
pub struct Service {
|
||||
pub dhcp_servers: Vec<DHCPServer>,
|
||||
|
@ -13,8 +14,8 @@ pub struct Service {
|
|||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Debug)]
|
||||
pub struct DHCPServer {
|
||||
pub interface: String,
|
||||
pub pool: Vec<String>,
|
||||
pub interface: NetworkInterfaceReference,
|
||||
pub pool: Vec<AddressReference>,
|
||||
pub lease_time: time::Duration,
|
||||
pub gateway_mode: GatewayMode,
|
||||
pub dns_server_mode: DNSServerMode,
|
||||
|
@ -25,13 +26,13 @@ pub struct DHCPServer {
|
|||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Default, Debug)]
|
||||
pub struct DNSServer {
|
||||
pub interface: String,
|
||||
pub interface: NetworkInterfaceReference,
|
||||
pub comment: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Default, Debug)]
|
||||
pub struct NTPServer {
|
||||
pub interface: String,
|
||||
pub interface: NetworkInterfaceReference,
|
||||
pub comment: String,
|
||||
}
|
||||
|
||||
|
@ -40,7 +41,7 @@ pub struct NTPServer {
|
|||
pub enum GatewayMode {
|
||||
None,
|
||||
Interface,
|
||||
Specify { gateway: String },
|
||||
Specify { gateway: AddressReference },
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
|
@ -48,7 +49,7 @@ pub enum GatewayMode {
|
|||
pub enum DNSServerMode {
|
||||
None,
|
||||
Interface,
|
||||
Specify { dns_servers: Vec<String> },
|
||||
Specify { dns_servers: Vec<AddressReference> },
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
|
@ -56,12 +57,12 @@ pub enum DNSServerMode {
|
|||
pub enum NTPServerMode {
|
||||
None,
|
||||
Interface,
|
||||
Specify { ntp_servers: Vec<String> },
|
||||
Specify { ntp_servers: Vec<AddressReference> },
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Reservation {
|
||||
pub ip_address: IpAddr,
|
||||
pub ip_address: AddressReference,
|
||||
pub hardware_address: MacAddr8,
|
||||
pub comment: String,
|
||||
}
|
||||
|
|
|
@ -1,18 +1,26 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
|
||||
use crate::get_thing;
|
||||
// Referencing
|
||||
use crate::definitions::config::Config;
|
||||
use crate::definitions::Referenceable;
|
||||
use crate::definitions::References;
|
||||
use crate::{impl_referenceable_trait, impl_references_trait};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Default, Debug)]
|
||||
pub struct System {
|
||||
pub users: Vec<User>,
|
||||
}
|
||||
|
||||
type Users = Vec<User>;
|
||||
impl_referenceable_trait!(Users, User);
|
||||
|
||||
pub type UserReference = String;
|
||||
impl_references_trait!(UserReference, User, system.users);
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Default, Debug)]
|
||||
pub struct User {
|
||||
pub name: String,
|
||||
pub comment: String,
|
||||
pub hash: String,
|
||||
}
|
||||
|
||||
get_thing!(User, get_user);
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
|
||||
use crate::get_thing;
|
||||
// Referencing
|
||||
use crate::definitions::config::Config;
|
||||
use crate::definitions::Referenceable;
|
||||
use crate::definitions::References;
|
||||
use crate::{impl_referenceable_trait, impl_references_trait};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Default, Debug)]
|
||||
pub struct VPN {
|
||||
|
@ -10,21 +14,35 @@ pub struct VPN {
|
|||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Default, Debug)]
|
||||
pub struct Wireguard {
|
||||
pub interfaces: Vec<WireguardInterface>,
|
||||
pub peers: Vec<WireguardPeer>,
|
||||
pub interfaces: WireguardInterfaces,
|
||||
pub peers: WireguardPeers,
|
||||
}
|
||||
|
||||
type WireguardInterfaces = Vec<WireguardInterface>;
|
||||
impl_referenceable_trait!(WireguardInterfaces, WireguardInterface);
|
||||
|
||||
pub type WireguardInterfaceReference = String;
|
||||
impl_references_trait!(
|
||||
WireguardInterfaceReference,
|
||||
WireguardInterface,
|
||||
vpn.wireguard.interfaces
|
||||
);
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Debug)]
|
||||
pub struct WireguardInterface {
|
||||
pub name: String,
|
||||
pub public_key: String,
|
||||
pub private_key: String,
|
||||
pub listen_port: u64,
|
||||
pub peers: Vec<String>,
|
||||
pub peers: Vec<WireguardPeerReference>,
|
||||
pub comment: String,
|
||||
}
|
||||
|
||||
get_thing!(WireguardInterface, get_wireguard_interface);
|
||||
pub type WireguardPeers = Vec<WireguardPeer>;
|
||||
impl_referenceable_trait!(WireguardPeers, WireguardPeer);
|
||||
|
||||
type WireguardPeerReference = String;
|
||||
impl_references_trait!(WireguardPeerReference, WireguardPeer, vpn.wireguard.peers);
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Validate, Debug)]
|
||||
pub struct WireguardPeer {
|
||||
|
@ -36,5 +54,3 @@ pub struct WireguardPeer {
|
|||
pub persistent_keepalive: Option<u64>,
|
||||
pub comment: String,
|
||||
}
|
||||
|
||||
get_thing!(WireguardPeer, get_wireguard_peer);
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
use crate::definitions::Referenceable;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use rbtag::BuildInfo;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::definitions::system::get_user;
|
||||
|
||||
use super::super::AppState;
|
||||
use axum::routing::post;
|
||||
use axum::{Json, Router};
|
||||
|
@ -66,10 +65,20 @@ async fn login_handler(
|
|||
State(state): State<AppState>,
|
||||
Json(payload): Json<LoginParameters>,
|
||||
) -> impl IntoResponse {
|
||||
if let Some(user) = get_user(
|
||||
state.config_manager.get_current_config().system.users,
|
||||
payload.username.to_string(),
|
||||
) {
|
||||
if state
|
||||
.config_manager
|
||||
.get_current_config()
|
||||
.system
|
||||
.users
|
||||
.named_exists(payload.username.to_string())
|
||||
{
|
||||
let user = state
|
||||
.config_manager
|
||||
.get_current_config()
|
||||
.system
|
||||
.users
|
||||
.named_get(payload.username.to_string());
|
||||
|
||||
if sha512_crypt::verify(payload.password, &user.hash) {
|
||||
let mut sessions = state.session_state.sessions.write().unwrap();
|
||||
let id = Uuid::new_v4().to_string();
|
||||
|
|
Loading…
Add table
Reference in a new issue