Implement more API to make Borepin happier

This commit is contained in:
Nadja Reitzenstein 2022-03-16 20:17:59 +01:00
parent b88c6f69cd
commit 33e8a62d2a
5 changed files with 187 additions and 37 deletions

View File

@ -10,6 +10,7 @@ use api::machine_capnp::machine::{
}; };
use capnp::capability::Promise; use capnp::capability::Promise;
use capnp_rpc::pry; use capnp_rpc::pry;
use crate::capnp::user::User;
#[derive(Clone)] #[derive(Clone)]
pub struct Machine { pub struct Machine {
@ -196,11 +197,13 @@ impl ManageServer for Machine {
fn get_machine_info_extended( fn get_machine_info_extended(
&mut self, &mut self,
_: manage::GetMachineInfoExtendedParams, _: manage::GetMachineInfoExtendedParams,
_: manage::GetMachineInfoExtendedResults, mut result: manage::GetMachineInfoExtendedResults,
) -> Promise<(), ::capnp::Error> { ) -> Promise<(), ::capnp::Error> {
Promise::err(::capnp::Error::unimplemented( let mut builder = result.get();
"method not implemented".to_string(), let user = User::new(self.session.clone());
)) user.build_else(self.resource.get_current_user(), builder.reborrow().init_current_user());
user.build_else(self.resource.get_previous_user(), builder.init_last_user());
Promise::ok(())
} }
fn set_property( fn set_property(
&mut self, &mut self,

View File

@ -1,29 +1,92 @@
use api::user_capnp::user::{
info,
manage,
admin,
};
use crate::session::SessionHandle; use crate::session::SessionHandle;
use api::user_capnp::user::{admin, info, manage, Builder};
use crate::users::UserRef;
struct User { pub struct User {
session: SessionHandle, session: SessionHandle,
} }
impl info::Server for User { impl User {
pub fn new(session: SessionHandle) -> Self {
Self { session }
}
fn list_roles(&mut self, _: info::ListRolesParams<>, _: info::ListRolesResults<>) -> ::capnp::capability::Promise<(), ::capnp::Error> { ::capnp::capability::Promise::err(::capnp::Error::unimplemented("method not implemented".to_string())) } pub fn build_else(&self, user: Option<UserRef>, mut builder: Builder) {
if let Some(user) = user {
builder.set_username(user.get_username());
}
}
pub fn build_into(self, mut builder: Builder) {
let user = self.session.get_user();
builder.set_username(user.get_username());
}
pub fn build(session: SessionHandle, mut builder: Builder) {
let this = Self::new(session);
this.build_into(builder)
}
}
impl info::Server for User {
fn list_roles(
&mut self,
_: info::ListRolesParams,
_: info::ListRolesResults,
) -> ::capnp::capability::Promise<(), ::capnp::Error> {
::capnp::capability::Promise::err(::capnp::Error::unimplemented(
"method not implemented".to_string(),
))
}
} }
impl manage::Server for User { impl manage::Server for User {
fn pwd(
fn pwd(&mut self, _: manage::PwdParams<>, _: manage::PwdResults<>) -> ::capnp::capability::Promise<(), ::capnp::Error> { ::capnp::capability::Promise::err(::capnp::Error::unimplemented("method not implemented".to_string())) } &mut self,
_: manage::PwdParams,
_: manage::PwdResults,
) -> ::capnp::capability::Promise<(), ::capnp::Error> {
::capnp::capability::Promise::err(::capnp::Error::unimplemented(
"method not implemented".to_string(),
))
}
} }
impl admin::Server for User { impl admin::Server for User {
fn get_user_info_extended(
fn get_user_info_extended(&mut self, _: admin::GetUserInfoExtendedParams<>, _: admin::GetUserInfoExtendedResults<>) -> ::capnp::capability::Promise<(), ::capnp::Error> { ::capnp::capability::Promise::err(::capnp::Error::unimplemented("method not implemented".to_string())) } &mut self,
fn add_role(&mut self, _: admin::AddRoleParams<>, _: admin::AddRoleResults<>) -> ::capnp::capability::Promise<(), ::capnp::Error> { ::capnp::capability::Promise::err(::capnp::Error::unimplemented("method not implemented".to_string())) } _: admin::GetUserInfoExtendedParams,
fn remove_role(&mut self, _: admin::RemoveRoleParams<>, _: admin::RemoveRoleResults<>) -> ::capnp::capability::Promise<(), ::capnp::Error> { ::capnp::capability::Promise::err(::capnp::Error::unimplemented("method not implemented".to_string())) } _: admin::GetUserInfoExtendedResults,
fn pwd(&mut self, _: admin::PwdParams<>, _: admin::PwdResults<>) -> ::capnp::capability::Promise<(), ::capnp::Error> { ::capnp::capability::Promise::err(::capnp::Error::unimplemented("method not implemented".to_string())) } ) -> ::capnp::capability::Promise<(), ::capnp::Error> {
} ::capnp::capability::Promise::err(::capnp::Error::unimplemented(
"method not implemented".to_string(),
))
}
fn add_role(
&mut self,
_: admin::AddRoleParams,
_: admin::AddRoleResults,
) -> ::capnp::capability::Promise<(), ::capnp::Error> {
::capnp::capability::Promise::err(::capnp::Error::unimplemented(
"method not implemented".to_string(),
))
}
fn remove_role(
&mut self,
_: admin::RemoveRoleParams,
_: admin::RemoveRoleResults,
) -> ::capnp::capability::Promise<(), ::capnp::Error> {
::capnp::capability::Promise::err(::capnp::Error::unimplemented(
"method not implemented".to_string(),
))
}
fn pwd(
&mut self,
_: admin::PwdParams,
_: admin::PwdResults,
) -> ::capnp::capability::Promise<(), ::capnp::Error> {
::capnp::capability::Promise::err(::capnp::Error::unimplemented(
"method not implemented".to_string(),
))
}
}

View File

@ -1,10 +1,10 @@
use capnp::capability::Promise;
use api::usersystem_capnp::user_system::{ use api::usersystem_capnp::user_system::{
Server as UserSystem, info::Server as InfoServer, manage::Server as ManageServer, info, manage, Server as UserSystem,
self as system,
}; };
use crate::authorization::permissions::Permission;
use crate::capnp::user::User;
use crate::session::SessionHandle; use crate::session::SessionHandle;
@ -15,20 +15,69 @@ pub struct Users {
impl Users { impl Users {
pub fn new(session: SessionHandle) -> Self { pub fn new(session: SessionHandle) -> Self {
Self { Self { session }
session,
}
} }
} }
impl UserSystem for Users { impl system::Server for Users {
fn info(
&mut self,
_: system::InfoParams,
mut result: system::InfoResults,
) -> Promise<(), ::capnp::Error> {
result.get().set_info(capnp_rpc::new_client(self.clone()));
Promise::ok(())
}
fn manage(
&mut self,
_: system::ManageParams,
mut result: system::ManageResults,
) -> Promise<(), ::capnp::Error> {
if self.session.has_perm(Permission::new("bffh.users.manage")) {
result.get().set_manage(capnp_rpc::new_client(self.clone()));
}
Promise::ok(())
}
} }
impl InfoServer for Users { impl info::Server for Users {
fn get_user_self(
&mut self,
_: info::GetUserSelfParams,
mut result: info::GetUserSelfResults,
) -> Promise<(), ::capnp::Error> {
let builder = result.get().init_user();
User::build(self.session.clone(), builder);
Promise::ok(())
}
} }
impl ManageServer for Users { impl manage::Server for Users {
fn get_user_list(
} &mut self,
_: manage::GetUserListParams,
_: manage::GetUserListResults,
) -> Promise<(), ::capnp::Error> {
Promise::err(::capnp::Error::unimplemented(
"method not implemented".to_string(),
))
}
fn add_user(
&mut self,
_: manage::AddUserParams,
_: manage::AddUserResults,
) -> Promise<(), ::capnp::Error> {
Promise::err(::capnp::Error::unimplemented(
"method not implemented".to_string(),
))
}
fn remove_user(
&mut self,
_: manage::RemoveUserParams,
_: manage::RemoveUserResults,
) -> Promise<(), ::capnp::Error> {
Promise::err(::capnp::Error::unimplemented(
"method not implemented".to_string(),
))
}
}

View File

@ -1,9 +1,10 @@
use std::convert::Infallible; use rkyv::Infallible;
use std::ops::Deref; use std::ops::Deref;
use std::sync::Arc; use std::sync::Arc;
use futures_signals::signal::{Mutable, Signal, SignalExt}; use futures_signals::signal::{Mutable, Signal, SignalExt};
use lmdb::RoTransaction; use lmdb::RoTransaction;
use rkyv::{Archived, Deserialize}; use rkyv::{Archived, Deserialize};
use rkyv::option::ArchivedOption;
use rkyv::ser::Serializer; use rkyv::ser::Serializer;
use rkyv::ser::serializers::AllocSerializer; use rkyv::ser::serializers::AllocSerializer;
use crate::authorization::permissions::PrivilegesBuf; use crate::authorization::permissions::PrivilegesBuf;
@ -117,6 +118,32 @@ impl Resource {
&self.inner.desc &self.inner.desc
} }
pub fn get_current_user(&self) -> Option<UserRef> {
let state = self.get_state_ref();
let state: &Archived<State> = state.as_ref();
match &state.inner.state {
ArchivedStatus::Blocked(user) |
ArchivedStatus::InUse(user) |
ArchivedStatus::Reserved(user) |
ArchivedStatus::ToCheck(user) => {
let user = Deserialize::<UserRef, _>::deserialize(user, &mut Infallible).unwrap();
Some(user)
},
_ => None,
}
}
pub fn get_previous_user(&self) -> Option<UserRef> {
let state = self.get_state_ref();
let state: &Archived<State> = state.as_ref();
if let ArchivedOption::Some(user) = &state.inner.previous {
let user = Deserialize::<UserRef, _>::deserialize(user, &mut Infallible).unwrap();
Some(user)
} else {
None
}
}
fn set_state(&self, state: MachineState) { fn set_state(&self, state: MachineState) {
let mut serializer = AllocSerializer::<1024>::default(); let mut serializer = AllocSerializer::<1024>::default();
serializer.serialize_value(&state); serializer.serialize_value(&state);

View File

@ -3,6 +3,7 @@
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;
use crate::authorization::permissions::Permission;
use crate::authorization::roles::{Roles}; use crate::authorization::roles::{Roles};
use crate::resources::Resource; use crate::resources::Resource;
use crate::Users; use crate::Users;
@ -78,4 +79,11 @@ impl SessionHandle {
false false
} }
} }
pub fn has_perm(&self, perm: impl AsRef<Permission>) -> bool {
if let Some(user) = self.users.get_user(self.user.get_username()) {
self.roles.is_permitted(&user.userdata, perm)
} else {
false
}
}
} }