From 5400d7f799399cb8fed417425e7a1acf30d32968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nadja=20von=20Reitzenstein=20=C4=8Cerpnjak?= Date: Tue, 14 May 2024 11:05:39 +0200 Subject: [PATCH] Implement resource API --- bffhd/capnp/machine.rs | 375 -------------------------------- bffhd/capnp/machinesystem.rs | 133 ----------- bffhd/capnp/mod.rs | 6 +- bffhd/capnp/permissionsystem.rs | 25 --- bffhd/capnp/resource.rs | 30 +++ bffhd/capnp/resources.rs | 49 +++++ bffhd/capnp/session.rs | 2 + 7 files changed, 84 insertions(+), 536 deletions(-) delete mode 100644 bffhd/capnp/machine.rs delete mode 100644 bffhd/capnp/machinesystem.rs create mode 100644 bffhd/capnp/resource.rs create mode 100644 bffhd/capnp/resources.rs diff --git a/bffhd/capnp/machine.rs b/bffhd/capnp/machine.rs deleted file mode 100644 index d05d4f2..0000000 --- a/bffhd/capnp/machine.rs +++ /dev/null @@ -1,375 +0,0 @@ -use crate::capnp::user::User; -use crate::resources::modules::fabaccess::{ArchivedStatus, Status}; -use crate::resources::Resource; -use crate::session::SessionHandle; -use api::general_capnp::optional; -use api::machine_capnp::machine::{ - self, admin, admin::Server as AdminServer, check, check::Server as CheckServer, - in_use as inuse, in_use::Server as InUseServer, info, info::Server as InfoServer, manage, - manage::Server as ManageServer, use_, use_::Server as UseServer, MachineState, -}; -use capnp::capability::Promise; -use capnp_rpc::pry; - -#[derive(Clone)] -pub struct Machine { - session: SessionHandle, - resource: Resource, -} - -impl Machine { - pub fn new(session: SessionHandle, resource: Resource) -> Self { - Self { session, resource } - } - - pub fn build_into(self, mut builder: machine::Builder) { - builder.set_id(self.resource.get_id()); - builder.set_name(self.resource.get_name()); - if let Some(ref desc) = self.resource.get_description().description { - builder.set_description(desc); - } - if let Some(ref wiki) = self.resource.get_description().wiki { - builder.set_wiki(wiki); - } - if let Some(ref category) = self.resource.get_description().category { - builder.set_category(category); - } - builder.set_urn(&format!( - "urn:fabaccess:resource:{}", - self.resource.get_id() - )); - - { - let user = self.session.get_user_ref(); - let state = self.resource.get_state_ref(); - let state = state.as_ref(); - - if self.session.has_write(&self.resource) - && match &state.inner.state { - ArchivedStatus::Free => true, - ArchivedStatus::Reserved(reserver) if reserver == &user => true, - _ => false, - } - { - builder.set_use(capnp_rpc::new_client(self.clone())); - } - - if self.session.has_manage(&self.resource) { - builder.set_manage(capnp_rpc::new_client(self.clone())); - } - - // TODO: admin perm - - let s = match &state.inner.state { - ArchivedStatus::Free => MachineState::Free, - ArchivedStatus::Disabled => MachineState::Disabled, - ArchivedStatus::Blocked(_) => MachineState::Blocked, - ArchivedStatus::InUse(owner) => { - if owner == &user { - builder.set_inuse(capnp_rpc::new_client(self.clone())); - } - MachineState::InUse - } - ArchivedStatus::Reserved(_) => MachineState::Reserved, - ArchivedStatus::ToCheck(_) => MachineState::ToCheck, - }; - if self.session.has_read(&self.resource) { - builder.set_state(s); - } - } - - builder.set_info(capnp_rpc::new_client(self)); - } - - /// Builds a machine into the given builder. Re - pub fn build(session: SessionHandle, resource: Resource, builder: machine::Builder) { - let this = Self::new(session.clone(), resource.clone()); - this.build_into(builder) - } - - pub fn optional_build( - session: SessionHandle, - resource: Resource, - builder: optional::Builder, - ) { - let this = Self::new(session.clone(), resource.clone()); - if this.resource.visible(&session) || session.has_read(&resource) { - let builder = builder.init_just(); - this.build_into(builder); - } - } -} - -impl InfoServer for Machine { - fn get_property_list( - &mut self, - _: info::GetPropertyListParams, - _: info::GetPropertyListResults, - ) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) - } - fn get_reservation_list( - &mut self, - _: info::GetReservationListParams, - _: info::GetReservationListResults, - ) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) - } -} - -impl UseServer for Machine { - fn use_(&mut self, _: use_::UseParams, _: use_::UseResults) -> Promise<(), ::capnp::Error> { - let resource = self.resource.clone(); - let session = self.session.clone(); - Promise::from_future(async move { - let user = session.get_user_ref(); - resource.try_update(session, Status::InUse(user)).await; - Ok(()) - }) - } - - fn reserve( - &mut self, - _: use_::ReserveParams, - _: use_::ReserveResults, - ) -> Promise<(), ::capnp::Error> { - let resource = self.resource.clone(); - let session = self.session.clone(); - Promise::from_future(async move { - let user = session.get_user_ref(); - resource.try_update(session, Status::Reserved(user)).await; - Ok(()) - }) - } - - fn reserveto( - &mut self, - _: use_::ReservetoParams, - _: use_::ReservetoResults, - ) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) - } -} - -impl InUseServer for Machine { - fn give_back( - &mut self, - _: inuse::GiveBackParams, - _: inuse::GiveBackResults, - ) -> Promise<(), ::capnp::Error> { - let resource = self.resource.clone(); - let session = self.session.clone(); - Promise::from_future(async move { - resource.give_back(session.clone()).await; - Ok(()) - }) - } - - fn send_raw_data( - &mut self, - _: inuse::SendRawDataParams, - _: inuse::SendRawDataResults, - ) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) - } -} - -impl CheckServer for Machine { - fn check( - &mut self, - _: check::CheckParams, - _: check::CheckResults, - ) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) - } - - fn reject( - &mut self, - _: check::RejectParams, - _: check::RejectResults, - ) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) - } -} - -impl ManageServer for Machine { - fn get_machine_info_extended( - &mut self, - _: manage::GetMachineInfoExtendedParams, - mut result: manage::GetMachineInfoExtendedResults, - ) -> Promise<(), ::capnp::Error> { - let mut builder = result.get(); - let user = User::new_self(self.session.clone()); - User::build_optional( - &self.session, - self.resource.get_current_user(), - builder.reborrow().init_current_user(), - ); - User::build_optional( - &self.session, - self.resource.get_previous_user(), - builder.init_last_user(), - ); - Promise::ok(()) - } - fn set_property( - &mut self, - _: manage::SetPropertyParams, - _: manage::SetPropertyResults, - ) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) - } - fn remove_property( - &mut self, - _: manage::RemovePropertyParams, - _: manage::RemovePropertyResults, - ) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) - } - - fn force_use( - &mut self, - _: manage::ForceUseParams, - _: manage::ForceUseResults, - ) -> Promise<(), ::capnp::Error> { - let resource = self.resource.clone(); - let session = self.session.clone(); - Promise::from_future(async move { - resource - .force_set(Status::InUse(session.get_user_ref())) - .await; - Ok(()) - }) - } - - fn force_free( - &mut self, - _: manage::ForceFreeParams, - _: manage::ForceFreeResults, - ) -> Promise<(), ::capnp::Error> { - let resource = self.resource.clone(); - let _session = self.session.clone(); - Promise::from_future(async move { - resource.force_set(Status::Free).await; - Ok(()) - }) - } - fn force_transfer( - &mut self, - _: manage::ForceTransferParams, - _: manage::ForceTransferResults, - ) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) - } - - fn block( - &mut self, - _: manage::BlockParams, - _: manage::BlockResults, - ) -> Promise<(), ::capnp::Error> { - let resource = self.resource.clone(); - let session = self.session.clone(); - Promise::from_future(async move { - resource - .force_set(Status::Blocked(session.get_user_ref())) - .await; - Ok(()) - }) - } - fn disabled( - &mut self, - _: manage::DisabledParams, - _: manage::DisabledResults, - ) -> Promise<(), ::capnp::Error> { - let resource = self.resource.clone(); - Promise::from_future(async move { - resource.force_set(Status::Disabled).await; - Ok(()) - }) - } -} - -impl AdminServer for Machine { - fn force_set_state( - &mut self, - params: admin::ForceSetStateParams, - _: admin::ForceSetStateResults, - ) -> Promise<(), ::capnp::Error> { - use api::schema::machine_capnp::machine::MachineState as APIMState; - let user = self.session.get_user_ref(); - let state = match pry!(pry!(params.get()).get_state()) { - APIMState::Free => Status::Free, - APIMState::Blocked => Status::Blocked(user), - APIMState::Disabled => Status::Disabled, - APIMState::InUse => Status::InUse(user), - APIMState::Reserved => Status::Reserved(user), - APIMState::ToCheck => Status::ToCheck(user), - APIMState::Totakeover => { - return Promise::err(::capnp::Error::unimplemented( - "totakeover not implemented".to_string(), - )) - } - }; - let resource = self.resource.clone(); - Promise::from_future(async move { - resource.force_set(state).await; - Ok(()) - }) - } - - fn force_set_user( - &mut self, - _: admin::ForceSetUserParams, - _: admin::ForceSetUserResults, - ) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) - } - - fn get_admin_property_list( - &mut self, - _: admin::GetAdminPropertyListParams, - _: admin::GetAdminPropertyListResults, - ) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) - } - fn set_admin_property( - &mut self, - _: admin::SetAdminPropertyParams, - _: admin::SetAdminPropertyResults, - ) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) - } - fn remove_admin_property( - &mut self, - _: admin::RemoveAdminPropertyParams, - _: admin::RemoveAdminPropertyResults, - ) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) - } -} diff --git a/bffhd/capnp/machinesystem.rs b/bffhd/capnp/machinesystem.rs deleted file mode 100644 index fad4240..0000000 --- a/bffhd/capnp/machinesystem.rs +++ /dev/null @@ -1,133 +0,0 @@ -use crate::capnp::machine::Machine; -use crate::resources::search::ResourcesHandle; -use crate::resources::Resource; -use crate::session::SessionHandle; -use crate::RESOURCES; -use api::machinesystem_capnp::machine_system::info; -use capnp::capability::Promise; -use capnp_rpc::pry; -use tracing::Span; - -const TARGET: &str = "bffh::api::machinesystem"; - -#[derive(Clone)] -pub struct Machines { - span: Span, - session: SessionHandle, - resources: ResourcesHandle, -} - -impl Machines { - pub fn new(session: SessionHandle) -> Self { - let span = tracing::info_span!( - target: TARGET, - parent: &session.span, - "MachineSystem", - ); - // FIXME no unwrap bad - Self { - span, - session, - resources: RESOURCES.get().unwrap().clone(), - } - } -} - -impl info::Server for Machines { - fn get_machine_list( - &mut self, - _: info::GetMachineListParams, - mut result: info::GetMachineListResults, - ) -> Promise<(), ::capnp::Error> { - let _guard = self.span.enter(); - let _span = tracing::trace_span!( - target: TARGET, - parent: &self.span, - "getMachineList", - ) - .entered(); - - tracing::trace!("method call"); - - let machine_list: Vec<(usize, &Resource)> = self - .resources - .list_all() - .into_iter() - .filter(|resource| resource.visible(&self.session)) - .enumerate() - .collect(); - let mut builder = result.get().init_machine_list(machine_list.len() as u32); - for (i, m) in machine_list { - let resource = m.clone(); - let mbuilder = builder.reborrow().get(i as u32); - Machine::build(self.session.clone(), resource, mbuilder); - } - - // TODO: indicate result? - tracing::trace!("method return"); - - Promise::ok(()) - } - - fn get_machine( - &mut self, - params: info::GetMachineParams, - mut result: info::GetMachineResults, - ) -> Promise<(), ::capnp::Error> { - let _guard = self.span.enter(); - let _span = tracing::trace_span!( - target: TARGET, - parent: &self.span, - "getMachine", - ) - .entered(); - - let params = pry!(params.get()); - let id = pry!(params.get_id()); - - tracing::trace!(params.id = id, "method call"); - - if let Some(resource) = self.resources.get_by_id(id) { - tracing::trace!(results = "Just", results.inner = id, "method return"); - let builder = result.get(); - Machine::optional_build(self.session.clone(), resource.clone(), builder); - } else { - tracing::trace!(results = "Nothing", "method return"); - } - - Promise::ok(()) - } - - fn get_machine_u_r_n( - &mut self, - params: info::GetMachineURNParams, - mut result: info::GetMachineURNResults, - ) -> Promise<(), ::capnp::Error> { - let _guard = self.span.enter(); - let _span = tracing::trace_span!( - target: TARGET, - parent: &self.span, - "getMachineURN", - ) - .entered(); - - let params = pry!(params.get()); - let urn = pry!(params.get_urn()); - - tracing::trace!(params.urn = urn, "method call"); - - if let Some(resource) = self.resources.get_by_urn(urn) { - tracing::trace!( - results = "Just", - results.inner = resource.get_id(), - "method return" - ); - let builder = result.get(); - Machine::optional_build(self.session.clone(), resource.clone(), builder); - } else { - tracing::trace!(results = "Nothing", "method return"); - } - - Promise::ok(()) - } -} diff --git a/bffhd/capnp/mod.rs b/bffhd/capnp/mod.rs index 1335c26..282dd06 100644 --- a/bffhd/capnp/mod.rs +++ b/bffhd/capnp/mod.rs @@ -25,9 +25,9 @@ pub use config::{Listen, TlsListen}; mod connection; mod authenticationsystem; mod session; -//mod machine; -//mod machinesystem; -//mod permissionsystem; +mod resource; +mod resources; +mod permissionsystem; mod user; mod user_system; diff --git a/bffhd/capnp/permissionsystem.rs b/bffhd/capnp/permissionsystem.rs index 6e8eac3..00ab454 100644 --- a/bffhd/capnp/permissionsystem.rs +++ b/bffhd/capnp/permissionsystem.rs @@ -1,8 +1,5 @@ use crate::authorization::roles::Role; use crate::Roles; -use api::permissionsystem_capnp::permission_system::info::{ - GetRoleListParams, GetRoleListResults, Server as PermissionSystem, -}; use capnp::capability::Promise; use capnp::Error; use tracing::Span; @@ -25,25 +22,3 @@ impl Permissions { } } } - -impl PermissionSystem for Permissions { - fn get_role_list( - &mut self, - _: GetRoleListParams, - mut results: GetRoleListResults, - ) -> Promise<(), Error> { - let _guard = self.span.enter(); - let _span = tracing::trace_span!(target: TARGET, "getRoleList",).entered(); - - tracing::trace!("method call"); - let roles = self.roles.list().collect::>(); - let mut builder = results.get(); - let mut b = builder.init_role_list(roles.len() as u32); - for (i, role) in roles.into_iter().enumerate() { - let mut role_builder = b.reborrow().get(i as u32); - role_builder.set_name(role); - } - tracing::trace!("method return"); - Promise::ok(()) - } -} diff --git a/bffhd/capnp/resource.rs b/bffhd/capnp/resource.rs new file mode 100644 index 0000000..2041840 --- /dev/null +++ b/bffhd/capnp/resource.rs @@ -0,0 +1,30 @@ +use crate::capnp::user::User; +use crate::resources::modules::fabaccess::{ArchivedStatus, Status}; +use crate::resources::Resource; +use crate::session::SessionHandle; +use api::resource_capnp::resource; +use api::claim_capnp::claimable; +use capnp::capability::Promise; +use capnp_rpc::pry; + +#[derive(Clone)] +pub struct Machine { + session: SessionHandle, + resource: Resource, +} + +impl Machine { + pub fn new(session: SessionHandle, resource: Resource) -> Self { + Self { session, resource } + } + pub fn fill_resource(self, builder: &mut resource::Builder) { + builder.set_identifier(self.resource.get_id()); + builder.set_claim(capnp_rpc::new_client(self.clone())); + } +} + + + +impl claimable::Server for Machine { + +} \ No newline at end of file diff --git a/bffhd/capnp/resources.rs b/bffhd/capnp/resources.rs new file mode 100644 index 0000000..229b037 --- /dev/null +++ b/bffhd/capnp/resources.rs @@ -0,0 +1,49 @@ +use crate::capnp::resource::Machine; +use crate::resources::search::ResourcesHandle; +use crate::resources::Resource; +use crate::session::SessionHandle; +use crate::RESOURCES; +use api::resources_capnp::resources::{GetByNameParams, GetByNameResults, Server as ResourcesServer}; +use capnp::capability::Promise; +use capnp::Error; +use capnp_rpc::pry; +use tracing::Span; + +const TARGET: &str = "bffh::api::machinesystem"; + +#[derive(Clone)] +pub struct Machines { + span: Span, + session: SessionHandle, + resources: ResourcesHandle, +} + +impl Machines { + pub fn new(session: SessionHandle) -> Self { + let span = tracing::info_span!( + target: TARGET, + parent: &session.span, + "MachineSystem", + ); + // FIXME no unwrap bad + Self { + span, + session, + resources: RESOURCES.get().unwrap().clone(), + } + } +} + +impl ResourcesServer for Machines { + fn get_by_name(&mut self, params: GetByNameParams, mut results: GetByNameResults) -> Promise<(), Error> { + let params = pry!(pry!(params.get()).get_name()); + + if let Some(r) = self.resources.get_by_id(params) { + let mut builder = results.get().init_ok(); + let machine = Machine::new(self.session.clone(), r.clone()); + machine.fill_resource(&mut builder); + } + + Promise::ok(()) + } +} \ No newline at end of file diff --git a/bffhd/capnp/session.rs b/bffhd/capnp/session.rs index 67b4f0f..c8ede3e 100644 --- a/bffhd/capnp/session.rs +++ b/bffhd/capnp/session.rs @@ -1,6 +1,7 @@ use crate::authorization::permissions::Permission; use api::main_capnp::session::Owned as CPSession; use api::auth_capnp::response::successful::Builder; +use crate::capnp::resources::Machines; use crate::session::SessionHandle; @@ -15,5 +16,6 @@ impl APISession { pub fn build(session: SessionHandle, builder: Builder) { let mut builder = builder.init_session(); + builder.set_resources(capnp_rpc::new_client(Machines::new(session))) } }