Skip to content

Commit

Permalink
Merge pull request #37 from Avarok-Cybersecurity/refactor_request_han…
Browse files Browse the repository at this point in the history
…dler

Refactor request handler
  • Loading branch information
tbraun96 authored Mar 30, 2024
2 parents 53ffc72 + 2a43199 commit b859dcf
Show file tree
Hide file tree
Showing 45 changed files with 3,235 additions and 2,915 deletions.
4 changes: 2 additions & 2 deletions citadel-internal-service-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ pub struct GroupKickFailure {
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct GroupListGroupsSuccess {
pub cid: u64,
pub peer_cid: u64,
pub peer_cid: Option<u64>,
pub group_list: Option<Vec<MessageGroupKey>>,
pub request_id: Option<Uuid>,
}
Expand Down Expand Up @@ -813,7 +813,7 @@ pub enum InternalServiceRequest {
},
GroupListGroupsFor {
cid: u64,
peer_cid: u64,
peer_cid: Option<u64>,
request_id: Uuid,
},
GroupRequestJoin {
Expand Down
530 changes: 40 additions & 490 deletions citadel-internal-service/src/kernel/mod.rs

Large diffs are not rendered by default.

2,421 changes: 0 additions & 2,421 deletions citadel-internal-service/src/kernel/request_handler.rs

This file was deleted.

100 changes: 100 additions & 0 deletions citadel-internal-service/src/kernel/requests/connect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use crate::kernel::requests::HandledRequestResult;
use crate::kernel::{create_client_server_remote, CitadelWorkspaceService, Connection};
use citadel_internal_service_types::{
ConnectFailure, InternalServiceRequest, InternalServiceResponse, MessageNotification,
};
use citadel_sdk::prelude::{AuthenticationRequest, ProtocolRemoteExt};
use futures::StreamExt;
use uuid::Uuid;

pub async fn handle(
this: &CitadelWorkspaceService,
uuid: Uuid,
request: InternalServiceRequest,
) -> Option<HandledRequestResult> {
let InternalServiceRequest::Connect {
request_id,
username,
password,
connect_mode,
udp_mode,
keep_alive_timeout,
session_security_settings,
} = request
else {
unreachable!("Should never happen if programmed properly")
};
let remote = this.remote();

match remote
.connect(
AuthenticationRequest::credentialed(username, password),
connect_mode,
udp_mode,
keep_alive_timeout,
session_security_settings,
)
.await
{
Ok(conn_success) => {
let cid = conn_success.cid;

let (sink, mut stream) = conn_success.channel.split();
let client_server_remote = create_client_server_remote(
stream.vconn_type,
remote.clone(),
session_security_settings,
);
let connection_struct = Connection::new(sink, client_server_remote, uuid);
this.server_connection_map
.lock()
.await
.insert(cid, connection_struct);

let hm_for_conn = this.tcp_connection_map.clone();

let response = InternalServiceResponse::ConnectSuccess(
citadel_internal_service_types::ConnectSuccess {
cid,
request_id: Some(request_id),
},
);

let connection_read_stream = async move {
while let Some(message) = stream.next().await {
let message =
InternalServiceResponse::MessageNotification(MessageNotification {
message: message.into_buffer(),
cid,
peer_cid: 0,
request_id: Some(request_id),
});
let lock = hm_for_conn.lock().await;
match lock.get(&uuid) {
Some(entry) => {
if let Err(err) = entry.send(message) {
citadel_logging::error!(target:"citadel","Error sending message to client: {err:?}");
}
}
None => {
citadel_logging::info!(target:"citadel","Hash map connection not found")
}
}
}
};

tokio::spawn(connection_read_stream);

Some(HandledRequestResult { response, uuid })
}

Err(err) => {
let response = InternalServiceResponse::ConnectFailure(ConnectFailure {
message: err.into_string(),
request_id: Some(request_id),
});

Some(HandledRequestResult { response, uuid })
}
}
}
54 changes: 54 additions & 0 deletions citadel-internal-service/src/kernel/requests/disconnect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use crate::kernel::requests::HandledRequestResult;
use crate::kernel::CitadelWorkspaceService;
use citadel_internal_service_types::{
DisconnectFailure, DisconnectNotification, InternalServiceRequest, InternalServiceResponse,
};
use citadel_logging::info;
use citadel_sdk::prelude::{DisconnectFromHypernode, NodeRequest};
use uuid::Uuid;

pub async fn handle(
this: &CitadelWorkspaceService,
uuid: Uuid,
request: InternalServiceRequest,
) -> Option<HandledRequestResult> {
let InternalServiceRequest::Disconnect { request_id, cid } = request else {
unreachable!("Should never happen if programmed properly")
};
let remote = this.remote();

let request = NodeRequest::DisconnectFromHypernode(DisconnectFromHypernode {
implicated_cid: cid,
});

this.server_connection_map.lock().await.remove(&cid);

match remote.send(request).await {
Ok(_res) => {
let disconnect_success =
InternalServiceResponse::DisconnectNotification(DisconnectNotification {
cid,
peer_cid: None,
request_id: Some(request_id),
});
Some(HandledRequestResult {
response: disconnect_success,
uuid,
})
}
Err(err) => {
let error_message = format!("Failed to disconnect {err:?}");
info!(target: "citadel", "{error_message}");
let disconnect_failure =
InternalServiceResponse::DisconnectFailure(DisconnectFailure {
cid,
message: error_message,
request_id: Some(request_id),
});
Some(HandledRequestResult {
response: disconnect_failure,
uuid,
})
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use crate::kernel::requests::HandledRequestResult;
use crate::kernel::CitadelWorkspaceService;
use citadel_internal_service_types::{
DeleteVirtualFileFailure, DeleteVirtualFileSuccess, InternalServiceRequest,
InternalServiceResponse,
};
use citadel_logging::error;
use citadel_sdk::prelude::{DeleteObject, NetworkError, NodeRequest, VirtualTargetType};
use uuid::Uuid;

pub async fn handle(
this: &CitadelWorkspaceService,
uuid: Uuid,
request: InternalServiceRequest,
) -> Option<HandledRequestResult> {
let InternalServiceRequest::DeleteVirtualFile {
virtual_directory,
cid,
peer_cid,
request_id,
} = request
else {
unreachable!("Should never happen if programmed properly")
};
let remote = this.remote();

let mut lock = this.server_connection_map.lock().await;
let response = match lock.get_mut(&cid) {
Some(conn) => {
let result = if let Some(peer_cid) = peer_cid {
if let Some(_peer_remote) = conn.peers.get_mut(&peer_cid) {
let request = NodeRequest::DeleteObject(DeleteObject {
v_conn: VirtualTargetType::LocalGroupPeer {
implicated_cid: cid,
peer_cid,
},
virtual_dir: virtual_directory,
security_level: Default::default(),
});

drop(lock);
remote.send(request).await
} else {
Err(NetworkError::msg("Peer Connection Not Found"))
}
} else {
let request = NodeRequest::DeleteObject(DeleteObject {
v_conn: VirtualTargetType::LocalGroupServer {
implicated_cid: cid,
},
virtual_dir: virtual_directory,
security_level: Default::default(),
});

drop(lock);
remote.send(request).await
};

match result {
Ok(_) => {
InternalServiceResponse::DeleteVirtualFileSuccess(DeleteVirtualFileSuccess {
cid,
request_id: Some(request_id),
})
}

Err(err) => {
InternalServiceResponse::DeleteVirtualFileFailure(DeleteVirtualFileFailure {
cid,
message: err.into_string(),
request_id: Some(request_id),
})
}
}
}
None => {
error!(target: "citadel","server connection not found");
InternalServiceResponse::DeleteVirtualFileFailure(DeleteVirtualFileFailure {
cid,
message: String::from("Server Connection Not Found"),
request_id: Some(request_id),
})
}
};

Some(HandledRequestResult { response, uuid })
}
82 changes: 82 additions & 0 deletions citadel-internal-service/src/kernel/requests/file/download.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use crate::kernel::requests::HandledRequestResult;
use crate::kernel::CitadelWorkspaceService;
use citadel_internal_service_types::{
DownloadFileFailure, DownloadFileSuccess, InternalServiceRequest, InternalServiceResponse,
};
use citadel_logging::error;
use citadel_sdk::prelude::{NetworkError, NodeRequest, PullObject, TargetLockedRemote};
use uuid::Uuid;

pub async fn handle(
this: &CitadelWorkspaceService,
uuid: Uuid,
request: InternalServiceRequest,
) -> Option<HandledRequestResult> {
let InternalServiceRequest::DownloadFile {
virtual_directory,
security_level,
delete_on_pull,
cid,
peer_cid,
request_id,
} = request
else {
unreachable!("Should never happen if programmed properly")
};
let remote = this.remote();

let security_level = security_level.unwrap_or_default();
let mut lock = this.server_connection_map.lock().await;
let response = match lock.get_mut(&cid) {
Some(conn) => {
let result = if let Some(peer_cid) = peer_cid {
if let Some(peer_remote) = conn.peers.get_mut(&peer_cid) {
let request = NodeRequest::PullObject(PullObject {
v_conn: *peer_remote.remote.user(),
virtual_dir: virtual_directory,
delete_on_pull,
transfer_security_level: security_level,
});

drop(lock);
remote.send(request).await
} else {
Err(NetworkError::msg("Peer Connection Not Found"))
}
} else {
let request = NodeRequest::PullObject(PullObject {
v_conn: *conn.client_server_remote.user(),
virtual_dir: virtual_directory,
delete_on_pull,
transfer_security_level: security_level,
});

drop(lock);
remote.send(request).await
};

match result {
Ok(_) => InternalServiceResponse::DownloadFileSuccess(DownloadFileSuccess {
cid,
request_id: Some(request_id),
}),

Err(err) => InternalServiceResponse::DownloadFileFailure(DownloadFileFailure {
cid,
message: err.into_string(),
request_id: Some(request_id),
}),
}
}
None => {
error!(target: "citadel","server connection not found");
InternalServiceResponse::DownloadFileFailure(DownloadFileFailure {
cid,
message: String::from("Server Connection Not Found"),
request_id: Some(request_id),
})
}
};

Some(HandledRequestResult { response, uuid })
}
4 changes: 4 additions & 0 deletions citadel-internal-service/src/kernel/requests/file/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod delete_virtual_file;
pub mod download;
pub mod respond_file_transfer;
pub mod upload;
Loading

0 comments on commit b859dcf

Please sign in to comment.