2021-09-20 13:47:08 +02:00
|
|
|
use std::rc::Rc;
|
|
|
|
use std::cell::RefCell;
|
|
|
|
use std::ops::Deref;
|
|
|
|
|
|
|
|
use slog::Logger;
|
|
|
|
|
2020-11-17 14:35:16 +01:00
|
|
|
use std::sync::Arc;
|
|
|
|
|
2020-11-17 14:38:11 +01:00
|
|
|
use capnp::capability::{Params, Results, Promise};
|
2020-11-17 14:35:16 +01:00
|
|
|
|
|
|
|
use crate::schema::connection_capnp;
|
|
|
|
use crate::connection::Session;
|
|
|
|
|
2020-11-20 13:06:55 +01:00
|
|
|
use crate::db::Databases;
|
2021-09-18 17:01:35 +02:00
|
|
|
use crate::db::user::UserId;
|
2020-11-20 13:06:55 +01:00
|
|
|
|
2020-12-15 13:12:22 +01:00
|
|
|
use crate::network::Network;
|
|
|
|
|
2020-11-17 14:35:16 +01:00
|
|
|
pub mod auth;
|
2020-11-17 14:15:29 +01:00
|
|
|
mod machine;
|
|
|
|
mod machines;
|
2020-11-17 14:35:16 +01:00
|
|
|
use machines::Machines;
|
|
|
|
|
2021-09-19 22:53:43 +02:00
|
|
|
mod user;
|
2021-09-19 19:47:29 +02:00
|
|
|
mod users;
|
|
|
|
use users::Users;
|
|
|
|
|
2020-12-09 18:44:52 +01:00
|
|
|
// TODO Session restoration by making the Bootstrap cap a SturdyRef
|
2020-11-17 14:35:16 +01:00
|
|
|
pub struct Bootstrap {
|
2021-09-20 13:47:08 +02:00
|
|
|
log: Logger,
|
|
|
|
|
2020-11-20 13:06:55 +01:00
|
|
|
db: Databases,
|
2020-12-15 13:12:22 +01:00
|
|
|
nw: Arc<Network>,
|
2021-09-20 13:47:08 +02:00
|
|
|
|
|
|
|
session: Rc<RefCell<Option<Session>>>,
|
2020-11-17 14:35:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Bootstrap {
|
2021-09-20 13:47:08 +02:00
|
|
|
pub fn new(log: Logger, db: Databases, nw: Arc<Network>) -> Self {
|
|
|
|
info!(log, "Created Bootstrap");
|
|
|
|
let session = Rc::new(RefCell::new(None));
|
|
|
|
Self { session, db, nw, log }
|
2020-11-17 14:35:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
use connection_capnp::bootstrap::*;
|
|
|
|
impl connection_capnp::bootstrap::Server for Bootstrap {
|
2021-09-09 21:50:11 +02:00
|
|
|
fn authentication_system(&mut self,
|
|
|
|
_: AuthenticationSystemParams,
|
|
|
|
mut res: AuthenticationSystemResults
|
2020-11-17 14:35:16 +01:00
|
|
|
) -> Promise<(), capnp::Error> {
|
2020-12-09 18:44:52 +01:00
|
|
|
// TODO: Forbid mutltiple authentication for now
|
2020-11-17 14:35:16 +01:00
|
|
|
// TODO: When should we allow multiple auth and how do me make sure that does not leak
|
|
|
|
// priviledges (e.g. due to previously issues caps)?
|
2020-11-24 15:57:23 +01:00
|
|
|
|
2021-09-20 13:47:08 +02:00
|
|
|
// If this Rc has a strong count of 1 then there's no other cap issued yet meaning we can
|
|
|
|
// safely transform the inner session with an auth.
|
|
|
|
if Rc::strong_count(&self.session) == 1 {
|
|
|
|
let session = Rc::clone(&self.session);
|
|
|
|
let db = self.db.clone();
|
|
|
|
res.get().set_authentication_system(capnp_rpc::new_client(
|
|
|
|
auth::Auth::new(self.log.new(o!()), db, session))
|
|
|
|
);
|
|
|
|
}
|
2020-11-24 15:57:23 +01:00
|
|
|
|
|
|
|
Promise::ok(())
|
2020-11-17 14:35:16 +01:00
|
|
|
}
|
|
|
|
|
2021-09-09 21:50:11 +02:00
|
|
|
fn machine_system(&mut self,
|
|
|
|
_: MachineSystemParams,
|
|
|
|
mut res: MachineSystemResults
|
2020-11-17 14:35:16 +01:00
|
|
|
) -> Promise<(), capnp::Error> {
|
2021-09-20 13:47:08 +02:00
|
|
|
if let Some(session) = self.session.borrow().deref() {
|
|
|
|
debug!(self.log, "Giving MachineSystem cap to user {} with perms:", session.authzid);
|
|
|
|
for r in session.perms.iter() {
|
|
|
|
debug!(session.log, " {}", r);
|
2021-09-18 17:01:35 +02:00
|
|
|
}
|
|
|
|
|
2021-09-20 13:47:08 +02:00
|
|
|
// TODO actual permission check and stuff
|
|
|
|
// Right now we only check that the user has authenticated at all.
|
|
|
|
let c = capnp_rpc::new_client(Machines::new(Rc::clone(&self.session), self.nw.clone()));
|
|
|
|
res.get().set_machine_system(c);
|
|
|
|
}
|
2021-09-18 17:01:35 +02:00
|
|
|
|
2021-09-20 13:47:08 +02:00
|
|
|
Promise::ok(())
|
2020-11-17 14:35:16 +01:00
|
|
|
}
|
|
|
|
|
2021-09-19 19:47:29 +02:00
|
|
|
fn user_system(
|
|
|
|
&mut self,
|
|
|
|
_: UserSystemParams,
|
|
|
|
mut results: UserSystemResults
|
|
|
|
) -> Promise<(), capnp::Error> {
|
2021-09-20 13:47:08 +02:00
|
|
|
if self.session.borrow().is_some() {
|
|
|
|
// TODO actual permission check and stuff
|
|
|
|
// Right now we only check that the user has authenticated at all.
|
|
|
|
let c = capnp_rpc::new_client(Users::new(Rc::clone(&self.session), self.db.userdb.clone()));
|
|
|
|
results.get().set_user_system(c);
|
|
|
|
}
|
2021-09-19 19:47:29 +02:00
|
|
|
|
2021-09-20 13:47:08 +02:00
|
|
|
Promise::ok(())
|
2021-09-19 19:47:29 +02:00
|
|
|
}
|
|
|
|
}
|