mod dynamic; mod handler; pub use dynamic::*; 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 update; // Temp pub use to figure out what's important pub mod models { pub use anyhow::Error; pub use giterated_models::authenticated::*; pub use giterated_models::error::{IntoInternalError, NetworkOperationError, OperationError}; pub use giterated_models::instance::Instance; pub use giterated_models::object::GiteratedObject; pub use giterated_models::operation::GiteratedOperation; pub use giterated_models::user::User; } use std::{convert::Infallible, ops::Deref}; 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 {0}")] pub struct MissingValue(&'static str); #[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("AuthenticatedUser"))) } } #[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("AuthenticatedInstance"))) } } #[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("AuthenticatedUser"))?; 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("AuthenticatedUser"))?; 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("AuthenticatedUser")))?; 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("AuthenticatedUser")))?; 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 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 = (); } pub struct OperationState(pub OS); #[async_trait::async_trait(?Send)] impl HandlerResolvable for OperationState { type Error = MissingValue; async fn from_handler_state( _required_parameters: &P, operation_state: &OS, ) -> Result { Ok(Self(operation_state.clone())) } }