sensible search return values for non-existant/non-visible resources

This commit is contained in:
Nadja Reitzenstein 2022-04-22 19:57:58 +02:00
parent 15c878e1d2
commit 047f7bc1de
5 changed files with 261 additions and 63 deletions

@ -1 +1 @@
Subproject commit 2406e77fb9fd2ce3d6e183742521a5d9c9cf77af
Subproject commit aa006507c48ac734fd09d524d0c84736b0147338

View File

@ -296,3 +296,194 @@ pub mod key_value_pair {
pub const TYPE_ID: u64 = 0xfb54_3b21_ce63_7bf1;
}
}
pub mod optional { /* T */
pub use self::Which::{Nothing,Just};
#[derive(Copy, Clone)]
pub struct Owned<T> {
_phantom: ::core::marker::PhantomData<T>
}
impl <'a, T> ::capnp::traits::Owned<'a> for Owned <T> where T: for<'c> ::capnp::traits::Owned<'c> { type Reader = Reader<'a, T>; type Builder = Builder<'a, T>; }
impl <'a, T> ::capnp::traits::OwnedStruct<'a> for Owned <T> where T: for<'c> ::capnp::traits::Owned<'c> { type Reader = Reader<'a, T>; type Builder = Builder<'a, T>; }
impl <T> ::capnp::traits::Pipelined for Owned<T> where T: for<'c> ::capnp::traits::Owned<'c> { type Pipeline = Pipeline<T>; }
#[derive(Clone, Copy)]
pub struct Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
reader: ::capnp::private::layout::StructReader<'a>,
_phantom: ::core::marker::PhantomData<T>
}
impl <'a,T> ::capnp::traits::HasTypeId for Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
#[inline]
fn type_id() -> u64 { _private::TYPE_ID }
}
impl <'a,T> ::capnp::traits::FromStructReader<'a> for Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
fn new(reader: ::capnp::private::layout::StructReader<'a>) -> Reader<'a,T> {
Reader { reader, _phantom: ::core::marker::PhantomData, }
}
}
impl <'a,T> ::capnp::traits::FromPointerReader<'a> for Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [capnp::Word]>) -> ::capnp::Result<Reader<'a,T>> {
::core::result::Result::Ok(::capnp::traits::FromStructReader::new(reader.get_struct(default)?))
}
}
impl <'a,T> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> {
self.reader
}
}
impl <'a,T> ::capnp::traits::Imbue<'a> for Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) {
self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table))
}
}
impl <'a,T> Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
pub fn reborrow(&self) -> Reader<'_,T> {
Reader { .. *self }
}
pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> {
self.reader.total_size()
}
pub fn has_just(&self) -> bool {
if self.reader.get_data_field::<u16>(0) != 1 { return false; }
!self.reader.get_pointer_field(0).is_null()
}
#[inline]
pub fn which(self) -> ::core::result::Result<WhichReader<'a,T>, ::capnp::NotInSchema> {
match self.reader.get_data_field::<u16>(0) {
0 => {
::core::result::Result::Ok(Nothing(
()
))
}
1 => {
::core::result::Result::Ok(Just(
::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None)
))
}
x => ::core::result::Result::Err(::capnp::NotInSchema(x))
}
}
}
pub struct Builder<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
builder: ::capnp::private::layout::StructBuilder<'a>,
_phantom: ::core::marker::PhantomData<T>
}
impl <'a,T> ::capnp::traits::HasStructSize for Builder<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
#[inline]
fn struct_size() -> ::capnp::private::layout::StructSize { _private::STRUCT_SIZE }
}
impl <'a,T> ::capnp::traits::HasTypeId for Builder<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
#[inline]
fn type_id() -> u64 { _private::TYPE_ID }
}
impl <'a,T> ::capnp::traits::FromStructBuilder<'a> for Builder<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
fn new(builder: ::capnp::private::layout::StructBuilder<'a>) -> Builder<'a, T> {
Builder { builder, _phantom: ::core::marker::PhantomData, }
}
}
impl <'a,T> ::capnp::traits::ImbueMut<'a> for Builder<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) {
self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table))
}
}
impl <'a,T> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Builder<'a,T> {
::capnp::traits::FromStructBuilder::new(builder.init_struct(_private::STRUCT_SIZE))
}
fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [capnp::Word]>) -> ::capnp::Result<Builder<'a,T>> {
::core::result::Result::Ok(::capnp::traits::FromStructBuilder::new(builder.get_struct(_private::STRUCT_SIZE, default)?))
}
}
impl <'a,T> ::capnp::traits::SetPointerBuilder for Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
fn set_pointer_builder<'b>(pointer: ::capnp::private::layout::PointerBuilder<'b>, value: Reader<'a,T>, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) }
}
impl <'a,T> Builder<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> {
pub fn into_reader(self) -> Reader<'a,T> {
::capnp::traits::FromStructReader::new(self.builder.into_reader())
}
pub fn reborrow(&mut self) -> Builder<'_,T> {
Builder { .. *self }
}
pub fn reborrow_as_reader(&self) -> Reader<'_,T> {
::capnp::traits::FromStructReader::new(self.builder.into_reader())
}
pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> {
self.builder.into_reader().total_size()
}
#[inline]
pub fn set_nothing(&mut self, _value: ()) {
self.builder.set_data_field::<u16>(0, 0);
}
#[inline]
pub fn initn_just(self, length: u32) -> <T as ::capnp::traits::Owned<'a>>::Builder {
self.builder.set_data_field::<u16>(0, 1);
::capnp::any_pointer::Builder::new(self.builder.get_pointer_field(0)).initn_as(length)
}
#[inline]
pub fn set_just(&mut self, value: <T as ::capnp::traits::Owned<'_>>::Reader) -> ::capnp::Result<()> {
self.builder.set_data_field::<u16>(0, 1);
::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field(0), value, false)
}
#[inline]
pub fn init_just(self, ) -> <T as ::capnp::traits::Owned<'a>>::Builder {
self.builder.set_data_field::<u16>(0, 1);
::capnp::any_pointer::Builder::new(self.builder.get_pointer_field(0)).init_as()
}
pub fn has_just(&self) -> bool {
if self.builder.get_data_field::<u16>(0) != 1 { return false; }
!self.builder.get_pointer_field(0).is_null()
}
#[inline]
pub fn which(self) -> ::core::result::Result<WhichBuilder<'a,T>, ::capnp::NotInSchema> {
match self.builder.get_data_field::<u16>(0) {
0 => {
::core::result::Result::Ok(Nothing(
()
))
}
1 => {
::core::result::Result::Ok(Just(
::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None)
))
}
x => ::core::result::Result::Err(::capnp::NotInSchema(x))
}
}
}
pub struct Pipeline<T> {
_typeless: ::capnp::any_pointer::Pipeline,
_phantom: ::core::marker::PhantomData<T>
}
impl<T> ::capnp::capability::FromTypelessPipeline for Pipeline<T> {
fn new(typeless: ::capnp::any_pointer::Pipeline) -> Pipeline<T> {
Pipeline { _typeless: typeless, _phantom: ::core::marker::PhantomData, }
}
}
impl<T> Pipeline<T> where T: ::capnp::traits::Pipelined, <T as ::capnp::traits::Pipelined>::Pipeline: ::capnp::capability::FromTypelessPipeline {
}
mod _private {
use capnp::private::layout;
pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 1 };
pub const TYPE_ID: u64 = 0xd77e_cca2_05b0_6927;
}
pub enum Which<A0> {
Nothing(()),
Just(A0),
}
pub type WhichReader<'a,T> = Which<::capnp::Result<<T as ::capnp::traits::Owned<'a>>::Reader>>;
pub type WhichBuilder<'a,T> = Which<::capnp::Result<<T as ::capnp::traits::Owned<'a>>::Builder>>;
}

