mod substack; use std::convert::Infallible; use std::fmt::Debug; use std::str::FromStr; use std::{fmt::Display, sync::Arc}; use giterated_stack::models::{Error, GiteratedObject, GiteratedOperation, Instance, User}; use rsa::pkcs1::DecodeRsaPrivateKey; use rsa::pkcs1v15::SigningKey; use rsa::sha2::Sha256; use rsa::signature::{RandomizedSigner, SignatureEncoding}; use rsa::RsaPrivateKey; use serde::{Deserialize, Serialize}; pub use substack::{NetworkedObject, NetworkedOperation, NetworkedSubstack}; #[derive(Clone, Default)] pub struct NetworkOperationState { authentication: Vec>, } impl NetworkOperationState { 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: NetworkAnyObject(self.object), operation: self.operation, payload: NetworkAnyOperation(self.payload), } } } 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)] } } mod verified {} #[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()), } } } #[repr(transparent)] #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] pub struct UserAuthenticationToken(String); impl From for UserAuthenticationToken { fn from(value: String) -> Self { Self(value) } } impl ToString for UserAuthenticationToken { fn to_string(&self) -> String { self.0.clone() } } impl AsRef for UserAuthenticationToken { fn as_ref(&self) -> &str { &self.0 } } #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] pub struct InstanceSignature(Vec); impl AsRef<[u8]> for InstanceSignature { fn as_ref(&self) -> &[u8] { &self.0 } } #[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(Clone, Debug, Serialize, Deserialize)] #[serde(transparent)] #[repr(transparent)] pub struct NetworkAnyObject(pub String); impl GiteratedObject for NetworkAnyObject { fn object_name() -> &'static str { "any" } fn from_object_str(object_str: &str) -> Result { Ok(Self(object_str.to_string())) } } impl Display for NetworkAnyObject { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(&self.0) } } impl FromStr for NetworkAnyObject { type Err = Infallible; fn from_str(s: &str) -> Result { Ok(Self(s.to_owned())) } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(transparent)] #[repr(transparent)] pub struct NetworkAnyOperation(pub Vec); impl GiteratedOperation for NetworkAnyOperation { type Success = Vec; type Failure = Vec; }