use crate::error::InvalidStateError;
use crate::network::auth::authorization::Authorization;
use crate::network::auth::AuthorizationManagerStateMachine;
use crate::network::auth::ConnectionAuthorizationType;
use crate::network::dispatch::{ConnectionId, Dispatcher, MessageSender};
use crate::protos::network::NetworkMessageType;
#[cfg(any(feature = "trust-authorization", feature = "challenge-authorization"))]
use super::v1_handlers::{
builders::{AuthProtocolRequestHandlerBuilder, AuthProtocolResponseHandlerBuilder},
AuthCompleteHandler,
};
use super::{AuthorizationErrorHandler, AuthorizationMessageHandler};
#[derive(Default)]
pub struct AuthorizationDispatchBuilder {
identity: Option<String>,
expected_authorization: Option<ConnectionAuthorizationType>,
local_authorization: Option<ConnectionAuthorizationType>,
authorizations: Vec<Box<dyn Authorization>>,
}
impl AuthorizationDispatchBuilder {
pub fn new() -> Self {
AuthorizationDispatchBuilder::default()
}
pub fn with_identity(mut self, identity: &str) -> Self {
self.identity = Some(identity.to_string());
self
}
pub fn with_expected_authorization(
mut self,
expected_authorization: Option<ConnectionAuthorizationType>,
) -> Self {
self.expected_authorization = expected_authorization;
self
}
pub fn with_local_authorization(
mut self,
local_authorization: Option<ConnectionAuthorizationType>,
) -> Self {
self.local_authorization = local_authorization;
self
}
pub fn add_authorization(mut self, authorization: Box<dyn Authorization>) -> Self {
self.authorizations.push(authorization);
self
}
pub fn build(
self,
auth_msg_sender: impl MessageSender<ConnectionId> + Clone + 'static,
auth_manager: AuthorizationManagerStateMachine,
) -> Result<Dispatcher<NetworkMessageType, ConnectionId>, InvalidStateError> {
#[cfg(feature = "trust-authorization")]
let identity = self.identity.ok_or_else(|| {
InvalidStateError::with_message("Missing required `identity` field".to_string())
})?;
let mut auth_dispatcher = Dispatcher::new(Box::new(auth_msg_sender.clone()));
#[cfg(any(feature = "trust-authorization", feature = "challenge-authorization"))]
{
#![allow(unused_mut)]
let mut auth_protocol_request_builder = AuthProtocolRequestHandlerBuilder::default()
.with_auth_manager(auth_manager.clone());
auth_protocol_request_builder = auth_protocol_request_builder
.with_expected_authorization(self.expected_authorization.clone())
.with_local_authorization(self.local_authorization.clone());
auth_dispatcher.set_handler(Box::new(auth_protocol_request_builder.build()?));
let mut auth_protocol_response_builder = AuthProtocolResponseHandlerBuilder::default()
.with_auth_manager(auth_manager.clone());
#[cfg(feature = "trust-authorization")]
{
auth_protocol_response_builder =
auth_protocol_response_builder.with_identity(&identity);
}
#[allow(clippy::redundant_clone)]
{
auth_protocol_response_builder = auth_protocol_response_builder
.with_required_local_auth(self.local_authorization.clone());
}
auth_dispatcher.set_handler(Box::new(auth_protocol_response_builder.build()?));
auth_dispatcher.set_handler(Box::new(AuthCompleteHandler::new(auth_manager.clone())));
}
for mut authorization in self.authorizations.into_iter() {
let handlers = authorization.get_handlers()?;
for handler in handlers {
auth_dispatcher.set_handler(handler);
}
}
auth_dispatcher.set_handler(Box::new(AuthorizationErrorHandler::new(auth_manager)));
let mut network_msg_dispatcher = Dispatcher::new(Box::new(auth_msg_sender));
network_msg_dispatcher
.set_handler(Box::new(AuthorizationMessageHandler::new(auth_dispatcher)));
Ok(network_msg_dispatcher)
}
}