use std::{ops::Deref, str::FromStr, sync::Arc}; use giterated_models::{ authenticated::{InstanceSignature, UserAuthenticationToken}, instance::Instance, object::GiteratedObject, operation::GiteratedOperation, user::User, }; use handlers::{NetworkedObject, NetworkedOperation}; use object::NetworkAnyObject; use operations::NetworkAnyOperation; use rsa::{ pkcs1::DecodeRsaPrivateKey, pss::SigningKey, sha2::Sha256, signature::{RandomizedSigner, SignatureEncoding}, RsaPrivateKey, }; use serde::{Deserialize, Serialize}; use std::fmt::Debug; pub mod handlers; pub mod object; pub mod operations; #[macro_use] extern crate tracing; #[derive(Clone)] pub struct StackOperationState { pub our_instance: Instance, pub instance: Option, pub user: Option, } #[derive(Clone, Debug)] pub struct AuthenticatedInstance(Instance); impl AuthenticatedInstance { pub fn new(instance: Instance) -> Self { AuthenticatedInstance(instance) } } impl Deref for AuthenticatedInstance { type Target = Instance; fn deref(&self) -> &Self::Target { &self.0 } } #[derive(Clone, Debug)] pub struct AuthenticatedUser(User); impl AuthenticatedUser { pub fn new(user: User) -> Self { AuthenticatedUser(user) } } impl Deref for AuthenticatedUser { type Target = User; fn deref(&self) -> &Self::Target { &self.0 } } #[derive(Clone)] pub struct NetworkOperationState { authentication: Vec>, } impl NetworkOperationState { pub fn new() -> Self { Self { authentication: vec![], } } pub fn authenticate( &mut self, provider: impl AuthenticationSourceProviders + Send + Sync + 'static, ) { self.authentication.push(Arc::new(provider)) } } #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)] pub struct AuthenticatedPayload { pub source: Vec, pub object: String, pub operation: String, pub payload: Vec, } impl AuthenticatedPayload { pub fn into_message(self) -> GiteratedMessage { GiteratedMessage { object: NetworkedObject::from_str(&self.object).unwrap(), operation: self.operation, payload: serde_json::from_slice(&self.payload).unwrap(), } } } pub trait AuthenticationSourceProvider: Debug { fn authenticate(&self, payload: &Vec) -> AuthenticationSource; } pub trait AuthenticationSourceProviders: Debug { fn authenticate_all(&self, payload: &Vec) -> Vec; } impl AuthenticationSourceProviders for A where A: AuthenticationSourceProvider, { fn authenticate_all(&self, payload: &Vec) -> Vec { vec![self.authenticate(payload)] } } impl AuthenticationSourceProviders for (A, B) where A: AuthenticationSourceProvider, B: AuthenticationSourceProvider, { fn authenticate_all(&self, payload: &Vec) -> Vec { let (first, second) = self; vec![first.authenticate(payload), second.authenticate(payload)] } } #[derive(Clone, Debug)] pub struct UserAuthenticator { pub user: User, pub token: UserAuthenticationToken, } impl AuthenticationSourceProvider for UserAuthenticator { fn authenticate(&self, _payload: &Vec) -> AuthenticationSource { AuthenticationSource::User { user: self.user.clone(), token: self.token.clone(), } } } #[derive(Debug, Clone)] pub struct InstanceAuthenticator { pub instance: Instance, pub private_key: String, } impl AuthenticationSourceProvider for InstanceAuthenticator { fn authenticate(&self, payload: &Vec) -> AuthenticationSource { let mut rng = rand::thread_rng(); let private_key = RsaPrivateKey::from_pkcs1_pem(&self.private_key).unwrap(); let signing_key = SigningKey::::new(private_key); let signature = signing_key.sign_with_rng(&mut rng, payload); AuthenticationSource::Instance { instance: self.instance.clone(), // TODO: Actually parse signature from private key signature: InstanceSignature(signature.to_bytes().into_vec()), } } } #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] pub enum AuthenticationSource { User { user: User, token: UserAuthenticationToken, }, Instance { instance: Instance, signature: InstanceSignature, }, } #[derive(Serialize)] #[serde(bound(deserialize = "O: GiteratedObject, V: GiteratedOperation"))] pub struct GiteratedMessage> { #[serde(with = "string")] pub object: O, pub operation: String, pub payload: V, } #[allow(unused)] mod string { use std::fmt::Display; use std::str::FromStr; use serde::{de, Deserialize, Deserializer, Serializer}; pub fn serialize(value: &T, serializer: S) -> Result where T: Display, S: Serializer, { serializer.collect_str(value) } pub fn deserialize<'de, T, D>(deserializer: D) -> Result where T: FromStr, T::Err: Display, D: Deserializer<'de>, { String::deserialize(deserializer)? .parse() .map_err(de::Error::custom) } } impl GiteratedMessage { pub fn try_into>( &self, ) -> Result, ()> { let object = O::from_object_str(&self.object.0).map_err(|_| ())?; let payload = serde_json::from_slice::(&self.payload.0).map_err(|_| ())?; Ok(GiteratedMessage { object, operation: self.operation.clone(), payload, }) } } impl + Debug, O: GiteratedObject + Debug> Debug for GiteratedMessage { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("GiteratedMessage") .field("object", &self.object) .field("operation", &self.operation) .field("payload", &self.payload) .finish() } } #[derive(Debug, Clone, thiserror::Error)] #[error("a remote internal error occurred")] pub struct RemoteError; #[derive(Debug, thiserror::Error)] #[error("a remote internal error occurred")] pub struct NetworkError; #[derive(Debug)] pub struct Authenticated> { pub source: Vec>, pub message: GiteratedMessage, } impl> Authenticated { pub fn new(message: GiteratedMessage) -> Self { Self { source: vec![], message, } } pub fn append_authentication( &mut self, authentication: Arc, ) { self.source.push(authentication); } pub fn into_payload(mut self) -> AuthenticatedPayload { let payload = serde_json::to_vec(&self.message.payload).unwrap(); AuthenticatedPayload { object: self.message.object.to_string(), operation: self.message.operation, source: self .source .drain(..) .map(|provider| provider.as_ref().authenticate_all(&payload)) .flatten() .collect::>(), payload, } } } #[derive(Clone, Debug)] pub struct ProtocolState { pub home_uri: Option, }