mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2025-03-12 16:11:43 +01:00
258 lines
7.9 KiB
Rust
258 lines
7.9 KiB
Rust
|
|
use std::time::Duration;
|
|
|
|
use capnp::capability::Promise;
|
|
|
|
|
|
use futures::FutureExt;
|
|
|
|
use crate::db::access::{Perms};
|
|
use crate::db::user::UserId;
|
|
use crate::db::machine::{Status, MachineState};
|
|
use crate::machine::Machine as NwMachine;
|
|
use crate::schema::machine_capnp::machine::*;
|
|
use crate::schema::machine_capnp::machine::MachineState as APIMState;
|
|
|
|
#[derive(Clone)]
|
|
pub struct Machine {
|
|
userid: UserId,
|
|
perms: Perms,
|
|
machine: NwMachine,
|
|
}
|
|
|
|
impl Machine {
|
|
pub fn new(userid: UserId, perms: Perms, machine: NwMachine) -> Self {
|
|
Self { userid, perms, machine }
|
|
}
|
|
}
|
|
|
|
impl info::Server for Machine {
|
|
fn get_machine_info_extended(
|
|
&mut self,
|
|
_: info::GetMachineInfoExtendedParams,
|
|
mut results: info::GetMachineInfoExtendedResults,
|
|
) -> Promise<(), capnp::Error> {
|
|
let machine = self.machine.get_inner();
|
|
let perms = self.perms.clone();
|
|
let f = async move {
|
|
if perms.manage {
|
|
let builder = results.get();
|
|
let mut extinfo = builder.init_machine_info_extended();
|
|
let guard = machine.lock().await;
|
|
|
|
// "previous" user
|
|
if let Some(user) = guard.get_previous() {
|
|
let mut previous = extinfo.reborrow().init_transfer_user();
|
|
previous.set_username(&user.uid);
|
|
}
|
|
|
|
let state = guard.read_state();
|
|
let state_lock = state.lock_ref();
|
|
match state_lock.state {
|
|
Status::Free => {}
|
|
Status::InUse(ref user) => if user.is_some() {
|
|
let user = user.as_ref().unwrap();
|
|
let mut current = extinfo.init_current_user();
|
|
current.set_username(&user.uid);
|
|
}
|
|
Status::ToCheck(ref user) => {
|
|
let mut current = extinfo.init_current_user();
|
|
current.set_username(&user.uid);
|
|
}
|
|
Status::Blocked(ref user) => {
|
|
let mut current = extinfo.init_current_user();
|
|
current.set_username(&user.uid);
|
|
}
|
|
Status::Disabled => {}
|
|
Status::Reserved(ref user) => {
|
|
let mut current = extinfo.init_current_user();
|
|
current.set_username(&user.uid);
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
};
|
|
|
|
let g = smol::future::race(f, smol::Timer::after(Duration::from_secs(4))
|
|
.map(|_| Err(capnp::Error::failed("Waiting for machine lock timed out!".to_string()))));
|
|
|
|
Promise::from_future(g)
|
|
}
|
|
|
|
fn get_reservation_list(
|
|
&mut self,
|
|
_: info::GetReservationListParams,
|
|
_results: info::GetReservationListResults,
|
|
) -> Promise<(), capnp::Error> {
|
|
Promise::err(capnp::Error::unimplemented("Reservations are unavailable".to_string()))
|
|
}
|
|
|
|
fn get_property_list(
|
|
&mut self,
|
|
_: info::GetPropertyListParams,
|
|
_results: info::GetPropertyListResults,
|
|
) -> Promise<(), capnp::Error> {
|
|
Promise::err(capnp::Error::unimplemented("Extended Properties are unavailable".to_string()))
|
|
}
|
|
}
|
|
|
|
impl use_::Server for Machine {
|
|
fn use_(
|
|
&mut self,
|
|
_: use_::UseParams,
|
|
_: use_::UseResults
|
|
) -> Promise<(), capnp::Error> {
|
|
let machine = self.machine.get_inner();
|
|
let userid = self.userid.clone();
|
|
let f = async move {
|
|
let mut guard = machine.lock().await;
|
|
let mut ok = false;
|
|
{
|
|
match { guard.read_state().lock_ref().state.clone() } {
|
|
Status::Free => {
|
|
ok = true;
|
|
},
|
|
Status::Reserved(ref whom) => {
|
|
// If it's reserved for us or we're allowed to take over
|
|
if &userid == whom {
|
|
ok = true;
|
|
}
|
|
},
|
|
_ => { }
|
|
}
|
|
}
|
|
|
|
if ok {
|
|
guard.do_state_change(MachineState::used(Some(userid)));
|
|
}
|
|
|
|
Ok(())
|
|
};
|
|
|
|
let g = smol::future::race(f, smol::Timer::after(Duration::from_secs(4))
|
|
.map(|_| Err(capnp::Error::failed("Waiting for machine lock timed out!".to_string()))));
|
|
|
|
Promise::from_future(g)
|
|
}
|
|
}
|
|
|
|
impl in_use::Server for Machine {
|
|
fn give_back(
|
|
&mut self,
|
|
_:in_use::GiveBackParams,
|
|
_:in_use::GiveBackResults
|
|
) -> Promise<(), capnp::Error> {
|
|
let machine = self.machine.get_inner();
|
|
let userid = self.userid.clone();
|
|
let f = async move {
|
|
let mut guard = machine.lock().await;
|
|
let mut ok = false;
|
|
{
|
|
match { guard.read_state().lock_ref().state.clone() } {
|
|
Status::InUse(ref whom) => {
|
|
if &Some(userid) == whom {
|
|
ok = true;
|
|
}
|
|
},
|
|
_ => { }
|
|
}
|
|
}
|
|
|
|
if ok {
|
|
guard.reset_state()
|
|
}
|
|
|
|
Ok(())
|
|
};
|
|
|
|
Promise::from_future(f)
|
|
}
|
|
}
|
|
|
|
impl transfer::Server for Machine {
|
|
}
|
|
|
|
impl check::Server for Machine {
|
|
}
|
|
|
|
impl manage::Server for Machine {
|
|
fn force_free(&mut self,
|
|
_: manage::ForceFreeParams,
|
|
_: manage::ForceFreeResults
|
|
) -> Promise<(), capnp::Error> {
|
|
let machine = self.machine.get_inner();
|
|
let f = async move {
|
|
let mut guard = machine.lock().await;
|
|
guard.do_state_change(MachineState::free());
|
|
Ok(())
|
|
};
|
|
Promise::from_future(f)
|
|
}
|
|
|
|
fn force_use(&mut self,
|
|
_: manage::ForceUseParams,
|
|
_: manage::ForceUseResults
|
|
) -> Promise<(), capnp::Error> {
|
|
let machine = self.machine.get_inner();
|
|
let f = async move {
|
|
let mut guard = machine.lock().await;
|
|
guard.do_state_change(MachineState::used(None));
|
|
Ok(())
|
|
};
|
|
Promise::from_future(f)
|
|
}
|
|
|
|
fn block(&mut self,
|
|
_:manage::BlockParams,
|
|
_:manage::BlockResults
|
|
) -> Promise<(), capnp::Error> {
|
|
let machine = self.machine.get_inner();
|
|
let uid = self.userid.clone();
|
|
let f = async move {
|
|
let mut guard = machine.lock().await;
|
|
guard.do_state_change(MachineState::blocked(uid));
|
|
Ok(())
|
|
};
|
|
Promise::from_future(f)
|
|
}
|
|
|
|
fn disabled(&mut self,
|
|
_:manage::DisabledParams,
|
|
_:manage::DisabledResults
|
|
) -> Promise<(), capnp::Error> {
|
|
let machine = self.machine.get_inner();
|
|
let f = async move {
|
|
let mut guard = machine.lock().await;
|
|
guard.do_state_change(MachineState::disabled());
|
|
Ok(())
|
|
};
|
|
Promise::from_future(f)
|
|
}
|
|
}
|
|
|
|
impl admin::Server for Machine {
|
|
fn force_set_state(&mut self,
|
|
params: admin::ForceSetStateParams,
|
|
_:admin::ForceSetStateResults
|
|
) -> Promise<(), capnp::Error> {
|
|
let uid = self.userid.clone();
|
|
let state = match pry!(pry!(params.get()).get_state()) {
|
|
APIMState::Free => MachineState::free(),
|
|
APIMState::Blocked => MachineState::blocked(uid),
|
|
APIMState::Disabled => MachineState::disabled(),
|
|
APIMState::InUse => MachineState::used(Some(uid)),
|
|
APIMState::Reserved => MachineState::reserved(uid),
|
|
APIMState::ToCheck => MachineState::check(uid),
|
|
};
|
|
let machine = self.machine.get_inner();
|
|
let f = async move {
|
|
let mut guard = machine.lock().await;
|
|
guard.do_state_change(state);
|
|
Ok(())
|
|
};
|
|
Promise::from_future(f)
|
|
}
|
|
|
|
}
|