mod handler; pub use handler::*; mod meta; pub use meta::*; pub mod provider; mod stack; pub use stack::*; mod substack; use serde::{de::DeserializeOwned, Deserialize, Serialize}; pub use stack::*; pub use substack::*; pub mod state; pub mod update; // Temp pub use to figure out what's important pub mod models { pub use anyhow::Error; pub use giterated_models::error::{IntoInternalError, OperationError}; pub use giterated_models::object::GiteratedObject; pub use giterated_models::operation::GiteratedOperation; } use std::{any::Any, convert::Infallible, ops::Deref, sync::Arc}; use core::fmt::Debug; use giterated_models::{ error::{ExtractorError, UnauthorizedError}, instance::{ AuthenticationTokenRequest, Instance, RegisterAccountRequest, RepositoryCreateRequest, }, object::GiteratedObject, object_backend::ObjectBackend, operation::GiteratedOperation, repository::{AccessList, Repository}, settings::{GetSetting, SetSetting, Setting}, user::User, value::{GetValue, GiteratedObjectValue}, }; #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] pub struct ObjectOperationPair<'a> { pub object_name: &'a str, pub operation_name: &'a str, } impl ObjectOperationPair<'static> { #[allow(unused)] pub fn from_types>() -> Self { Self { object_name: O::object_name(), operation_name: D::operation_name(), } } } #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] pub struct ObjectValuePair<'a> { pub object_kind: &'a str, pub value_kind: &'a str, } impl ObjectValuePair<'static> { pub fn from_types>() -> Self { Self { object_kind: O::object_name(), value_kind: V::value_name(), } } } #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] pub struct ObjectSettingPair<'a> { pub object_kind: &'a str, pub setting_name: &'a str, } impl ObjectSettingPair<'static> { pub fn from_types() -> Self { Self { object_kind: O::object_name(), setting_name: S::name(), } } } #[async_trait::async_trait(?Send)] pub trait FromOperationState>: Sized + Clone { type Error: Into; async fn from_state( object: &O, operation: &D, state: &StackOperationState, ) -> Result>; } #[async_trait::async_trait(?Send)] impl> FromOperationState for StackOperationState { type Error = Infallible; async fn from_state( _object: &O, _operation: &D, state: &StackOperationState, ) -> Result> { Ok(state.clone()) } } #[derive(Debug, thiserror::Error, Serialize, Deserialize)] #[error("missing value")] pub struct MissingValue; #[async_trait::async_trait(?Send)] impl + Send + Sync> FromOperationState for AuthenticatedUser { type Error = MissingValue; async fn from_state( _object: &O, _operation: &D, state: &StackOperationState, ) -> Result> { state.user.clone().ok_or(ExtractorError(MissingValue)) } } #[async_trait::async_trait(?Send)] impl + Send + Sync> FromOperationState for AuthenticatedInstance { type Error = MissingValue; async fn from_state( _object: &O, _operation: &D, state: &StackOperationState, ) -> Result> { state.instance.clone().ok_or(ExtractorError(MissingValue)) } } #[async_trait::async_trait(?Send)] impl< T: FromOperationState + Send + Sync, O: GiteratedObject + Sync, D: GiteratedOperation + Send + Sync, > FromOperationState for Option { type Error = Infallible; async fn from_state( object: &O, operation: &D, state: &StackOperationState, ) -> Result, ExtractorError> { Ok(T::from_state(object, operation, state).await.ok()) } } #[derive(Clone)] pub struct AuthorizedUser(AuthenticatedUser); #[derive(Clone)] pub struct AuthorizedInstance(AuthenticatedInstance); #[async_trait::async_trait(?Send)] pub trait AuthorizedOperation: GiteratedOperation { type Error: Into; async fn authorize( &self, authorize_for: &O, state: &StackOperationState, ) -> Result>; } #[async_trait::async_trait(?Send)] impl AuthorizedOperation for GetValue { type Error = anyhow::Error; async fn authorize( &self, authorize_for: &O, operation_state: &StackOperationState, ) -> Result> { Ok(operation_state .runtime .get_object::(&authorize_for.to_string(), operation_state) .await .is_ok()) } } #[async_trait::async_trait(?Send)] impl AuthorizedOperation for SetSetting { type Error = MissingValue; async fn authorize( &self, authorize_for: &User, operation_state: &StackOperationState, ) -> Result> { let authenticated_user = operation_state.user.as_ref().ok_or(MissingValue)?; Ok(authorize_for == authenticated_user.deref()) } } #[async_trait::async_trait(?Send)] impl AuthorizedOperation for GetSetting { type Error = MissingValue; async fn authorize( &self, authorize_for: &User, operation_state: &StackOperationState, ) -> Result> { let authenticated_user = operation_state.user.as_ref().ok_or(MissingValue)?; Ok(authorize_for == authenticated_user.deref()) } } #[async_trait::async_trait(?Send)] impl AuthorizedOperation for SetSetting { type Error = anyhow::Error; async fn authorize( &self, authorize_for: &Repository, operation_state: &StackOperationState, ) -> Result> { let authenticated_user = operation_state .user .as_ref() .ok_or_else(|| anyhow::Error::from(MissingValue))?; let mut object = operation_state .runtime .get_object::(&authorize_for.to_string(), operation_state) .await .map_err(anyhow::Error::from)?; let access_list = object .get_setting::(operation_state) .await .map_err(anyhow::Error::from)?; if access_list .0 .iter() .any(|user| user == authenticated_user.deref()) { Ok(true) } else { Ok(false) } } } #[async_trait::async_trait(?Send)] impl AuthorizedOperation for GetSetting { type Error = anyhow::Error; async fn authorize( &self, authorize_for: &Repository, operation_state: &StackOperationState, ) -> Result> { let authenticated_user = operation_state .user .as_ref() .ok_or_else(|| anyhow::Error::from(MissingValue))?; let mut object = operation_state .runtime .get_object::(&authorize_for.to_string(), operation_state) .await .map_err(anyhow::Error::from)?; let access_list = object .get_setting::(operation_state) .await .map_err(anyhow::Error::from)?; if access_list .0 .iter() .any(|user| user == authenticated_user.deref()) { Ok(true) } else { Ok(false) } } } #[async_trait::async_trait(?Send)] impl AuthorizedOperation for RegisterAccountRequest { type Error = Infallible; async fn authorize( &self, authorize_for: &Instance, state: &StackOperationState, ) -> Result> { if state.our_instance == *authorize_for { Ok(true) } else { Ok(false) } } } #[async_trait::async_trait(?Send)] impl AuthorizedOperation for AuthenticationTokenRequest { type Error = Infallible; async fn authorize( &self, authorize_for: &Instance, state: &StackOperationState, ) -> Result> { if state.our_instance == *authorize_for { Ok(true) } else { Ok(false) } } } #[async_trait::async_trait(?Send)] impl AuthorizedOperation for RepositoryCreateRequest { type Error = Infallible; async fn authorize( &self, authorize_for: &Instance, state: &StackOperationState, ) -> Result> { if state.our_instance == *authorize_for { Ok(true) } else { Ok(false) } } } #[async_trait::async_trait(?Send)] impl + Send + Sync> FromOperationState for AuthorizedUser { type Error = UnauthorizedError; async fn from_state( object: &User, operation: &A, state: &StackOperationState, ) -> Result> { // TODO let authenticated = AuthenticatedUser::from_state(object, operation, state) .await .map_err(|_| ExtractorError(UnauthorizedError))?; match operation.authorize(object, state).await { Ok(authorized) => { assert!(authorized); } Err(_err) => return Err(ExtractorError(UnauthorizedError)), }; Ok(AuthorizedUser(authenticated)) } } #[async_trait::async_trait(?Send)] impl + Send + Sync> FromOperationState for AuthorizedInstance { type Error = UnauthorizedError; async fn from_state( object: &Instance, operation: &A, state: &StackOperationState, ) -> Result> { //TODO let authenticated = AuthenticatedInstance::from_state(object, operation, state) .await .map_err(|_| ExtractorError(UnauthorizedError))?; match operation.authorize(object, state).await { Ok(authorized) => { assert!(authorized); } Err(_err) => return Err(ExtractorError(UnauthorizedError)), }; Ok(AuthorizedInstance(authenticated)) } } #[derive(Clone)] pub struct StackOperationState { pub our_instance: Instance, pub runtime: Arc, 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, Debug, Serialize, Deserialize)] #[serde(transparent)] #[serde(bound(deserialize = "S: DeserializeOwned"))] pub struct SettingUpdate(pub S); impl GiteratedOperation for SettingUpdate where O: GiteratedObject, S: Setting + Serialize + DeserializeOwned, { type Success = (); type Failure = (); } #[derive(Clone)] pub struct AnyObject { inner: Arc, kind: &'static str, } impl AnyObject { pub fn new(object: O) -> Self { Self { inner: Arc::new(object) as _, kind: O::object_name(), } } pub fn new_raw(_object: Arc, _kind: &'static str) -> Self { todo!() } pub fn kind(&self) -> &'static str { self.kind } } impl Deref for AnyObject { type Target = dyn Any + Send + Sync; fn deref(&self) -> &Self::Target { self.inner.as_ref() } } #[derive(Clone)] pub struct AnyOperation { inner: Arc, kind: ObjectOperationPair<'static>, } impl AnyOperation { pub fn new + 'static>(operation: D) -> Self { Self { inner: Arc::new(operation) as _, kind: ObjectOperationPair::from_types::(), } } pub fn new_raw( _operation: Arc, _kind: ObjectOperationPair<'static>, ) -> Self { todo!() } pub fn kind(&self) -> ObjectOperationPair<'static> { self.kind } } impl Deref for AnyOperation { type Target = dyn Any + Send + Sync; fn deref(&self) -> &Self::Target { self.inner.as_ref() } } #[derive(Clone)] pub struct AnyValue { inner: Arc, kind: ObjectValuePair<'static>, } impl AnyValue { pub fn new + 'static>( value: V, ) -> Self { Self { inner: Arc::new(value) as _, kind: ObjectValuePair::from_types::(), } } pub fn new_raw(_value: Arc, _kind: ObjectValuePair<'static>) -> Self { todo!() } pub fn kind(&self) -> ObjectValuePair<'static> { self.kind } } impl Deref for AnyValue { type Target = dyn Any + Send + Sync; fn deref(&self) -> &Self::Target { self.inner.as_ref() } } #[derive(Clone)] pub struct AnySetting { inner: Arc, kind: ObjectSettingPair<'static>, } impl AnySetting { pub fn new(setting: S) -> Self { Self { inner: Arc::new(setting) as _, kind: ObjectSettingPair::from_types::(), } } pub fn new_raw( _setting: Arc, _kind: ObjectSettingPair<'static>, ) -> Self { todo!() } pub fn kind(&self) -> ObjectSettingPair<'static> { self.kind } } impl Deref for AnySetting { type Target = dyn Any + Send + Sync; fn deref(&self) -> &Self::Target { self.inner.as_ref() } } #[derive(Clone)] pub struct AnySuccess(pub Arc); #[derive(Clone)] pub struct AnyFailure(pub Arc); /// Should be renamed. /// /// Allows accepting object types that are either GiteratedObject types or /// AnyObject. pub trait MaybeDynamicObject: Clone { fn from_any(object: &AnyObject) -> Self; fn object_name() -> &'static str; } impl MaybeDynamicObject for O { fn from_any(_object: &AnyObject) -> Self { todo!() } fn object_name() -> &'static str { ::object_name() } } impl MaybeDynamicObject for AnyObject { fn from_any(object: &AnyObject) -> Self { object.clone() } fn object_name() -> &'static str { "any" } } pub trait MaybeDynamicValue { fn from_any(value: &AnyValue) -> Self; fn into_any(self) -> AnyValue; fn meta() -> Option; fn value_name() -> &'static str; } impl MaybeDynamicValue for V { fn from_any(_object: &AnyValue) -> Self { todo!() } fn value_name() -> &'static str { todo!() } fn into_any(self) -> AnyValue { todo!() } fn meta() -> Option { todo!() } } impl MaybeDynamicValue for AnyValue { fn value_name() -> &'static str { "any" } fn from_any(value: &AnyValue) -> Self { value.clone() } fn into_any(self) -> AnyValue { self } fn meta() -> Option { todo!() } }