View File

@ -136,9 +136,9 @@ pub mod machine_system {
pub type GetMachineListParams<> = ::capnp::capability::Params<crate::schema::machinesystem_capnp::machine_system::info::get_machine_list_params::Owned>;
pub type GetMachineListResults<> = ::capnp::capability::Results<crate::schema::machinesystem_capnp::machine_system::info::get_machine_list_results::Owned>;
pub type GetMachineParams<> = ::capnp::capability::Params<crate::schema::machinesystem_capnp::machine_system::info::get_machine_params::Owned>;
pub type GetMachineResults<> = ::capnp::capability::Results<crate::schema::machine_capnp::machine::Owned>;
pub type GetMachineResults<> = ::capnp::capability::Results<crate::schema::general_capnp::optional::Owned<crate::schema::machine_capnp::machine::Owned>>;
pub type GetMachineURNParams<> = ::capnp::capability::Params<crate::schema::machinesystem_capnp::machine_system::info::get_machine_u_r_n_params::Owned>;
pub type GetMachineURNResults<> = ::capnp::capability::Results<crate::schema::machine_capnp::machine::Owned>;
pub type GetMachineURNResults<> = ::capnp::capability::Results<crate::schema::general_capnp::optional::Owned<crate::schema::machine_capnp::machine::Owned>>;
pub struct Client {
pub client: ::capnp::capability::Client,
@ -185,10 +185,10 @@ pub mod machine_system {
pub fn get_machine_list_request(&self) -> ::capnp::capability::Request<crate::schema::machinesystem_capnp::machine_system::info::get_machine_list_params::Owned,crate::schema::machinesystem_capnp::machine_system::info::get_machine_list_results::Owned> {
self.client.new_call(_private::TYPE_ID, 0, None)
}
pub fn get_machine_request(&self) -> ::capnp::capability::Request<crate::schema::machinesystem_capnp::machine_system::info::get_machine_params::Owned,crate::schema::machine_capnp::machine::Owned> {
pub fn get_machine_request(&self) -> ::capnp::capability::Request<crate::schema::machinesystem_capnp::machine_system::info::get_machine_params::Owned,crate::schema::general_capnp::optional::Owned<crate::schema::machine_capnp::machine::Owned>> {
self.client.new_call(_private::TYPE_ID, 1, None)
}
pub fn get_machine_u_r_n_request(&self) -> ::capnp::capability::Request<crate::schema::machinesystem_capnp::machine_system::info::get_machine_u_r_n_params::Owned,crate::schema::machine_capnp::machine::Owned> {
pub fn get_machine_u_r_n_request(&self) -> ::capnp::capability::Request<crate::schema::machinesystem_capnp::machine_system::info::get_machine_u_r_n_params::Owned,crate::schema::general_capnp::optional::Owned<crate::schema::machine_capnp::machine::Owned>> {
self.client.new_call(_private::TYPE_ID, 2, None)
}
}

View File

@ -2,12 +2,14 @@ use crate::resources::modules::fabaccess::{ArchivedStatus, Status};
use crate::resources::Resource;
use crate::session::SessionHandle;
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,
Builder, MachineState,
MachineState,
};
use api::general_capnp::optional;
use capnp::capability::Promise;
use capnp_rpc::pry;
use crate::capnp::user::User;
@ -23,68 +25,73 @@ impl Machine {
Self { session, resource }
}
pub fn build_into(self, mut builder: Builder) {
if self.resource.visible(&self.session) {
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));
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: Builder) {
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<machine::Owned>) {
let this = Self::new(session.clone(), resource.clone());
if this.resource.visible(&session) {
let mut builder = builder.init_just();
this.build_into(builder);
}
}
}
impl InfoServer for Machine {

View File

@ -54,7 +54,7 @@ impl info::Server for Machines {
if let Some(resource) = self.resources.get_by_id(id) {
let builder = result.get();
Machine::build(self.session.clone(), resource.clone(), builder);
Machine::optional_build(self.session.clone(), resource.clone(), builder);
}
Promise::ok(())
@ -70,7 +70,7 @@ impl info::Server for Machines {
if let Some(resource) = self.resources.get_by_urn(urn) {
let builder = result.get();
Machine::build(self.session.clone(), resource.clone(), builder);
Machine::optional_build(self.session.clone(), resource.clone(), builder);
}
Promise::ok(())