Make capnp machines api work again

This commit is contained in:
Nadja Reitzenstein 2022-03-16 19:01:09 +01:00
parent 2b7044d498
commit 29a44bdb6a
7 changed files with 101 additions and 16 deletions

View File

@ -16,6 +16,8 @@ use std::task::{Context, Poll};
use std::time::Duration; use std::time::Duration;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use rumqttc::ConnectReturnCode::Success;
use rumqttc::Packet::ConnAck;
use rustls::{RootCertStore}; use rustls::{RootCertStore};
use url::Url; use url::Url;
use crate::actors::dummy::Dummy; use crate::actors::dummy::Dummy;
@ -153,6 +155,13 @@ pub fn load(executor: Executor, config: &Config, resources: ResourcesHandle) ->
async move { async move {
match eventloop.poll().await { match eventloop.poll().await {
Ok(Event::Incoming(Incoming::Connect(_connect))) => {} Ok(Event::Incoming(Incoming::Connect(_connect))) => {}
Ok(Event::Incoming(Incoming::ConnAck(connack))) => {
if connack.code == Success {
tracing::debug!(?connack, "MQTT connection established");
} else {
tracing::error!(?connack, "MQTT connect failed");
}
}
Ok(event) => { Ok(event) => {
tracing::warn!(?event, "Got unexpected mqtt event"); tracing::warn!(?event, "Got unexpected mqtt event");
} }

View File

@ -1,10 +1,12 @@
use crate::resources::modules::fabaccess::{Status}; use crate::resources::modules::fabaccess::{ArchivedStatus, Status};
use crate::resources::Resource; use crate::resources::Resource;
use crate::session::SessionHandle; use crate::session::SessionHandle;
use api::machine_capnp::machine::{ use api::machine_capnp::machine::{
admin, admin::Server as AdminServer, check, check::Server as CheckServer, in_use as inuse, 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, in_use::Server as InUseServer, info, info::Server as InfoServer, manage,
manage::Server as ManageServer, use_, use_::Server as UseServer, Builder, manage::Server as ManageServer, use_, use_::Server as UseServer,
Builder, MachineState,
}; };
use capnp::capability::Promise; use capnp::capability::Promise;
use capnp_rpc::pry; use capnp_rpc::pry;
@ -16,9 +18,71 @@ pub struct Machine {
} }
impl Machine { impl Machine {
pub fn new(session: SessionHandle, resource: Resource) -> Self {
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();
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 /// 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: Builder) {
if resource.visible(&session) {} let this = Self::new(session.clone(), resource.clone());
this.build_into(builder)
} }
} }

View File

@ -35,8 +35,8 @@ impl Inner {
tracing::info!(%id, ?previous, "Found previous state"); tracing::info!(%id, ?previous, "Found previous state");
previous previous
} else { } else {
tracing::info!(%id, "No previous state, defaulting to `free`"); let state = MachineState::free(None);
let state = MachineState::used(UserRef::new("test".to_string()), Some(UserRef::new("prev".to_string()))); tracing::info!(%id, ?state, "No previous state found, setting default");
let update = state.to_state(); let update = state.to_state();
@ -61,7 +61,7 @@ impl Inner {
.expect("state should never be None") .expect("state should never be None")
} }
fn get_ref(&self) -> impl Deref<Target=ArchivedValue<State>> + '_ { fn get_state_ref(&self) -> impl Deref<Target=ArchivedValue<State>> + '_ {
self.signal.lock_ref() self.signal.lock_ref()
} }
@ -93,10 +93,18 @@ impl Resource {
self.inner.get_state() self.inner.get_state()
} }
pub fn get_state_ref(&self) -> impl Deref<Target=ArchivedValue<State>> + '_ {
self.inner.get_state_ref()
}
pub fn get_id(&self) -> &str { pub fn get_id(&self) -> &str {
&self.inner.id &self.inner.id
} }
pub fn get_name(&self) -> &str {
self.inner.desc.name.as_str()
}
pub fn get_signal(&self) -> impl Signal<Item=ArchivedValue<State>> { pub fn get_signal(&self) -> impl Signal<Item=ArchivedValue<State>> {
self.inner.signal() self.inner.signal()
} }
@ -105,6 +113,10 @@ impl Resource {
&self.inner.desc.privs &self.inner.desc.privs
} }
pub fn get_description(&self) -> &MachineDescription {
&self.inner.desc
}
fn set_state(&self, state: MachineState) { fn set_state(&self, state: MachineState) {
let mut serializer = AllocSerializer::<1024>::default(); let mut serializer = AllocSerializer::<1024>::default();
serializer.serialize_value(&state); serializer.serialize_value(&state);
@ -181,12 +193,12 @@ impl Resource {
let state = self.get_state(); let state = self.get_state();
let s: &Archived<State> = state.as_ref(); let s: &Archived<State> = state.as_ref();
let i: &Archived<MachineState> = &s.inner; let i: &Archived<MachineState> = &s.inner;
unimplemented!(); if let ArchivedStatus::InUse(user) = &i.state {
/*if let Status::InUse(user) = self.get_state().state { let current = session.get_user();
if user == session.get_user() { if user == &current {
self.set_state(MachineState::free(Some(user))); self.set_state(MachineState::free(Some(current)));
} }
}*/ }
} }
pub async fn force_set(&self, new: Status) { pub async fn force_set(&self, new: Status) {

View File

@ -23,6 +23,7 @@ impl StateDB {
| EnvironmentFlags::NO_TLS | EnvironmentFlags::NO_TLS
| EnvironmentFlags::NO_READAHEAD, | EnvironmentFlags::NO_READAHEAD,
) )
.set_max_dbs(8)
.open(path.as_ref()) .open(path.as_ref())
.map(Arc::new) .map(Arc::new)
} }

