2022-05-05 15:50:44 +02:00
|
|
|
use api::usersystem_capnp::user_system::{info, manage, search};
|
2022-03-16 20:17:59 +01:00
|
|
|
use capnp::capability::Promise;
|
2022-03-21 00:01:50 +01:00
|
|
|
use capnp_rpc::pry;
|
2022-06-24 13:57:47 +02:00
|
|
|
use tracing::Span;
|
2022-04-26 23:21:43 +02:00
|
|
|
|
2022-03-16 20:17:59 +01:00
|
|
|
use crate::capnp::user::User;
|
2022-03-15 20:00:43 +01:00
|
|
|
|
2022-03-12 17:31:53 +01:00
|
|
|
use crate::session::SessionHandle;
|
2022-04-28 20:33:46 +02:00
|
|
|
use crate::users::{db, UserRef};
|
2022-04-26 23:21:43 +02:00
|
|
|
|
2022-06-24 13:57:47 +02:00
|
|
|
const TARGET: &str = "bffh::api::usersystem";
|
|
|
|
|
2022-03-15 19:14:04 +01:00
|
|
|
#[derive(Clone)]
|
2022-03-11 22:13:54 +01:00
|
|
|
pub struct Users {
|
2022-06-24 13:57:47 +02:00
|
|
|
span: Span,
|
2022-03-12 17:31:53 +01:00
|
|
|
session: SessionHandle,
|
2022-03-11 22:13:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Users {
|
2022-03-12 17:31:53 +01:00
|
|
|
pub fn new(session: SessionHandle) -> Self {
|
2022-06-24 13:57:47 +02:00
|
|
|
let span = tracing::info_span!(target: TARGET, "UserSystem",);
|
|
|
|
Self { span, session }
|
2022-03-11 22:13:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-16 20:17:59 +01:00
|
|
|
impl info::Server for Users {
|
|
|
|
fn get_user_self(
|
|
|
|
&mut self,
|
|
|
|
_: info::GetUserSelfParams,
|
|
|
|
mut result: info::GetUserSelfResults,
|
|
|
|
) -> Promise<(), ::capnp::Error> {
|
2022-06-24 13:57:47 +02:00
|
|
|
let _guard = self.span.enter();
|
|
|
|
let _span = tracing::trace_span!(target: TARGET, "getUserSelf").entered();
|
|
|
|
tracing::trace!("method call");
|
|
|
|
|
2022-04-21 23:02:58 +02:00
|
|
|
let builder = result.get();
|
2022-03-16 20:17:59 +01:00
|
|
|
User::build(self.session.clone(), builder);
|
2022-06-24 13:57:47 +02:00
|
|
|
|
|
|
|
tracing::trace!("method return");
|
2022-03-16 20:17:59 +01:00
|
|
|
Promise::ok(())
|
|
|
|
}
|
2022-03-11 22:13:54 +01:00
|
|
|
}
|
|
|
|
|
2022-03-16 20:17:59 +01:00
|
|
|
impl manage::Server for Users {
|
|
|
|
fn get_user_list(
|
|
|
|
&mut self,
|
|
|
|
_: manage::GetUserListParams,
|
2022-03-21 00:01:50 +01:00
|
|
|
mut result: manage::GetUserListResults,
|
2022-03-16 20:17:59 +01:00
|
|
|
) -> Promise<(), ::capnp::Error> {
|
2022-06-24 13:57:47 +02:00
|
|
|
let _guard = self.span.enter();
|
|
|
|
let _span = tracing::trace_span!(target: TARGET, "getUserList",).entered();
|
|
|
|
tracing::trace!("method call");
|
|
|
|
|
2022-03-21 00:01:50 +01:00
|
|
|
let userdb = self.session.users.into_inner();
|
2022-05-05 15:50:44 +02:00
|
|
|
let users = pry!(userdb
|
|
|
|
.get_all()
|
2022-03-21 00:01:50 +01:00
|
|
|
.map_err(|e| capnp::Error::failed(format!("UserDB error: {:?}", e))));
|
|
|
|
let mut builder = result.get().init_user_list(users.len() as u32);
|
|
|
|
for (i, (_, user)) in users.into_iter().enumerate() {
|
2022-04-27 20:19:04 +02:00
|
|
|
User::fill(&self.session, user, builder.reborrow().get(i as u32));
|
2022-03-21 00:01:50 +01:00
|
|
|
}
|
2022-06-24 13:57:47 +02:00
|
|
|
|
|
|
|
tracing::trace!("method return");
|
2022-03-21 00:01:50 +01:00
|
|
|
Promise::ok(())
|
2022-03-16 20:17:59 +01:00
|
|
|
}
|
2022-06-24 13:57:47 +02:00
|
|
|
|
2022-04-28 20:38:44 +02:00
|
|
|
fn add_user_fallible(
|
2022-03-16 20:17:59 +01:00
|
|
|
&mut self,
|
2022-04-28 20:38:44 +02:00
|
|
|
params: manage::AddUserFallibleParams,
|
|
|
|
mut result: manage::AddUserFallibleResults,
|
2022-03-16 20:17:59 +01:00
|
|
|
) -> Promise<(), ::capnp::Error> {
|
2022-06-24 13:57:47 +02:00
|
|
|
let _guard = self.span.enter();
|
|
|
|
let _span = tracing::trace_span!(target: TARGET, "addUserFallible").entered();
|
|
|
|
|
2022-04-27 20:19:04 +02:00
|
|
|
let params = pry!(params.get());
|
|
|
|
let username = pry!(params.get_username());
|
|
|
|
let password = pry!(params.get_password());
|
|
|
|
// FIXME: saslprep passwords & usernames before storing them
|
|
|
|
|
2022-06-24 13:57:47 +02:00
|
|
|
tracing::trace!(
|
|
|
|
params.username = username,
|
|
|
|
params.password = "<redacted>",
|
|
|
|
"method call"
|
|
|
|
);
|
|
|
|
|
2022-04-28 20:38:44 +02:00
|
|
|
let mut builder = result.get();
|
|
|
|
|
2022-04-27 20:19:04 +02:00
|
|
|
if !username.is_empty() && !password.is_empty() {
|
|
|
|
if self.session.users.get_user(username).is_none() {
|
|
|
|
let user = db::User::new_with_plain_pw(username, password);
|
|
|
|
self.session.users.put_user(username, &user);
|
2022-04-28 20:38:44 +02:00
|
|
|
let mut builder = builder.init_successful();
|
2022-04-27 20:19:04 +02:00
|
|
|
User::fill(&self.session, user, builder);
|
|
|
|
} else {
|
2022-04-28 20:38:44 +02:00
|
|
|
let mut builder = builder.init_failed();
|
|
|
|
builder.set_error(manage::add_user_error::AddUserError::AlreadyExists);
|
2022-04-27 20:19:04 +02:00
|
|
|
tracing::warn!("Failed to add user: Username taken");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if username.is_empty() {
|
2022-04-28 20:38:44 +02:00
|
|
|
let mut builder = builder.init_failed();
|
|
|
|
builder.set_error(manage::add_user_error::AddUserError::UsernameInvalid);
|
2022-04-27 20:19:04 +02:00
|
|
|
tracing::warn!("Failed to add user: Username empty");
|
|
|
|
} else if password.is_empty() {
|
2022-04-28 20:38:44 +02:00
|
|
|
let mut builder = builder.init_failed();
|
|
|
|
builder.set_error(manage::add_user_error::AddUserError::PasswordInvalid);
|
2022-04-27 20:19:04 +02:00
|
|
|
tracing::warn!("Failed to add user: Password empty");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-24 13:57:47 +02:00
|
|
|
tracing::trace!("method return");
|
2022-04-27 20:19:04 +02:00
|
|
|
Promise::ok(())
|
2022-03-16 20:17:59 +01:00
|
|
|
}
|
2022-06-24 13:57:47 +02:00
|
|
|
|
2022-03-16 20:17:59 +01:00
|
|
|
fn remove_user(
|
|
|
|
&mut self,
|
2022-04-27 20:19:04 +02:00
|
|
|
params: manage::RemoveUserParams,
|
2022-03-16 20:17:59 +01:00
|
|
|
_: manage::RemoveUserResults,
|
|
|
|
) -> Promise<(), ::capnp::Error> {
|
2022-06-24 13:57:47 +02:00
|
|
|
let _guard = self.span.enter();
|
|
|
|
let _span = tracing::trace_span!(target: TARGET, "removeUser",).entered();
|
|
|
|
|
2022-04-27 20:27:14 +02:00
|
|
|
let who: &str = pry!(pry!(pry!(params.get()).get_user()).get_username());
|
2022-04-27 20:19:04 +02:00
|
|
|
|
2022-06-24 13:57:47 +02:00
|
|
|
tracing::trace!(params.user = who, "method call");
|
|
|
|
|
2022-04-27 20:19:04 +02:00
|
|
|
if let Err(e) = self.session.users.del_user(who) {
|
|
|
|
tracing::warn!("Failed to delete user: {:?}", e);
|
|
|
|
} else {
|
|
|
|
tracing::info!("Deleted user {}", who);
|
|
|
|
}
|
|
|
|
|
2022-06-24 13:57:47 +02:00
|
|
|
tracing::trace!("method return");
|
2022-04-27 20:19:04 +02:00
|
|
|
Promise::ok(())
|
2022-03-16 20:17:59 +01:00
|
|
|
}
|
|
|
|
}
|
2022-04-28 20:33:46 +02:00
|
|
|
|
|
|
|
impl search::Server for Users {
|
|
|
|
fn get_user_by_name(
|
|
|
|
&mut self,
|
|
|
|
params: search::GetUserByNameParams,
|
|
|
|
mut result: search::GetUserByNameResults,
|
|
|
|
) -> Promise<(), ::capnp::Error> {
|
2022-06-24 13:57:47 +02:00
|
|
|
let _guard = self.span.enter();
|
|
|
|
let _span = tracing::trace_span!(target: TARGET, "getUserByName",).entered();
|
|
|
|
|
2022-04-28 20:33:46 +02:00
|
|
|
let username: &str = pry!(pry!(params.get()).get_username());
|
2022-06-24 13:57:47 +02:00
|
|
|
|
|
|
|
tracing::trace!(params.username = username, "method call");
|
|
|
|
|
2022-04-28 20:33:46 +02:00
|
|
|
let userref = UserRef::new(username.to_string());
|
|
|
|
User::build_optional(&self.session, Some(userref), result.get());
|
2022-06-24 13:57:47 +02:00
|
|
|
|
|
|
|
tracing::trace!("method return");
|
2022-04-28 20:33:46 +02:00
|
|
|
Promise::ok(())
|
|
|
|
}
|
2022-05-05 15:50:44 +02:00
|
|
|
}
|