diff --git a/src/access.rs b/src/access.rs index bdcee5a..cef7470 100644 --- a/src/access.rs +++ b/src/access.rs @@ -19,9 +19,9 @@ use crate::config::Settings; use crate::error::Result; // FIXME: fabinfra/fabaccess/bffh#3 -type UserIdentifier = u64; -type RoleIdentifier = u64; -type PermIdentifier = u64; +pub type UserIdentifier = u64; +pub type RoleIdentifier = u64; +pub type PermIdentifier = u64; pub struct PermissionsProvider { log: Logger, diff --git a/src/machine.rs b/src/machine.rs index 4ad62ed..c60e369 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -11,6 +11,7 @@ use smol::lock::RwLock; use crate::error::Result; use crate::config::Settings; +use crate::access; use capnp::Error; @@ -26,6 +27,7 @@ pub type ID = Uuid; /// Status of a Machine #[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize)] +#[repr(u8)] pub enum Status { /// Not currently used by anybody Free, @@ -100,11 +102,16 @@ impl MachineManager { /// machine, checking that the user who wants the machine (de)activated has the required /// permissions. pub struct Machine { + /// Computer-readable identifier for this machine + // Implicit in database since it's the key. + #[serde(skip)] + id: ID, + /// The human-readable name of the machine. Does not need to be unique name: String, /// The required permission to use this machine. - perm: String, + perm: access::PermIdentifier, /// The state of the machine as bffh thinks the machine *should* be in. /// @@ -114,8 +121,9 @@ pub struct Machine { } impl Machine { - pub fn new(name: String, perm: String) -> Machine { + pub fn new(id: Uuid, name: String, perm: access::PermIdentifier) -> Machine { Machine { + id: id, name: name, perm: perm, state: Mutable::new(Status::Free), @@ -133,6 +141,24 @@ impl Machine { pub fn signal(&self) -> impl Signal { self.state.signal().dedupe() } + + /// Requests to use a machine. Returns `true` if successful. + /// + /// This will update the internal state of the machine, notifying connected actors, if any. + pub fn request_use + ( &mut self + , txn: &T + , pp: &access::PermissionsProvider + , who: access::UserIdentifier + ) -> Result + { + if pp.check(txn, who, self.perm)? { + self.state.set(Status::Occupied); + return Ok(true); + } else { + return Ok(false); + } + } } pub struct MachineDB { @@ -149,7 +175,10 @@ impl MachineDB { { match txn.get(self.db, &uuid.as_bytes()) { Ok(bytes) => { - Ok(Some(flexbuffers::from_slice(bytes)?)) + let mut machine: Machine = flexbuffers::from_slice(bytes)?; + machine.id = uuid; + + Ok(Some(machine)) }, Err(lmdb::Error::NotFound) => { Ok(None) }, Err(e) => { Err(e.into()) }, diff --git a/src/network.rs b/src/network.rs index 9a72bfd..a93b8b0 100644 --- a/src/network.rs +++ b/src/network.rs @@ -34,5 +34,5 @@ impl Network { enum Event { /// An user wants to use a machine // TODO: Define /what/ an user wants to do with said machine? - MachineRequest(machine::ID, access::UserIdentifer), + MachineRequest(machine::ID, access::UserIdentifier), }