refactor: Remove unused code and restructure modules

This commit is contained in:
DaLaw2 2026-04-27 23:59:33 +08:00
parent b7ee352ca5
commit d36d6d8e8e
33 changed files with 115 additions and 129 deletions

View File

@ -143,6 +143,14 @@ impl AccessControl {
}
impl AccessControlAdminPort for AccessControl {
fn get_ipv4_list(&self, direction: FlowDirection, list_type: ListType) -> HashMap<Ipv4Addr, Vec<Port>> {
self.get_ipv4_list(direction, list_type)
}
fn get_ipv6_list(&self, direction: FlowDirection, list_type: ListType) -> HashMap<Ipv6Addr, Vec<Port>> {
self.get_ipv6_list(direction, list_type)
}
fn add_ipv4_list(&self, direction: FlowDirection, list_type: ListType, address: SocketAddrV4) -> Result<(), Error> {
self.add_ipv4_list(direction, list_type, address)
}
@ -168,14 +176,6 @@ impl AccessControlAdminPort for AccessControl {
) -> Result<(), Error> {
self.remove_ipv6_list(direction, list_type, address)
}
fn get_ipv4_list(&self, direction: FlowDirection, list_type: ListType) -> HashMap<Ipv4Addr, Vec<Port>> {
self.get_ipv4_list(direction, list_type)
}
fn get_ipv6_list(&self, direction: FlowDirection, list_type: ListType) -> HashMap<Ipv6Addr, Vec<Port>> {
self.get_ipv6_list(direction, list_type)
}
}
struct MapWrapper<T> {

View File

@ -1,4 +1,3 @@
use std::mem;
use std::net::Ipv6Addr;
use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
@ -152,12 +151,12 @@ fn reason_to_str(reason: u8) -> &'static str {
}
}
/// Start the ring buffer consumer as a tokio task. Returns a shutdown sender.
pub async fn start_consumer(ring_buf: RingBuf<MapData>, monitor: Arc<DropMonitor>) -> oneshot::Sender<()> {
let (shutdown_tx, mut shutdown_rx) = oneshot::channel();
tokio::spawn(async move {
let mut ring_buf = ring_buf;
// todo add interval value to config
let mut interval = interval(Duration::from_millis(100));
loop {
@ -167,7 +166,7 @@ pub async fn start_consumer(ring_buf: RingBuf<MapData>, monitor: Arc<DropMonitor
}
while let Some(item) = ring_buf.next() {
if item.len() >= mem::size_of::<RawDropEvent>() {
if item.len() >= size_of::<RawDropEvent>() {
let event = unsafe { &*(item.as_ptr() as *const RawDropEvent) };
monitor.process_event(event);
}

View File

@ -15,9 +15,8 @@ use crate::domain::common::error::misc::MiscError;
use crate::domain::data_plane::error::EbpfError;
use crate::interface::geo_block_api::GeoBlockPort;
/// Pre-indexed GeoIP prefix table, built once at startup.
struct GeoIndex {
v4: StdHashMap<String, Vec<(u32, u32)>>, // country -> [(ip_be, prefix_len)]
v4: StdHashMap<String, Vec<(u32, u32)>>,
v6: StdHashMap<String, Vec<(u128, u32)>>,
}
@ -36,6 +35,7 @@ impl GeoBlock {
let v6_map = ebpf.take_map("GEO_BLOCK_V6").ok_or(EbpfError::MapNotFound)?;
let v6_trie = LpmTrie::try_from(v6_map).map_err(EbpfError::MapOperationError)?;
// todo read config from AppConfig, not db
let db_path = app_config.load().acl.geoip_db_name.clone();
let reader = Reader::open_readfile(&db_path).map_err(|e| MiscError::GeoIPDatabaseError(db_path.clone(), e))?;
@ -49,10 +49,6 @@ impl GeoBlock {
})
}
/// Construct a GeoBlock with no eBPF trie backing. Attempts to still load
/// the GeoIP index so the frontend can list what *would* be enforced;
/// mutating calls (`block_countries`, `unblock_countries`) return
/// `EbpfError::NotLoaded`.
pub fn unavailable(app_config: Arc<ArcSwap<AppConfig>>) -> Self {
let index = Reader::open_readfile(&app_config.load().acl.geoip_db_name)
.ok()
@ -69,7 +65,6 @@ impl GeoBlock {
}
}
/// Build index from MaxMind DB at startup. One-time cost.
fn build_index(reader: &Reader<Vec<u8>>) -> Result<GeoIndex, Error> {
let mut v4: StdHashMap<String, Vec<(u32, u32)>> = StdHashMap::new();
let mut v6: StdHashMap<String, Vec<(u128, u32)>> = StdHashMap::new();
@ -115,7 +110,10 @@ impl GeoBlock {
Ok(GeoIndex { v4, v6 })
}
/// Block multiple countries at once, rebuilding tries only once.
pub fn get_blocked_countries(&self) -> Vec<String> {
self.blocked_countries.load().iter().cloned().collect()
}
pub fn block_countries(&self, country_codes: &[String]) -> Result<u64, Error> {
self.blocked_countries.rcu(|cur| {
let mut next: HashSet<String> = (**cur).clone();
@ -130,7 +128,6 @@ impl GeoBlock {
self.rebuild_tries()
}
/// Unblock multiple countries at once, rebuilding tries only once.
pub fn unblock_countries(&self, country_codes: &[String]) -> Result<u64, Error> {
self.blocked_countries.rcu(|cur| {
let mut next: HashSet<String> = (**cur).clone();
@ -142,15 +139,9 @@ impl GeoBlock {
self.rebuild_tries()
}
pub fn get_blocked_countries(&self) -> Vec<String> {
self.blocked_countries.load().iter().cloned().collect()
}
/// Rebuild LPM tries from pre-indexed data. Fast — no DB scan.
fn rebuild_tries(&self) -> Result<u64, Error> {
let countries = self.blocked_countries.load_full();
// Collect entries from index (no DB scan)
let mut v4_entries: Vec<(Key<u32>, u8)> = Vec::new();
let mut v6_entries: Vec<(Key<u128>, u8)> = Vec::new();
@ -167,7 +158,6 @@ impl GeoBlock {
}
}
// Lock, clear, insert
let mut v4_guard = self.geo_block_v4.write();
let mut v6_guard = self.geo_block_v6.write();
let (v4_trie, v6_trie) = match (v4_guard.as_mut(), v6_guard.as_mut()) {
@ -208,6 +198,10 @@ impl GeoBlock {
}
impl GeoBlockPort for GeoBlock {
fn list_blocked(&self) -> Vec<String> {
self.get_blocked_countries()
}
fn block_countries(&self, codes: &[String]) -> Result<u64, Error> {
self.block_countries(codes)
}
@ -215,8 +209,4 @@ impl GeoBlockPort for GeoBlock {
fn unblock_countries(&self, codes: &[String]) -> Result<u64, Error> {
self.unblock_countries(codes)
}
fn list_blocked(&self) -> Vec<String> {
self.get_blocked_countries()
}
}

View File

@ -1,5 +1,5 @@
use std::collections::HashMap;
use std::net::{IpAddr, SocketAddr};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use aya::maps::{Array as AyaArray, HashMap as AyaHashMap, MapData};
use aya::{Ebpf, Pod};
@ -56,28 +56,28 @@ impl ProtocolFilter {
}
}
fn require_v4_socket(addr: SocketAddr) -> Result<std::net::SocketAddrV4, Error> {
fn require_v4_socket(addr: SocketAddr) -> Result<SocketAddrV4, Error> {
match addr {
SocketAddr::V4(a) => Ok(a),
SocketAddr::V6(_) => Err(EbpfError::IpVersionMismatch("IPv4".to_string()))?,
}
}
fn require_v6_socket(addr: SocketAddr) -> Result<std::net::SocketAddrV6, Error> {
fn require_v6_socket(addr: SocketAddr) -> Result<SocketAddrV6, Error> {
match addr {
SocketAddr::V6(a) => Ok(a),
SocketAddr::V4(_) => Err(EbpfError::IpVersionMismatch("IPv6".to_string()))?,
}
}
fn require_v4_ip(ip: IpAddr) -> Result<std::net::Ipv4Addr, Error> {
fn require_v4_ip(ip: IpAddr) -> Result<Ipv4Addr, Error> {
match ip {
IpAddr::V4(a) => Ok(a),
IpAddr::V6(_) => Err(EbpfError::IpVersionMismatch("IPv4".to_string()))?,
}
}
fn require_v6_ip(ip: IpAddr) -> Result<std::net::Ipv6Addr, Error> {
fn require_v6_ip(ip: IpAddr) -> Result<Ipv6Addr, Error> {
match ip {
IpAddr::V6(a) => Ok(a),
IpAddr::V4(_) => Err(EbpfError::IpVersionMismatch("IPv6".to_string()))?,

View File

@ -83,30 +83,39 @@ impl RateLimitPort for RateLimitConfig {
fn set_packet_rate(&self, rate: u64) -> Result<(), Error> {
self.set_packet_rate(rate)
}
fn set_syn_rate(&self, rate: u64) -> Result<(), Error> {
self.set_syn_rate(rate)
}
fn set_udp_rate(&self, rate: u64) -> Result<(), Error> {
self.set_udp_rate(rate)
}
fn set_dns_rate(&self, rate: u64) -> Result<(), Error> {
self.set_dns_rate(rate)
}
fn set_window_ns(&self, ns: u64) -> Result<(), Error> {
self.set_window_ns(ns)
}
fn get_packet_rate(&self) -> Result<u64, Error> {
self.get_packet_rate()
}
fn get_syn_rate(&self) -> Result<u64, Error> {
self.get_syn_rate()
}
fn get_udp_rate(&self) -> Result<u64, Error> {
self.get_udp_rate()
}
fn get_dns_rate(&self) -> Result<u64, Error> {
self.get_dns_rate()
}
fn get_window_ns(&self) -> Result<u64, Error> {
self.get_window_ns()
}

View File

@ -30,7 +30,6 @@ use crate::interface::dns_query_filter::DnsQueryFilter;
use crate::interface::packet_sink::{PacketSink, PacketSinkFactory};
use crate::utils::packet_parser::parse_packet;
/// Pre-allocated buffer pool to avoid per-packet malloc.
struct BufferPool {
buffers: Vec<Vec<u8>>,
buffer_size: usize,
@ -63,7 +62,7 @@ impl BufferPool {
pub struct XskManager {
app_config: Arc<ArcSwap<AppConfig>>,
xsk_map: Mutex<Option<XskMap<MapData>>>,
ingress_xsk_map: Mutex<Option<XskMap<MapData>>>,
egress_xsk_map: Mutex<Option<XskMap<MapData>>>,
}
@ -73,17 +72,17 @@ impl XskManager {
ingress_ebpf: &mut Ebpf,
egress_ebpf: &mut Ebpf,
) -> Result<Self, Error> {
let map = ingress_ebpf
let ingress_map = ingress_ebpf
.take_map("INGRESS_XSKS_MAP")
.ok_or(EbpfError::MapNotFound)?;
let xsk_map = XskMap::try_from(map).map_err(EbpfError::MapOperationError)?;
let ingress_xsk_map = XskMap::try_from(ingress_map).map_err(EbpfError::MapOperationError)?;
let egress_map = egress_ebpf.take_map("EGRESS_XSKS_MAP").ok_or(EbpfError::MapNotFound)?;
let egress_xsk_map = XskMap::try_from(egress_map).map_err(EbpfError::MapOperationError)?;
Ok(Self {
app_config,
xsk_map: Mutex::new(Some(xsk_map)),
ingress_xsk_map: Mutex::new(Some(ingress_xsk_map)),
egress_xsk_map: Mutex::new(Some(egress_xsk_map)),
})
}
@ -91,7 +90,7 @@ impl XskManager {
pub fn unavailable(app_config: Arc<ArcSwap<AppConfig>>) -> Self {
Self {
app_config,
xsk_map: Mutex::new(None),
ingress_xsk_map: Mutex::new(None),
egress_xsk_map: Mutex::new(None),
}
}
@ -103,10 +102,11 @@ impl XskManager {
drop_monitor: Option<Arc<DropMonitor>>,
shutdowns: &SegQueue<oneshot::Sender<()>>,
) -> Result<(), Error> {
// todo need to check logic
// If eBPF failed to load, there are no XSK maps to bind and no queues
// to start — skip silently. AF_XDP would have no maps to attach sockets
// to, and ML sees no packets, which is the designed behaviour.
if self.xsk_map.lock().is_none() || self.egress_xsk_map.lock().is_none() {
if self.ingress_xsk_map.lock().is_none() || self.egress_xsk_map.lock().is_none() {
return Ok(());
}
@ -139,13 +139,13 @@ impl XskManager {
drop_monitor.clone(),
)?;
let mut xsk_guard = self.xsk_map.lock();
let mut ingress_guard = self.ingress_xsk_map.lock();
let mut egress_guard = self.egress_xsk_map.lock();
let xsk_map = xsk_guard.as_mut().ok_or(EbpfError::NotLoaded)?;
let ingress_xsk_map = ingress_guard.as_mut().ok_or(EbpfError::NotLoaded)?;
let egress_xsk_map = egress_guard.as_mut().ok_or(EbpfError::NotLoaded)?;
let ingress_fd = ingress_xsk.rx.fd().as_raw_fd();
xsk_map
ingress_xsk_map
.set(queue_id, ingress_fd, 0)
.map_err(EbpfError::AfXdpSetFailed)?;
@ -154,7 +154,7 @@ impl XskManager {
.set(queue_id, egress_fd, 0)
.map_err(EbpfError::AfXdpSetFailed)?;
drop(xsk_guard);
drop(ingress_guard);
drop(egress_guard);
let ingress_shutdown = ingress_xsk.run(ingress_to_egress_tx, egress_to_ingress_rx)?;

View File

@ -3,7 +3,7 @@ use std::net::{SocketAddrV4, SocketAddrV6};
use actix_web::{HttpResponse, Responder, Scope, web};
use serde::Deserialize;
use crate::adapter::http::response::ok_or_error;
use crate::adapter::http::helpers::ok_or_error;
use crate::core::data_plane::acl_service::AclService;
use crate::domain::data_plane::direction::FlowDirection;
use crate::domain::data_plane::list_type::ListType;

View File

@ -4,7 +4,7 @@ use actix_web::{HttpResponse, Responder, Scope, web};
use common::model::http_method::HttpMethod;
use serde::Deserialize;
use crate::adapter::http::response::ok_or_error;
use crate::adapter::http::helpers::ok_or_error;
use crate::core::data_plane::dns_filter_service::DnsFilterService;
use crate::interface::protocol_filter::{IpVersion, ProtocolFilterPort};

View File

@ -0,0 +1,3 @@
pub mod acl;
pub mod filter;
pub mod rate_limit;

View File

@ -1,7 +1,7 @@
use actix_web::{HttpResponse, Responder, Scope, web};
use common::define::setting::*;
use crate::adapter::http::response::ok_or_error;
use crate::adapter::http::helpers::ok_or_error;
use crate::core::data_plane::rate_limit_service::RateLimitService;
use crate::domain::common::system::rate_limit_settings::RateLimitSettings;

View File

@ -0,0 +1,7 @@
pub mod byo;
pub mod flow_trace;
pub mod fusion;
pub mod health;
pub mod ml;
pub mod model_upload;
pub mod stats;

View File

@ -1,8 +1,8 @@
use actix_web::{HttpResponse, Responder, Scope, web};
use serde::Deserialize;
use crate::adapter::http::helpers::ok_or_error;
use crate::adapter::http::middleware::extractor::AuthClaims;
use crate::adapter::http::response::ok_or_error;
use crate::core::identity::auth_service::{AuthService, LoginError, RegisterError};
use crate::domain::identity::auth::{DEFAULT_ADMIN_USERNAME, GROUP_ADMIN, GROUP_VIEWER, ROLE_ADMIN, ROLE_VIEWER};
use crate::domain::identity::password;

View File

@ -0,0 +1,2 @@
pub mod api_keys;
pub mod auth;

View File

@ -1,24 +1,13 @@
pub mod acl;
pub mod api_keys;
pub mod audit;
pub mod auth;
pub mod byo;
pub mod data_plane;
pub mod default;
pub mod filter;
pub mod flow_trace;
pub mod fusion;
pub mod health;
pub mod detection;
pub mod helpers;
pub mod identity;
pub mod jwt;
pub mod logs;
pub mod middleware;
pub mod ml;
pub mod model_upload;
pub mod notification;
pub mod rate_limit;
pub mod ready;
pub mod report;
pub mod response;
pub mod setup;
pub mod soar;
pub mod stats;
pub mod system;

View File

@ -0,0 +1,3 @@
pub mod notification;
pub mod report;
pub mod soar;

View File

@ -1,8 +1,8 @@
use actix_web::{HttpResponse, Scope, web};
use serde::Deserialize;
use crate::adapter::http::helpers::{ok_json_or_error, ok_or_error};
use crate::adapter::http::middleware::extractor::AuthClaims;
use crate::adapter::http::response::{ok_json_or_error, ok_or_error};
use crate::core::common::notification_service::NotificationService;
pub fn initialize() -> Scope {

View File

@ -5,8 +5,8 @@ use arc_swap::ArcSwap;
use chrono::Local;
use tokio::task::spawn_blocking;
use crate::adapter::http::helpers::ok_json_or_error;
use crate::adapter::http::middleware::extractor::AuthClaims;
use crate::adapter::http::response::ok_json_or_error;
use crate::adapter::notification::smtp::SmtpClient;
use crate::adapter::persistence::Database;
use crate::core::reporting::email_report::generate_weekly_report;

View File

@ -4,8 +4,8 @@ use actix_web::{HttpResponse, Scope, web};
use arc_swap::ArcSwap;
use serde::Deserialize;
use crate::adapter::http::helpers::{ok_json_or_error, ok_or_error};
use crate::adapter::http::middleware::extractor::AuthClaims;
use crate::adapter::http::response::{ok_json_or_error, ok_or_error};
use crate::core::response::engine::SoarEngine;
use crate::core::response::playbook_service::PlaybookService;
use crate::domain::common::config::AppConfig;

View File

@ -61,6 +61,7 @@ async fn set_enforce_mode(
}
async fn get_xdp_mode(db: web::Data<Repo>) -> impl Responder {
// todo get from config, not db
let ingress = db
.get_setting("xdp_ingress_mode")
.ok()

View File

@ -11,17 +11,19 @@ use macros::log;
use tokio::sync::broadcast;
use crate::adapter::ebpf::EbpfServices;
use crate::adapter::http::data_plane::{acl, filter, rate_limit as rate_limit_api};
use crate::adapter::http::default;
use crate::adapter::http::detection::model_upload::PromoteGate;
use crate::adapter::http::detection::{byo, flow_trace, fusion, health as health_api, ml, model_upload, stats};
use crate::adapter::http::identity::{api_keys, auth};
use crate::adapter::http::jwt::JwtService;
use crate::adapter::http::middleware::auth::AuthMiddleware;
use crate::adapter::http::middleware::csrf::CsrfMiddleware;
use crate::adapter::http::middleware::https_redirect::HttpsRedirect;
use crate::adapter::http::middleware::setup_guard::SetupGuard;
use crate::adapter::http::model_upload::PromoteGate;
use crate::adapter::http::{
acl, api_keys, audit as audit_api, auth, byo, default, filter, flow_trace, fusion, health as health_api,
logs as logs_api, ml, model_upload, notification as notification_api, rate_limit as rate_limit_api, ready,
report as report_api, setup as setup_api, soar, stats, system as system_api,
};
use crate::adapter::http::ready;
use crate::adapter::http::response::{notification as notification_api, report as report_api, soar};
use crate::adapter::http::{audit as audit_api, logs as logs_api, setup as setup_api, system as system_api};
use crate::adapter::persistence::Database;
use crate::adapter::websocket::routes as ws;
use crate::core::common::config_service::ConfigService;
@ -54,8 +56,6 @@ use crate::interface::app_repo::AppRepo;
use crate::interface::audit::AuditRepo;
use crate::interface::drop_stats::DropStatsPort;
use crate::interface::protocol_filter::ProtocolFilterPort;
use crate::interface::secret_store::SecretStorePort;
use crate::interface::token_minter::TokenMinter;
#[derive(Clone)]
pub struct SetupCompleteFlag(pub Arc<AtomicBool>);
@ -155,32 +155,12 @@ fn is_private_origin(origin: &str) -> bool {
}
pub struct SetupServerParams {
database: Arc<Database>,
secret_store: Arc<SecretStore>,
jwt_service: Arc<JwtService>,
auth_service: Arc<AuthService>,
setup_complete: SetupCompleteFlag,
port: u16,
}
impl SetupServerParams {
pub fn build(database: Arc<Database>, setup_complete: SetupCompleteFlag, port: u16) -> Result<Self, Error> {
let secret_store = Arc::new(SecretStore::new(database.clone()));
let secrets: Arc<dyn SecretStorePort> = secret_store.clone();
let jwt_service = Arc::new(JwtService::new(&secrets, 24)?);
let auth_service = Arc::new(AuthService::new(
database.clone() as Arc<dyn AppRepo>,
jwt_service.clone() as Arc<dyn TokenMinter>,
));
Ok(Self {
database,
secret_store,
jwt_service,
auth_service,
setup_complete,
port,
})
}
pub database: Arc<Database>,
pub secret_store: Arc<SecretStore>,
pub jwt_service: Arc<JwtService>,
pub auth_service: Arc<AuthService>,
pub setup_complete: SetupCompleteFlag,
pub port: u16,
}
pub fn start_setup_server(params: SetupServerParams) -> Result<ServerHandle, Error> {

View File

@ -13,6 +13,10 @@ use crate::domain::data_plane::list_type::ListType;
/// `unblock_ip` for SOAR). `AclService` uses this richer API to serve the
/// `/api/acl` HTTP routes.
pub trait AccessControlAdminPort: Send + Sync {
fn get_ipv4_list(&self, direction: FlowDirection, list_type: ListType) -> HashMap<Ipv4Addr, Vec<Port>>;
fn get_ipv6_list(&self, direction: FlowDirection, list_type: ListType) -> HashMap<Ipv6Addr, Vec<Port>>;
fn add_ipv4_list(&self, direction: FlowDirection, list_type: ListType, address: SocketAddrV4) -> Result<(), Error>;
fn add_ipv6_list(&self, direction: FlowDirection, list_type: ListType, address: SocketAddrV6) -> Result<(), Error>;
@ -30,8 +34,4 @@ pub trait AccessControlAdminPort: Send + Sync {
list_type: ListType,
address: SocketAddrV6,
) -> Result<(), Error>;
fn get_ipv4_list(&self, direction: FlowDirection, list_type: ListType) -> HashMap<Ipv4Addr, Vec<Port>>;
fn get_ipv6_list(&self, direction: FlowDirection, list_type: ListType) -> HashMap<Ipv6Addr, Vec<Port>>;
}

View File

@ -1,16 +1,9 @@
use crate::domain::common::error::Error;
/// Data-plane geo-block admin port — block / unblock / list country codes.
/// Used by `AclService` for the `/api/acl/geo` HTTP routes.
pub trait GeoBlockPort: Send + Sync {
/// Add every ISO-3166-1 alpha-2 code in `codes` to the block set.
/// Returns the number of /24 ranges actually added (existing codes
/// count as zero).
fn list_blocked(&self) -> Vec<String>;
fn block_countries(&self, codes: &[String]) -> Result<u64, Error>;
/// Remove every code in `codes` from the block set. Returns the number
/// of /24 ranges actually removed.
fn unblock_countries(&self, codes: &[String]) -> Result<u64, Error>;
fn list_blocked(&self) -> Vec<String>;
}

View File

@ -2,22 +2,10 @@ use std::sync::Arc;
use crate::domain::data_plane::user_packet::UserPacket;
/// Data-plane packet sink — receives parsed packets from the AF_XDP RX path.
///
/// Implementations wrap a `FlowTracker` (or other per-queue state) and forward
/// each packet into the ML inference pipeline. `XskManager` sees only this
/// trait, never `core::ml`, so the dependency direction stays
/// `adapter/ebpf → interface/port`.
pub trait PacketSink: Send + Sync {
/// Process one parsed packet. The boolean says whether the packet arrived
/// on the ingress interface (`true`) or the egress interface (`false`).
fn process_packet(&self, packet: UserPacket, is_ingress: bool);
}
/// Factory that hands out a per-queue `PacketSink` for each AF_XDP queue the
/// manager spins up. `XskManager` calls this once per queue during bring-up.
pub trait PacketSinkFactory: Send + Sync {
/// Return a sink bound to `queue_id`, or `None` to skip per-packet
/// tracking on that queue.
fn sink_for_queue(&self, queue_id: u32) -> Option<Arc<dyn PacketSink>>;
}

View File

@ -19,7 +19,9 @@ use sd_notify::NotifyState;
use tokio::time::sleep;
use tokio::{signal, time};
use crate::adapter::http::jwt::JwtService;
use crate::adapter::persistence::Database;
use crate::core::identity::auth_service::AuthService;
use crate::domain::common::config::observability::ObservabilityConfig;
use crate::domain::common::error::Error;
use crate::domain::common::error::system::SystemError;
@ -28,8 +30,13 @@ use crate::domain::identity::auth::{DEFAULT_ADMIN_USERNAME, GROUP_ADMIN, ROLE_AD
use crate::domain::identity::password;
use crate::infrastructure::cli::{Cli, handle_subcommand};
use crate::infrastructure::http_server;
use crate::infrastructure::http_server::SetupServerParams;
use crate::infrastructure::logger::Logger;
use crate::infrastructure::secret_store::SecretStore;
use crate::infrastructure::system::{ShutdownMode, System};
use crate::interface::app_repo::AppRepo;
use crate::interface::secret_store::SecretStorePort;
use crate::interface::token_minter::TokenMinter;
fn seed_default_admin(database: &Arc<Database>) -> Result<(), Error> {
if database.user_count().unwrap_or(0) != 0 {
@ -60,7 +67,22 @@ async fn run_setup_wizard(database: &Arc<Database>) -> Result<(), Error> {
let setup_flag = Arc::new(AtomicBool::new(false));
let setup_complete_flag = http_server::SetupCompleteFlag(setup_flag.clone());
let params = http_server::SetupServerParams::build(database.clone(), setup_complete_flag, 8080)?;
let database = database.clone();
let secret_store = Arc::new(SecretStore::new(database.clone()));
let secrets: Arc<dyn SecretStorePort> = secret_store.clone();
let jwt_service = Arc::new(JwtService::new(&secrets, 24)?);
let auth_service = Arc::new(AuthService::new(
database.clone() as Arc<dyn AppRepo>,
jwt_service.clone() as Arc<dyn TokenMinter>,
));
let params = SetupServerParams {
database,
secret_store,
jwt_service,
auth_service,
setup_complete: setup_complete_flag,
port: 8080,
};
let handle = http_server::start_setup_server(params)?;
let flag = setup_flag.clone();