use api::usersystem_capnp::user_system::{info, manage, search}; use capnp::capability::Promise; use capnp_rpc::pry; use crate::capnp::user::User; use crate::session::SessionHandle; use crate::users::{db, UserRef}; #[derive(Clone)] pub struct Users { session: SessionHandle, } impl Users { pub fn new(session: SessionHandle) -> Self { Self { session } } } impl info::Server for Users { fn get_user_self( &mut self, _: info::GetUserSelfParams, mut result: info::GetUserSelfResults, ) -> Promise<(), ::capnp::Error> { let builder = result.get(); User::build(self.session.clone(), builder); Promise::ok(()) } } impl manage::Server for Users { fn get_user_list( &mut self, _: manage::GetUserListParams, mut result: manage::GetUserListResults, ) -> Promise<(), ::capnp::Error> { let userdb = self.session.users.into_inner(); let users = pry!(userdb .get_all() .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() { User::fill(&self.session, user, builder.reborrow().get(i as u32)); } Promise::ok(()) } fn add_user_fallible( &mut self, params: manage::AddUserFallibleParams, mut result: manage::AddUserFallibleResults, ) -> Promise<(), ::capnp::Error> { let params = pry!(params.get()); let username = pry!(params.get_username()); let password = pry!(params.get_password()); // FIXME: saslprep passwords & usernames before storing them let mut builder = result.get(); 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); let mut builder = builder.init_successful(); User::fill(&self.session, user, builder); } else { let mut builder = builder.init_failed(); builder.set_error(manage::add_user_error::AddUserError::AlreadyExists); tracing::warn!("Failed to add user: Username taken"); } } else { if username.is_empty() { let mut builder = builder.init_failed(); builder.set_error(manage::add_user_error::AddUserError::UsernameInvalid); tracing::warn!("Failed to add user: Username empty"); } else if password.is_empty() { let mut builder = builder.init_failed(); builder.set_error(manage::add_user_error::AddUserError::PasswordInvalid); tracing::warn!("Failed to add user: Password empty"); } } Promise::ok(()) } fn remove_user( &mut self, params: manage::RemoveUserParams, _: manage::RemoveUserResults, ) -> Promise<(), ::capnp::Error> { let who: &str = pry!(pry!(pry!(params.get()).get_user()).get_username()); if let Err(e) = self.session.users.del_user(who) { tracing::warn!("Failed to delete user: {:?}", e); } else { tracing::info!("Deleted user {}", who); } Promise::ok(()) } } impl search::Server for Users { fn get_user_by_name( &mut self, params: search::GetUserByNameParams, mut result: search::GetUserByNameResults, ) -> Promise<(), ::capnp::Error> { let username: &str = pry!(pry!(params.get()).get_username()); let userref = UserRef::new(username.to_string()); User::build_optional(&self.session, Some(userref), result.get()); Promise::ok(()) } }