use anyhow::Error; use thiserror::Error; use crate::messages::authentication::{AuthenticationMessage, AuthenticationResponse}; use crate::model::authenticated::MessageHandler; use crate::{ messages::{authentication::AuthenticationRequest, MessageKind}, model::authenticated::{AuthenticatedInstance, NetworkMessage, State}, }; use super::wrapper::ConnectionState; use super::HandlerUnhandled; pub async fn authentication_handle( message: &NetworkMessage, state: &ConnectionState, ) -> Result<(), Error> { let message_kind: MessageKind = serde_json::from_slice(&message.0).unwrap(); match message_kind { MessageKind::Authentication(AuthenticationMessage::Request(request)) => match request { AuthenticationRequest::RegisterAccount(_) => { register_account_request .handle_message(message, state) .await } AuthenticationRequest::AuthenticationToken(_) => { authentication_token_request .handle_message(message, state) .await } AuthenticationRequest::TokenExtension(_) => { token_extension_request.handle_message(message, state).await } }, _ => Err(Error::from(HandlerUnhandled)), } } async fn register_account_request( State(connection_state): State, request: MessageKind, instance: AuthenticatedInstance, ) -> Result<(), AuthenticationConnectionError> { let request = if let MessageKind::Authentication(AuthenticationMessage::Request( AuthenticationRequest::RegisterAccount(request), )) = request { request } else { return Err(AuthenticationConnectionError::InvalidRequest); }; if *instance.inner() != connection_state.instance { return Err(AuthenticationConnectionError::SameInstance); } let mut user_backend = connection_state.user_backend.lock().await; let response = user_backend .register(request.clone()) .await .map_err(|e| AuthenticationConnectionError::Registration(e))?; drop(user_backend); connection_state .send(MessageKind::Authentication( AuthenticationMessage::Response(AuthenticationResponse::RegisterAccount(response)), )) .await .map_err(|e| AuthenticationConnectionError::Sending(e))?; Ok(()) } async fn authentication_token_request( State(connection_state): State, request: MessageKind, instance: AuthenticatedInstance, ) -> Result<(), AuthenticationConnectionError> { let request = if let MessageKind::Authentication(AuthenticationMessage::Request( AuthenticationRequest::AuthenticationToken(request), )) = request { request } else { return Err(AuthenticationConnectionError::InvalidRequest); }; let issued_for = instance.inner().clone(); let mut token_granter = connection_state.auth_granter.lock().await; let response = token_granter .token_request(issued_for, request.username, request.password) .await .map_err(|e| AuthenticationConnectionError::TokenIssuance(e))?; connection_state .send(MessageKind::Authentication( AuthenticationMessage::Response(AuthenticationResponse::AuthenticationToken(response)), )) .await .map_err(|e| AuthenticationConnectionError::Sending(e))?; Ok(()) } async fn token_extension_request( State(connection_state): State, request: MessageKind, instance: AuthenticatedInstance, ) -> Result<(), AuthenticationConnectionError> { let request = if let MessageKind::Authentication(AuthenticationMessage::Request( AuthenticationRequest::TokenExtension(request), )) = request { request } else { return Err(AuthenticationConnectionError::InvalidRequest); }; let issued_for = instance.inner().clone(); let mut token_granter = connection_state.auth_granter.lock().await; let response = token_granter .extension_request(&issued_for, request.token) .await .map_err(|e| AuthenticationConnectionError::TokenIssuance(e))?; connection_state .send(MessageKind::Authentication( AuthenticationMessage::Response(AuthenticationResponse::TokenExtension(response)), )) .await .map_err(|e| AuthenticationConnectionError::Sending(e))?; Ok(()) } async fn verify(state: ConnectionState) { register_account_request .handle_message(&NetworkMessage(vec![]), &state) .await; } #[derive(Debug, Error)] pub enum AuthenticationConnectionError { #[error("the request was invalid")] InvalidRequest, #[error("request must be from the same instance")] SameInstance, #[error("issue during registration {0}")] Registration(Error), #[error("sending error")] Sending(Error), #[error("error issuing token")] TokenIssuance(Error), }