mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-23 15:17:57 +01:00
Implement new traits structure
This commit is contained in:
parent
5400d7f799
commit
2acf35d54d
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -489,6 +489,15 @@ version = "0.21.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||
|
||||
[[package]]
|
||||
name = "bffh-impl"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitfield"
|
||||
version = "0.13.2"
|
||||
@ -1052,6 +1061,7 @@ dependencies = [
|
||||
"async-process",
|
||||
"async-trait",
|
||||
"backtrace",
|
||||
"bffh-impl",
|
||||
"capnp",
|
||||
"capnp-rpc",
|
||||
"chrono",
|
||||
|
@ -44,6 +44,9 @@ miette = { version = "4.7.1", features = ["fancy"] }
|
||||
thiserror = "1.0.31"
|
||||
toml = "0.5.8"
|
||||
|
||||
# Compilation proc-macros
|
||||
bffh-impl = { path = "modules/impl" }
|
||||
|
||||
# Well-known paths/dirs for e.g. cache
|
||||
dirs = "4.0.0"
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit cae56b00842362bd4599187b171ddf8a1030e248
|
||||
Subproject commit 879bc578b20433c527cea34a5821cdccec9ee587
|
@ -30,6 +30,7 @@ mod resources;
|
||||
mod permissionsystem;
|
||||
mod user;
|
||||
mod user_system;
|
||||
mod traits;
|
||||
|
||||
pub struct APIServer {
|
||||
executor: Executor<'static>,
|
||||
|
@ -3,9 +3,16 @@ use crate::resources::modules::fabaccess::{ArchivedStatus, Status};
|
||||
use crate::resources::Resource;
|
||||
use crate::session::SessionHandle;
|
||||
use api::resource_capnp::resource;
|
||||
use api::claim_capnp::claimable;
|
||||
use api::claim_capnp::{claimable, claim};
|
||||
use api::notify_capnp::notifiable;
|
||||
use api::owned_capnp::owned;
|
||||
use api::projects_capnp::project;
|
||||
use capnp::capability::Promise;
|
||||
use capnp::Error;
|
||||
use capnp_rpc::pry;
|
||||
use api::claim_capnp::claim::{DisownParams, DisownResults, TraitsParams, TraitsResults};
|
||||
use api::claim_capnp::claimable::{ClaimParams, ClaimResults};
|
||||
use api::owned_capnp::owned::{GetUserParams, GetUserResults};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Machine {
|
||||
@ -26,5 +33,38 @@ impl Machine {
|
||||
|
||||
|
||||
impl claimable::Server for Machine {
|
||||
fn claim(&mut self, params: ClaimParams, mut results: ClaimResults) -> Promise<(), Error> {
|
||||
let project = params.get().and_then(|r| r.get_project()).ok();
|
||||
//self.resource.try_claim();
|
||||
let claim = Claim::new(self.session.clone(), project, self.resource.clone());
|
||||
pry!(results.get().set_ok(capnp_rpc::new_client(claim)));
|
||||
Promise::ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Claim {
|
||||
session: SessionHandle,
|
||||
project: Option<project::Client>,
|
||||
resource: Resource,
|
||||
}
|
||||
impl Claim {
|
||||
fn new(session: SessionHandle, project: Option<project::Client>, resource: Resource) -> Self {
|
||||
Self { session, project, resource }
|
||||
}
|
||||
}
|
||||
|
||||
impl notifiable::Server for Claim {}
|
||||
|
||||
impl owned::Server for Claim {
|
||||
fn get_user(&mut self, _: GetUserParams, mut results: GetUserResults) -> Promise<(), Error> {
|
||||
let owner = User::new_self(self.session.clone());
|
||||
results.get().set_owner(capnp_rpc::new_client(owner));
|
||||
Promise::ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl claim::Server for Claim {
|
||||
fn traits(&mut self, _: TraitsParams, _: TraitsResults) -> Promise<(), Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
7
bffhd/capnp/traits/claimable.rs
Normal file
7
bffhd/capnp/traits/claimable.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::oid;
|
||||
use crate::utils::oid::ObjectIdentifier;
|
||||
use api::traits::claimable_capnp::trait_claimable;
|
||||
|
||||
pub const CLAIMABLE_TRAIT_ID: ObjectIdentifier = oid!(1.3.6.1.4.1.61783.612.1.0);
|
||||
|
||||
|
2
bffhd/capnp/traits/mod.rs
Normal file
2
bffhd/capnp/traits/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
mod claimable;
|
||||
mod powerable;
|
4
bffhd/capnp/traits/powerable.rs
Normal file
4
bffhd/capnp/traits/powerable.rs
Normal file
@ -0,0 +1,4 @@
|
||||
use crate::oid;
|
||||
use crate::utils::oid::ObjectIdentifier;
|
||||
|
||||
pub const TRAIT_ID_POWERABLE: ObjectIdentifier = oid!(1.3.6.1.4.1.61783.612.1.1);
|
@ -132,7 +132,7 @@ pub trait SerializeDynOid {
|
||||
///
|
||||
/// This OID will be serialized alongside the trait object and is used to retrieve the
|
||||
/// correct vtable when loading the state from DB.
|
||||
fn archived_type_oid(&self) -> &'static ObjectIdentifier;
|
||||
fn archived_type_oid(&self) -> &'static ObjectIdentifier<'static>;
|
||||
|
||||
/// Serialize this type into a [`DynSerializer`](trait@DynSerializer)
|
||||
fn serialize_dynoid(&self, serializer: &mut dyn DynSerializer) -> Result<usize, DynError>;
|
||||
@ -144,7 +144,7 @@ pub trait SerializeDynOid {
|
||||
/// providing the OID that is serialized alongside the state object to be able to correctly cast
|
||||
/// it when accessing state from the DB.
|
||||
pub trait TypeOid {
|
||||
fn type_oid() -> &'static ObjectIdentifier;
|
||||
fn type_oid() -> &'static ObjectIdentifier<'static>;
|
||||
fn type_name() -> &'static str;
|
||||
}
|
||||
|
||||
@ -153,7 +153,7 @@ where
|
||||
T: for<'a> Serialize<dyn DynSerializer + 'a>,
|
||||
T::Archived: TypeOid,
|
||||
{
|
||||
fn archived_type_oid(&self) -> &'static ObjectIdentifier {
|
||||
fn archived_type_oid(&self) -> &'static ObjectIdentifier<'static> {
|
||||
Archived::<T>::type_oid()
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ impl ArchivePointee for dyn ArchivedStateValue {
|
||||
|
||||
impl ArchiveUnsized for dyn SerializeStateValue {
|
||||
type Archived = dyn ArchivedStateValue;
|
||||
type MetadataResolver = <ObjectIdentifier as Archive>::Resolver;
|
||||
type MetadataResolver = <ObjectIdentifier<'static> as Archive>::Resolver;
|
||||
|
||||
unsafe fn resolve_metadata(
|
||||
&self,
|
||||
@ -203,7 +203,7 @@ impl<S: ScratchSpace + Serializer + ?Sized> SerializeUnsized<S> for dyn Serializ
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ArchivedStateValueMetadata {
|
||||
pub type_oid: Archived<ObjectIdentifier>,
|
||||
pub type_oid: Archived<ObjectIdentifier<'static>>,
|
||||
vtable_cache: AtomicUsize,
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@
|
||||
//! [Object Identifiers]: https://en.wikipedia.org/wiki/Object_identifier
|
||||
//! [ITU]: https://en.wikipedia.org/wiki/International_Telecommunications_Union
|
||||
|
||||
use std::borrow::Cow;
|
||||
use crate::utils::varint::VarU128;
|
||||
use rkyv::ser::Serializer;
|
||||
use rkyv::vec::{ArchivedVec, VecResolver};
|
||||
@ -114,16 +115,16 @@ pub enum ObjectIdentifierError {
|
||||
/// Object Identifier (OID)
|
||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||
#[repr(transparent)]
|
||||
pub struct ObjectIdentifier {
|
||||
nodes: Box<[u8]>,
|
||||
pub struct ObjectIdentifier<'a> {
|
||||
nodes: Cow<'a, [u8]>,
|
||||
}
|
||||
|
||||
impl ObjectIdentifier {
|
||||
impl<'a> ObjectIdentifier<'a> {
|
||||
#[inline(always)]
|
||||
pub const fn new_unchecked(nodes: Box<[u8]>) -> Self {
|
||||
pub const fn new_unchecked(nodes: Cow<'a, [u8]>) -> Self {
|
||||
Self { nodes }
|
||||
}
|
||||
pub fn from_box(nodes: Box<[u8]>) -> Result<Self, ObjectIdentifierError> {
|
||||
pub fn from_box(nodes: Cow<'a, [u8]>) -> Result<Self, ObjectIdentifierError> {
|
||||
if nodes.len() < 1 {
|
||||
return Err(ObjectIdentifierError::IllegalRootNode);
|
||||
};
|
||||
@ -167,7 +168,7 @@ impl ObjectIdentifier {
|
||||
vec.extend_from_slice(var.as_bytes())
|
||||
}
|
||||
Ok(Self {
|
||||
nodes: vec.into_boxed_slice(),
|
||||
nodes: Cow::from(vec),
|
||||
})
|
||||
}
|
||||
|
||||
@ -175,28 +176,29 @@ impl ObjectIdentifier {
|
||||
pub fn root(&self) -> Result<ObjectIdentifierRoot, ObjectIdentifierError> {
|
||||
ObjectIdentifierRoot::try_from(self.nodes[0] / 40)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub const fn first_node(&self) -> u8 {
|
||||
self.nodes[0] % 40
|
||||
pub fn first_node(&self) -> u8 {
|
||||
self.nodes.as_ref()[0] % 40
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn child_nodes(&self) -> &[u8] {
|
||||
&self.nodes[1..]
|
||||
}
|
||||
#[inline(always)]
|
||||
pub const fn as_bytes(&self) -> &[u8] {
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
&self.nodes
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for ObjectIdentifier {
|
||||
impl Deref for ObjectIdentifier<'_> {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.nodes
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for ObjectIdentifier {
|
||||
impl FromStr for ObjectIdentifier<'static> {
|
||||
type Err = ObjectIdentifierError;
|
||||
|
||||
fn from_str(value: &str) -> Result<Self, Self::Err> {
|
||||
@ -230,13 +232,13 @@ impl FromStr for ObjectIdentifier {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ObjectIdentifier {
|
||||
impl fmt::Display for ObjectIdentifier<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
let show: String = self.into();
|
||||
write!(f, "{}", show)
|
||||
}
|
||||
}
|
||||
impl fmt::Debug for ObjectIdentifier {
|
||||
impl fmt::Debug for ObjectIdentifier<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
let show: String = self.into();
|
||||
write!(f, "{}", show)
|
||||
@ -266,7 +268,7 @@ impl fmt::Debug for ArchivedObjectIdentifier {
|
||||
}
|
||||
}
|
||||
|
||||
impl Archive for ObjectIdentifier {
|
||||
impl Archive for ObjectIdentifier<'_> {
|
||||
type Archived = ArchivedObjectIdentifier;
|
||||
type Resolver = VecResolver;
|
||||
|
||||
@ -275,7 +277,7 @@ impl Archive for ObjectIdentifier {
|
||||
ArchivedVec::resolve_from_slice(self.nodes.as_ref(), pos + oid_pos, resolver, oid_out);
|
||||
}
|
||||
}
|
||||
impl Archive for &'static ObjectIdentifier {
|
||||
impl Archive for &'static ObjectIdentifier<'_> {
|
||||
type Archived = ArchivedObjectIdentifier;
|
||||
type Resolver = VecResolver;
|
||||
|
||||
@ -285,7 +287,7 @@ impl Archive for &'static ObjectIdentifier {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Serializer + ?Sized> Serialize<S> for ObjectIdentifier
|
||||
impl<S: Serializer + ?Sized> Serialize<S> for ObjectIdentifier<'_>
|
||||
where
|
||||
[u8]: rkyv::SerializeUnsized<S>,
|
||||
{
|
||||
@ -304,8 +306,8 @@ fn parse_string_first_node(first_child_node: &str) -> Result<u8, ObjectIdentifie
|
||||
Ok(first_child_node)
|
||||
}
|
||||
|
||||
impl ObjectIdentifier {
|
||||
fn from_string<S>(value: S) -> Result<ObjectIdentifier, ObjectIdentifierError>
|
||||
impl ObjectIdentifier<'static> {
|
||||
fn from_string<S>(value: S) -> Result<Self, ObjectIdentifierError>
|
||||
where
|
||||
S: AsRef<str>,
|
||||
{
|
||||
@ -350,55 +352,55 @@ fn convert_to_string(nodes: &[u8]) -> Result<String, ObjectIdentifierError> {
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
impl Into<String> for &ObjectIdentifier {
|
||||
impl Into<String> for &ObjectIdentifier<'_> {
|
||||
fn into(self) -> String {
|
||||
convert_to_string(&self.nodes).expect("Valid OID object couldn't be serialized.")
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for ObjectIdentifier {
|
||||
impl Into<String> for ObjectIdentifier <'_>{
|
||||
fn into(self) -> String {
|
||||
(&self).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Into<&'a [u8]> for &'a ObjectIdentifier {
|
||||
impl<'a> Into<&'a [u8]> for &'a ObjectIdentifier<'_> {
|
||||
fn into(self) -> &'a [u8] {
|
||||
&self.nodes
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Vec<u8>> for ObjectIdentifier {
|
||||
impl Into<Vec<u8>> for ObjectIdentifier<'_> {
|
||||
fn into(self) -> Vec<u8> {
|
||||
self.nodes.into_vec()
|
||||
self.nodes.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for ObjectIdentifier {
|
||||
impl TryFrom<&str> for ObjectIdentifier<'static> {
|
||||
type Error = ObjectIdentifierError;
|
||||
fn try_from(value: &str) -> Result<ObjectIdentifier, Self::Error> {
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
ObjectIdentifier::from_string(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for ObjectIdentifier {
|
||||
impl TryFrom<String> for ObjectIdentifier<'static> {
|
||||
type Error = ObjectIdentifierError;
|
||||
fn try_from(value: String) -> Result<ObjectIdentifier, Self::Error> {
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
ObjectIdentifier::from_string(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&[u8]> for ObjectIdentifier {
|
||||
impl<'a> TryFrom<&'a [u8]> for ObjectIdentifier<'a> {
|
||||
type Error = ObjectIdentifierError;
|
||||
fn try_from(nodes: &[u8]) -> Result<ObjectIdentifier, Self::Error> {
|
||||
Self::from_box(nodes.into())
|
||||
fn try_from(nodes: &'a [u8]) -> Result<Self, Self::Error> {
|
||||
Self::from_box(Cow::Borrowed(nodes))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Vec<u8>> for ObjectIdentifier {
|
||||
impl TryFrom<Vec<u8>> for ObjectIdentifier<'static> {
|
||||
type Error = ObjectIdentifierError;
|
||||
fn try_from(value: Vec<u8>) -> Result<ObjectIdentifier, Self::Error> {
|
||||
Self::from_box(value.into_boxed_slice())
|
||||
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
|
||||
Self::from_box(Cow::from(value))
|
||||
}
|
||||
}
|
||||
|
||||
@ -410,17 +412,17 @@ mod serde_support {
|
||||
struct OidVisitor;
|
||||
|
||||
impl<'de> de::Visitor<'de> for OidVisitor {
|
||||
type Value = ObjectIdentifier;
|
||||
type Value = ObjectIdentifier<'de>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a valid buffer representing an OID")
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
ObjectIdentifier::try_from(v).map_err(|err| {
|
||||
ObjectIdentifier::try_from(v).map_err(move |err| {
|
||||
E::invalid_value(
|
||||
de::Unexpected::Other(match err {
|
||||
ObjectIdentifierError::IllegalRootNode => "illegal root node",
|
||||
@ -449,8 +451,8 @@ mod serde_support {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> de::Deserialize<'de> for ObjectIdentifier {
|
||||
fn deserialize<D>(deserializer: D) -> Result<ObjectIdentifier, D::Error>
|
||||
impl<'de> de::Deserialize<'de> for ObjectIdentifier<'de> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<ObjectIdentifier<'de>, D::Error>
|
||||
where
|
||||
D: de::Deserializer<'de>,
|
||||
{
|
||||
@ -462,7 +464,7 @@ mod serde_support {
|
||||
}
|
||||
}
|
||||
|
||||
impl ser::Serialize for ObjectIdentifier {
|
||||
impl ser::Serialize for ObjectIdentifier<'_> {
|
||||
fn serialize<S>(
|
||||
&self,
|
||||
serializer: S,
|
||||
@ -494,6 +496,67 @@ mod serde_support {
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper macro to declare Object Identifiers at compile-time
|
||||
///
|
||||
/// Since the DER encoded oids are not very readable we provide a
|
||||
/// procedural macro `oid!`. The macro can be used the following ways:
|
||||
///
|
||||
/// - `oid!(1.4.42.23)`: Create a const expression for the corresponding `Oid<'static>`
|
||||
/// - `oid!(rel 42.23)`: Create a const expression for the corresponding relative `Oid<'static>`
|
||||
/// - `oid!(raw 1.4.42.23)`/`oid!(raw rel 42.23)`: Obtain the DER encoded form as a byte array.
|
||||
///
|
||||
/// # Comparing oids
|
||||
///
|
||||
/// Comparing a parsed oid to a static oid is probably the most common
|
||||
/// thing done with oids in your code. The `oid!` macro can be used in expression positions for
|
||||
/// this purpose. For example
|
||||
/// ```
|
||||
/// use diflouroborane::oid;
|
||||
/// use diflouroborane::utils::oid::ObjectIdentifier;
|
||||
///
|
||||
/// # let some_oid: ObjectIdentifier = oid!(1.2.456);
|
||||
/// const SOME_STATIC_OID: ObjectIdentifier = oid!(1.2.456);
|
||||
/// assert_eq!(some_oid, SOME_STATIC_OID)
|
||||
/// ```
|
||||
/// To get a relative Oid use `oid!(rel 1.2)`.
|
||||
///
|
||||
/// Because of limitations for procedural macros ([rust issue](https://github.com/rust-lang/rust/issues/54727))
|
||||
/// and constants used in patterns ([rust issue](https://github.com/rust-lang/rust/issues/31434))
|
||||
/// the `oid` macro can not directly be used in patterns, also not through constants.
|
||||
/// You can do this, though:
|
||||
/// ```
|
||||
/// # use diflouroborane::oid;
|
||||
/// # use diflouroborane::utils::oid::ObjectIdentifier;
|
||||
/// # let some_oid: ObjectIdentifier<'static> = oid!(1.2.456);
|
||||
/// const SOME_OID: ObjectIdentifier<'static> = oid!(1.2.456);
|
||||
/// if some_oid == SOME_OID || some_oid == oid!(1.2.456) {
|
||||
/// println!("match");
|
||||
/// }
|
||||
///
|
||||
/// // Alternatively, compare the DER encoded form directly:
|
||||
/// const SOME_OID_RAW: &[u8] = &oid!(raw 1.2.456);
|
||||
/// match some_oid.as_bytes() {
|
||||
/// SOME_OID_RAW => println!("match"),
|
||||
/// _ => panic!("no match"),
|
||||
/// }
|
||||
/// ```
|
||||
/// *Attention*, be aware that the latter version might not handle the case of a relative oid correctly. An
|
||||
/// extra check might be necessary.
|
||||
#[macro_export]
|
||||
macro_rules! oid {
|
||||
(raw $( $item:literal ).*) => {
|
||||
::bffh_impl::encode_oid!( $( $item ).* )
|
||||
};
|
||||
(raw $items:expr) => {
|
||||
::bffh_impl::encode_oid!($items)
|
||||
};
|
||||
($($item:literal ).*) => {
|
||||
$crate::utils::oid::ObjectIdentifier::new_unchecked(::std::borrow::Cow::Borrowed(
|
||||
&$crate::oid!(raw $( $item ).*),
|
||||
))
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use super::*;
|
||||
|
Loading…
Reference in New Issue
Block a user