2022-03-21 00:01:50 +01:00
|
|
|
use capnp::capability::Promise;
|
|
|
|
use capnp_rpc::pry;
|
2022-03-12 17:31:53 +01:00
|
|
|
use crate::session::SessionHandle;
|
2022-04-22 20:09:34 +02:00
|
|
|
use api::user_capnp::user::{admin, info, manage, self};
|
|
|
|
use api::general_capnp::optional;
|
2022-03-21 00:01:50 +01:00
|
|
|
use crate::authorization::permissions::Permission;
|
|
|
|
use crate::users::{db, UserRef};
|
2022-03-11 22:13:54 +01:00
|
|
|
|
2022-03-21 00:01:50 +01:00
|
|
|
#[derive(Clone)]
|
2022-03-16 20:17:59 +01:00
|
|
|
pub struct User {
|
2022-03-12 17:31:53 +01:00
|
|
|
session: SessionHandle,
|
2022-03-21 00:01:50 +01:00
|
|
|
user: UserRef,
|
2022-03-12 17:31:53 +01:00
|
|
|
}
|
2022-03-11 22:13:54 +01:00
|
|
|
|
2022-03-16 20:17:59 +01:00
|
|
|
impl User {
|
2022-03-21 00:01:50 +01:00
|
|
|
pub fn new(session: SessionHandle, user: UserRef) -> Self {
|
|
|
|
Self { session, user }
|
2022-03-16 20:17:59 +01:00
|
|
|
}
|
|
|
|
|
2022-03-21 00:01:50 +01:00
|
|
|
pub fn new_self(session: SessionHandle) -> Self {
|
|
|
|
let user = session.get_user_ref();
|
|
|
|
Self::new(session, user)
|
2022-03-16 20:17:59 +01:00
|
|
|
}
|
2022-03-11 22:13:54 +01:00
|
|
|
|
2022-04-22 20:09:34 +02:00
|
|
|
pub fn build_optional(&self, user: Option<UserRef>, builder: optional::Builder<user::Owned>) {
|
2022-03-21 00:01:50 +01:00
|
|
|
if let Some(user) = user.and_then(|u| self.session.users.get_user(u.get_username())) {
|
2022-04-26 23:21:43 +02:00
|
|
|
let builder = builder.init_just();
|
2022-04-27 20:19:04 +02:00
|
|
|
Self::fill(&self.session, user, builder);
|
2022-03-21 00:01:50 +01:00
|
|
|
}
|
2022-03-16 20:17:59 +01:00
|
|
|
}
|
|
|
|
|
2022-04-26 23:21:43 +02:00
|
|
|
pub fn build(session: SessionHandle, builder: user::Builder) {
|
2022-03-21 00:01:50 +01:00
|
|
|
let this = Self::new_self(session);
|
|
|
|
let user = this.session.get_user();
|
2022-04-27 20:19:04 +02:00
|
|
|
Self::fill(&this.session, user, builder);
|
2022-03-21 00:01:50 +01:00
|
|
|
}
|
|
|
|
|
2022-04-27 20:19:04 +02:00
|
|
|
pub fn fill(session: &SessionHandle, user: db::User, mut builder: user::Builder) {
|
2022-03-21 00:01:50 +01:00
|
|
|
builder.set_username(user.id.as_str());
|
|
|
|
|
|
|
|
// We have permissions on ourself
|
2022-04-27 20:19:04 +02:00
|
|
|
let is_me = &session.get_user_ref().id == &user.id;
|
|
|
|
|
|
|
|
let client = Self::new(session.clone(), UserRef::new(user.id));
|
2022-03-21 00:01:50 +01:00
|
|
|
|
2022-04-27 20:19:04 +02:00
|
|
|
if is_me || session.has_perm(Permission::new("bffh.users.info")) {
|
2022-03-21 00:01:50 +01:00
|
|
|
builder.set_info(capnp_rpc::new_client(client.clone()));
|
|
|
|
}
|
|
|
|
if is_me {
|
|
|
|
builder.set_manage(capnp_rpc::new_client(client.clone()));
|
|
|
|
}
|
2022-04-27 20:19:04 +02:00
|
|
|
if session.has_perm(Permission::new("bffh.users.admin")) {
|
2022-03-21 00:01:50 +01:00
|
|
|
builder.set_admin(capnp_rpc::new_client(client.clone()));
|
|
|
|
}
|
2022-03-16 20:17:59 +01:00
|
|
|
}
|
2022-03-11 22:13:54 +01:00
|
|
|
}
|
|
|
|
|
2022-03-16 20:17:59 +01:00
|
|
|
impl info::Server for User {
|
|
|
|
fn list_roles(
|
|
|
|
&mut self,
|
|
|
|
_: info::ListRolesParams,
|
2022-03-21 00:01:50 +01:00
|
|
|
mut result: info::ListRolesResults,
|
|
|
|
) -> Promise<(), ::capnp::Error> {
|
2022-04-27 20:19:04 +02:00
|
|
|
if let Some(user) = self.session.users.get_user(self.user.get_username()) {
|
|
|
|
let mut builder = result.get().init_roles(user.userdata.roles.len() as u32);
|
|
|
|
for (i, role) in user.userdata.roles.into_iter().enumerate() {
|
|
|
|
let mut b = builder.reborrow().get(i as u32);
|
|
|
|
b.set_name(role.as_str());
|
|
|
|
}
|
2022-03-21 00:01:50 +01:00
|
|
|
}
|
|
|
|
Promise::ok(())
|
2022-03-16 20:17:59 +01:00
|
|
|
}
|
|
|
|
}
|
2022-03-11 22:13:54 +01:00
|
|
|
|
2022-03-16 20:17:59 +01:00
|
|
|
impl manage::Server for User {
|
|
|
|
fn pwd(
|
|
|
|
&mut self,
|
2022-04-26 23:21:43 +02:00
|
|
|
_params: manage::PwdParams,
|
|
|
|
_results: manage::PwdResults,
|
2022-03-21 00:01:50 +01:00
|
|
|
) -> Promise<(), ::capnp::Error> {
|
|
|
|
Promise::err(::capnp::Error::unimplemented(
|
2022-03-16 20:17:59 +01:00
|
|
|
"method not implemented".to_string(),
|
|
|
|
))
|
|
|
|
}
|
2022-03-11 22:13:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl admin::Server for User {
|
2022-03-16 20:17:59 +01:00
|
|
|
fn get_user_info_extended(
|
|
|
|
&mut self,
|
|
|
|
_: admin::GetUserInfoExtendedParams,
|
|
|
|
_: admin::GetUserInfoExtendedResults,
|
2022-03-21 00:01:50 +01:00
|
|
|
) -> Promise<(), ::capnp::Error> {
|
|
|
|
Promise::err(::capnp::Error::unimplemented(
|
2022-03-16 20:17:59 +01:00
|
|
|
"method not implemented".to_string(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
fn add_role(
|
|
|
|
&mut self,
|
2022-03-21 00:01:50 +01:00
|
|
|
param: admin::AddRoleParams,
|
2022-03-16 20:17:59 +01:00
|
|
|
_: admin::AddRoleResults,
|
2022-03-21 00:01:50 +01:00
|
|
|
) -> Promise<(), ::capnp::Error> {
|
|
|
|
let rolename = pry!(pry!(pry!(param.get()).get_role()).get_name());
|
|
|
|
|
|
|
|
if let Some(_role) = self.session.roles.get(rolename) {
|
|
|
|
let mut target = self.session.users.get_user(self.user.get_username()).unwrap();
|
|
|
|
|
|
|
|
// Only update if needed
|
|
|
|
if !target.userdata.roles.iter().any(|r| r.as_str() == rolename) {
|
|
|
|
target.userdata.roles.push(rolename.to_string());
|
|
|
|
self.session.users.put_user(self.user.get_username(), &target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Promise::ok(())
|
2022-03-16 20:17:59 +01:00
|
|
|
}
|
|
|
|
fn remove_role(
|
|
|
|
&mut self,
|
2022-03-21 00:01:50 +01:00
|
|
|
param: admin::RemoveRoleParams,
|
2022-03-16 20:17:59 +01:00
|
|
|
_: admin::RemoveRoleResults,
|
2022-03-21 00:01:50 +01:00
|
|
|
) -> Promise<(), ::capnp::Error> {
|
|
|
|
let rolename = pry!(pry!(pry!(param.get()).get_role()).get_name());
|
|
|
|
|
|
|
|
if let Some(_role) = self.session.roles.get(rolename) {
|
|
|
|
let mut target = self.session.users.get_user(self.user.get_username()).unwrap();
|
|
|
|
|
|
|
|
// Only update if needed
|
|
|
|
if target.userdata.roles.iter().any(|r| r.as_str() == rolename) {
|
|
|
|
target.userdata.roles.retain(|r| r.as_str() != rolename);
|
|
|
|
self.session.users.put_user(self.user.get_username(), &target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Promise::ok(())
|
2022-03-16 20:17:59 +01:00
|
|
|
}
|
|
|
|
fn pwd(
|
|
|
|
&mut self,
|
|
|
|
_: admin::PwdParams,
|
|
|
|
_: admin::PwdResults,
|
2022-03-21 00:01:50 +01:00
|
|
|
) -> Promise<(), ::capnp::Error> {
|
|
|
|
Promise::err(::capnp::Error::unimplemented(
|
2022-03-16 20:17:59 +01:00
|
|
|
"method not implemented".to_string(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|