/* * Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers * All rights reserved. * Licensed under the Apache License, Version 2.0 * * or the MIT license , * at your option. All files in the project carrying such * notice may not be copied, modified, or distributed except * according to those terms. */ use std::sync::Arc; use async_std::sync::Mutex; use ng_repo::errors::*; use ng_repo::log::*; use crate::app_protocol::*; use crate::broker::BROKER; use crate::connection::NoiseFSM; use crate::types::*; use crate::{actor::*, types::ProtocolMessage}; impl AppSessionStart { pub fn get_actor(&self, id: i64) -> Box { Actor::::new_responder(id) } } impl TryFrom for AppSessionStart { type Error = ProtocolError; fn try_from(msg: ProtocolMessage) -> Result { if let AppMessageContentV0::SessionStart(req) = msg.try_into()? { Ok(req) } else { log_debug!("INVALID AppMessageContentV0::SessionStart"); Err(ProtocolError::InvalidValue) } } } impl From for ProtocolMessage { fn from(request: AppSessionStart) -> ProtocolMessage { AppMessageContentV0::SessionStart(request).into() } } impl TryFrom for AppSessionStartResponse { type Error = ProtocolError; fn try_from(msg: ProtocolMessage) -> Result { if let AppMessageContentV0::Response(AppResponse::V0(AppResponseV0::SessionStart(res))) = msg.try_into()? { Ok(res) } else { log_debug!("INVALID AppSessionStartResponse"); Err(ProtocolError::InvalidValue) } } } impl From for AppMessage { fn from(response: AppSessionStartResponse) -> AppMessage { AppResponse::V0(AppResponseV0::SessionStart(response)).into() } } impl From for ProtocolMessage { fn from(response: AppSessionStartResponse) -> ProtocolMessage { response.into() } } impl Actor<'_, AppSessionStart, AppSessionStartResponse> {} #[async_trait::async_trait] impl EActor for Actor<'_, AppSessionStart, AppSessionStartResponse> { async fn respond( &mut self, msg: ProtocolMessage, fsm: Arc>, ) -> Result<(), ProtocolError> { let req = AppSessionStart::try_from(msg)?; let res = { let lock = fsm.lock().await; let remote = lock.remote_peer(); //TODO: if fsm.get_user_id is some, check that user_priv_key in credentials matches. //TODO: if no user in fsm (headless), check user in request is allowed if remote.is_none() { Err(ServerError::BrokerError) } else { let (sb, broker_id) = { let b = BROKER.read().await; (b.get_server_broker()?, b.get_server_peer_id()) }; let lock = sb.read().await; lock.app_session_start(req, remote.unwrap(), broker_id) .await } }; let app_message: AppMessage = match res { Err(e) => e.into(), Ok(o) => o.into(), }; fsm.lock() .await .send_in_reply_to(app_message.into(), self.id()) .await?; Ok(()) } } /////////////////////// impl AppSessionStop { pub fn get_actor(&self, id: i64) -> Box { Actor::::new_responder(id) } } impl TryFrom for AppSessionStop { type Error = ProtocolError; fn try_from(msg: ProtocolMessage) -> Result { if let AppMessageContentV0::SessionStop(req) = msg.try_into()? { Ok(req) } else { log_debug!("INVALID AppMessageContentV0::SessionStop"); Err(ProtocolError::InvalidValue) } } } impl TryFrom for EmptyAppResponse { type Error = ProtocolError; fn try_from(msg: ProtocolMessage) -> Result { let res: Result = msg.try_into(); if let AppMessageContentV0::EmptyResponse = res? { Ok(EmptyAppResponse(())) } else { log_debug!("INVALID AppMessageContentV0::EmptyResponse"); Err(ProtocolError::InvalidValue) } } } impl From for ProtocolMessage { fn from(request: AppSessionStop) -> ProtocolMessage { AppMessageContentV0::SessionStop(request).into() } } impl From> for ProtocolMessage { fn from(res: Result) -> ProtocolMessage { match res { Ok(_a) => ServerError::Ok.into(), Err(err) => AppMessage::V0(AppMessageV0 { id: 0, result: err.into(), content: AppMessageContentV0::EmptyResponse, }), } .into() } } impl Actor<'_, AppSessionStop, EmptyAppResponse> {} #[async_trait::async_trait] impl EActor for Actor<'_, AppSessionStop, EmptyAppResponse> { async fn respond( &mut self, msg: ProtocolMessage, fsm: Arc>, ) -> Result<(), ProtocolError> { let req = AppSessionStop::try_from(msg)?; let res = { let lock = fsm.lock().await; let remote = lock.remote_peer(); if remote.is_none() { Err(ServerError::BrokerError) } else { let sb = { BROKER.read().await.get_server_broker()? }; let lock = sb.read().await; lock.app_session_stop(req, remote.as_ref().unwrap()).await } }; fsm.lock() .await .send_in_reply_to(res.into(), self.id()) .await?; Ok(()) } }