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 once_cell::sync::Lazy;
use rumqttc::ConnectReturnCode::Success;
use rumqttc::Packet::ConnAck;
use rustls::{RootCertStore};
use url::Url;
use crate::actors::dummy::Dummy;
@ -153,6 +155,13 @@ pub fn load(executor: Executor, config: &Config, resources: ResourcesHandle) ->
async move {
match eventloop.poll().await {
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) => {
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::session::SessionHandle;
use api::machine_capnp::machine::{
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,
manage::Server as ManageServer, use_, use_::Server as UseServer,
Builder, MachineState,
};
use capnp::capability::Promise;
use capnp_rpc::pry;
@ -16,9 +18,71 @@ pub struct 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
pub fn build(session: SessionHandle, resource: Resource, _builder: Builder) {
if resource.visible(&session) {}
pub fn build(session: SessionHandle, resource: Resource, builder: Builder) {
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");
previous
} else {
tracing::info!(%id, "No previous state, defaulting to `free`");
let state = MachineState::used(UserRef::new("test".to_string()), Some(UserRef::new("prev".to_string())));
let state = MachineState::free(None);
tracing::info!(%id, ?state, "No previous state found, setting default");
let update = state.to_state();
@ -61,7 +61,7 @@ impl Inner {
.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()
}
@ -93,10 +93,18 @@ impl Resource {
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 {
&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>> {
self.inner.signal()
}
@ -105,6 +113,10 @@ impl Resource {
&self.inner.desc.privs
}
pub fn get_description(&self) -> &MachineDescription {
&self.inner.desc
}
fn set_state(&self, state: MachineState) {
let mut serializer = AllocSerializer::<1024>::default();
serializer.serialize_value(&state);
@ -181,12 +193,12 @@ impl Resource {
let state = self.get_state();
let s: &Archived<State> = state.as_ref();
let i: &Archived<MachineState> = &s.inner;
unimplemented!();
/*if let Status::InUse(user) = self.get_state().state {
if user == session.get_user() {
self.set_state(MachineState::free(Some(user)));
if let ArchivedStatus::InUse(user) = &i.state {
let current = session.get_user();
if user == &current {
self.set_state(MachineState::free(Some(current)));
}
}*/
}
}
pub async fn force_set(&self, new: Status) {

View File

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

View File

@ -25,7 +25,7 @@ impl SessionManager {
pub fn open(&self, uid: impl AsRef<str>) -> Option<SessionHandle> {
let uid = uid.as_ref();
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 {
users: self.users.clone(),
roles: self.roles.clone(),

View File

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

View File

@ -2,7 +2,7 @@
# 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
# 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.
passwd = "secret"