View File

@ -25,7 +25,7 @@ impl SessionManager {
pub fn open(&self, uid: impl AsRef<str>) -> Option<SessionHandle> { pub fn open(&self, uid: impl AsRef<str>) -> Option<SessionHandle> {
let uid = uid.as_ref(); let uid = uid.as_ref();
if let Some(user) = self.users.get_user(uid) { if let Some(user) = self.users.get_user(uid) {
tracing::trace!(uid, "opening new session for user"); tracing::trace!(uid, ?user, "opening new session for user");
Some(SessionHandle { Some(SessionHandle {
users: self.users.clone(), users: self.users.clone(),
roles: self.roles.clone(), roles: self.roles.clone(),

View File

@ -105,8 +105,7 @@ impl UserDB {
pub fn put(&self, uid: &str, user: &User) -> Result<(), db::Error> { pub fn put(&self, uid: &str, user: &User) -> Result<(), db::Error> {
let mut serializer = AllocSerializer::<1024>::default(); let mut serializer = AllocSerializer::<1024>::default();
let pos = serializer.serialize_value(user).expect("rkyv error"); serializer.serialize_value(user).expect("rkyv error");
assert_eq!(pos, 0);
let v = serializer.into_serializer().into_inner(); let v = serializer.into_serializer().into_inner();
let value = ArchivedValue::new(v); let value = ArchivedValue::new(v);

View File

@ -2,7 +2,7 @@
# These roles have to be defined in 'bffh.dhall'. # These roles have to be defined in 'bffh.dhall'.
# Non-existant roles will not crash the server but print a `WARN` level message in the # Non-existant roles will not crash the server but print a `WARN` level message in the
# server log in the form "Did not find role somerole/internal while trying to tally". # server log in the form "Did not find role somerole/internal while trying to tally".
roles = ["somerole/internal", "testrole/internal"] roles = ["somerole", "testrole"]
# The password will be hashed using argon2id on load time and is not available in plaintext afterwards. # The password will be hashed using argon2id on load time and is not available in plaintext afterwards.
passwd = "secret" passwd = "secret"