nullnet-wallguard-server 0.1.10

A centralized management system for network firewalls
Documentation
use tonic::{Request, Response, Status};

use crate::{
    grpc_server::server::WallGuardImpl,
    proto::wallguard::{CommonResponse, ConfigSnapshot, ConfigStatus},
};

impl WallGuardImpl {
    pub(crate) async fn handle_config_impl(
        &self,
        request: Request<ConfigSnapshot>,
    ) -> Result<Response<CommonResponse>, Status> {
        let datastore = self
            .datastore
            .as_ref()
            .ok_or_else(|| Status::internal("Datastore is unavailable"))?;

        let snapshot = request.into_inner();

        let (jwt_token, token_info) = Self::authenticate(snapshot.auth)?;

        let config_file = snapshot
            .files
            .iter()
            .find(|file| file.filename == "config.xml");

        let document = std::str::from_utf8(config_file.unwrap().contents.as_slice())
            .map_err(|e| Status::internal(format!("Failed to stringify file content: {}", e)))?;

        let configuration =
            libfireparse::Parser::parse("pfsense", document).map_err(|e| match e {
                libfireparse::FireparseError::UnsupportedPlatform(msg) => Status::internal(msg),
                libfireparse::FireparseError::ParserError(msg) => Status::internal(msg),
            })?;

        let created_id = datastore
            .config_upload(
                &jwt_token,
                token_info.account.device.id,
                configuration,
                convert_status(
                    ConfigStatus::try_from(snapshot.status).unwrap_or(ConfigStatus::CsUndefined),
                ),
            )
            .await
            .map_err(|e| Status::internal(e.to_string()))?;

        Ok(Response::new(CommonResponse {
            success: true,
            message: format!("Configuration created [ID '{}']", created_id),
        }))
    }
}

fn convert_status(status: ConfigStatus) -> String {
    match status {
        ConfigStatus::CsDraft => String::from("Draft"),
        ConfigStatus::CsApplied => String::from("Applied"),
        ConfigStatus::CsUndefined => String::from("Undefined"),
    }
}