This commit is contained in:
Nadja von Reitzenstein Čerpnjak 2024-04-22 15:30:34 +02:00
parent a9143b0cdd
commit 391661dbcc
16 changed files with 1336 additions and 825 deletions

1860
Cargo.lock generated

File diff suppressed because it is too large Load Diff

6
Writerside/c.list Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE categories
SYSTEM "https://resources.jetbrains.com/writerside/1.0/categories.dtd">
<categories>
<category id="wrs" name="Writerside documentation" order="1"/>
</categories>

10
Writerside/f.tree Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE instance-profile
SYSTEM "https://resources.jetbrains.com/writerside/1.0/product-profile.dtd">
<instance-profile id="f"
name="fabaccess"
start-page="starter-topic.md">
<toc-element topic="starter-topic.md"/>
</instance-profile>

View File

@ -0,0 +1,79 @@
# About fabaccess
<!--Writerside adds this topic when you create a new documentation project.
You can use it as a sandbox to play with Writerside features, and remove it from the TOC when you don't need it anymore.-->
## Add new topics
You can create empty topics, or choose a template for different types of content that contains some boilerplate structure to help you get started:
![Create new topic options](new_topic_options.png){ width=290 }{border-effect=line}
## Write content
%product% supports two types of markup: Markdown and XML.
When you create a new help article, you can choose between two topic types, but this doesn't mean you have to stick to a single format.
You can author content in Markdown and extend it with semantic attributes or inject entire XML elements.
## Inject XML
For example, this is how you inject a procedure:
<procedure title="Inject a procedure" id="inject-a-procedure">
<step>
<p>Start typing and select a procedure type from the completion suggestions:</p>
<img src="completion_procedure.png" alt="completion suggestions for procedure" border-effect="line"/>
</step>
<step>
<p>Press <shortcut>Tab</shortcut> or <shortcut>Enter</shortcut> to insert the markup.</p>
</step>
</procedure>
## Add interactive elements
### Tabs
To add switchable content, you can make use of tabs (inject them by starting to type `tab` on a new line):
<tabs>
<tab title="Markdown">
<code-block lang="plain text">![Alt Text](new_topic_options.png){ width=450 }</code-block>
</tab>
<tab title="Semantic markup">
<code-block lang="xml">
<![CDATA[<img src="new_topic_options.png" alt="Alt text" width="450px"/>]]></code-block>
</tab>
</tabs>
### Collapsible blocks
Apart from injecting entire XML elements, you can use attributes to configure the behavior of certain elements.
For example, you can collapse a chapter that contains non-essential information:
#### Supplementary info {collapsible="true"}
Content under a collapsible header will be collapsed by default,
but you can modify the behavior by adding the following attribute:
`default-state="expanded"`
### Convert selection to XML
If you need to extend an element with more functions, you can convert selected content from Markdown to semantic markup.
For example, if you want to merge cells in a table, it's much easier to convert it to XML than do this in Markdown.
Position the caret anywhere in the table and press <shortcut>Alt+Enter</shortcut>:
<img src="convert_table_to_xml.png" alt="Convert table to XML" width="706" border-effect="line"/>
## Feedback and support
Please report any issues, usability improvements, or feature requests to our
<a href="https://youtrack.jetbrains.com/newIssue?project=WRS">YouTrack project</a>
(you will need to register).
You are welcome to join our
<a href="https://jb.gg/WRS_Slack">public Slack workspace</a>.
Before you do, please read our [Code of conduct](https://plugins.jetbrains.com/plugin/20158-writerside/docs/writerside-code-of-conduct.html).
We assume that youve read and acknowledged it before joining.
You can also always email us at [writerside@jetbrains.com](mailto:writerside@jetbrains.com).
<seealso>
<category ref="wrs">
<a href="https://plugins.jetbrains.com/plugin/20158-writerside/docs/markup-reference.html">Markup reference</a>
<a href="https://plugins.jetbrains.com/plugin/20158-writerside/docs/manage-table-of-contents.html">Reorder topics in the TOC</a>
<a href="https://plugins.jetbrains.com/plugin/20158-writerside/docs/local-build.html">Build and publish</a>
<a href="https://plugins.jetbrains.com/plugin/20158-writerside/docs/configure-search.html">Configure Search</a>
</category>
</seealso>

5
Writerside/v.list Normal file
View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE vars SYSTEM "https://resources.jetbrains.com/writerside/1.0/vars.dtd">
<vars>
<var name="product" value="Writerside"/>
</vars>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ihp SYSTEM "https://resources.jetbrains.com/writerside/1.0/ihp.dtd">
<ihp version="2.0">
<topics dir="topics" web-path="topics"/>
<images dir="images" web-path="images"/>
<instance src="f.tree" web-path="/f/" version="1.0"/>
</ihp>

View File

@ -1,41 +1,103 @@
pub use capnpc::schema_capnp; pub use capnpc::schema_capnp;
pub mod authenticationsystem_capnp { pub mod audit_capnp {
include!(concat!(env!("OUT_DIR"), "/authenticationsystem_capnp.rs")); include!(concat!(env!("OUT_DIR"), "/audit_capnp.rs"));
} }
pub mod connection_capnp { pub mod auth_capnp {
include!(concat!(env!("OUT_DIR"), "/connection_capnp.rs")); include!(concat!(env!("OUT_DIR"), "/auth_capnp.rs"));
} }
pub mod general_capnp { pub mod cache_capnp {
include!(concat!(env!("OUT_DIR"), "/general_capnp.rs")); include!(concat!(env!("OUT_DIR"), "/cache_capnp.rs"));
} }
pub mod machine_capnp { pub mod claim_capnp {
include!(concat!(env!("OUT_DIR"), "/machine_capnp.rs")); include!(concat!(env!("OUT_DIR"), "/claim_capnp.rs"));
} }
pub mod machinesystem_capnp { pub mod interest_capnp {
include!(concat!(env!("OUT_DIR"), "/machinesystem_capnp.rs")); include!(concat!(env!("OUT_DIR"), "/interest_capnp.rs"));
} }
pub mod permissionsystem_capnp { pub mod main_capnp {
include!(concat!(env!("OUT_DIR"), "/permissionsystem_capnp.rs")); include!(concat!(env!("OUT_DIR"), "/main_capnp.rs"));
}
pub mod measure_capnp {
include!(concat!(env!("OUT_DIR"), "/measure_capnp.rs"));
}
pub mod notify_capnp {
include!(concat!(env!("OUT_DIR"), "/notify_capnp.rs"));
}
pub mod owned_capnp {
include!(concat!(env!("OUT_DIR"), "/owned_capnp.rs"));
}
pub mod permissions_capnp {
include!(concat!(env!("OUT_DIR"), "/permissions_capnp.rs"));
}
pub mod projects_capnp {
include!(concat!(env!("OUT_DIR"), "/projects_capnp.rs"));
}
pub mod resource_capnp {
include!(concat!(env!("OUT_DIR"), "/resource_capnp.rs"));
}
pub mod resources_capnp {
include!(concat!(env!("OUT_DIR"), "/resources_capnp.rs"));
} }
pub mod role_capnp { pub mod role_capnp {
include!(concat!(env!("OUT_DIR"), "/role_capnp.rs")); include!(concat!(env!("OUT_DIR"), "/role_capnp.rs"));
} }
pub mod space_capnp { pub mod state_capnp {
include!(concat!(env!("OUT_DIR"), "/space_capnp.rs")); include!(concat!(env!("OUT_DIR"), "/state_capnp.rs"));
}
pub mod traits_capnp {
include!(concat!(env!("OUT_DIR"), "/traits_capnp.rs"));
} }
pub mod user_capnp { pub mod user_capnp {
include!(concat!(env!("OUT_DIR"), "/user_capnp.rs")); include!(concat!(env!("OUT_DIR"), "/user_capnp.rs"));
} }
pub mod usersystem_capnp { pub mod users_capnp {
include!(concat!(env!("OUT_DIR"), "/usersystem_capnp.rs")); include!(concat!(env!("OUT_DIR"), "/users_capnp.rs"));
}
pub mod utils_capnp {
include!(concat!(env!("OUT_DIR"), "/utils_capnp.rs"));
}
pub mod traits {
pub mod checkable_capnp {
include!(concat!(env!("OUT_DIR"), "/traits/checkable_capnp.rs"));
}
pub mod claimable_capnp {
include!(concat!(env!("OUT_DIR"), "/traits/claimable_capnp.rs"));
}
pub mod door_capnp {
include!(concat!(env!("OUT_DIR"), "/traits/door_capnp.rs"));
}
pub mod locateable_capnp {
include!(concat!(env!("OUT_DIR"), "/traits/locateable_capnp.rs"));
}
pub mod lockers_capnp {
include!(concat!(env!("OUT_DIR"), "/traits/lockers_capnp.rs"));
}
pub mod powerable_capnp {
include!(concat!(env!("OUT_DIR"), "/traits/powerable_capnp.rs"));
}
} }

View File

@ -0,0 +1,4 @@
fn main() {
}

View File

@ -13,10 +13,11 @@ use tracing::Span;
use crate::authentication::V; use crate::authentication::V;
use crate::capnp::session::APISession; use crate::capnp::session::APISession;
use crate::session::SessionManager; use crate::session::SessionManager;
use api::authenticationsystem_capnp::authentication::{ use api::main_capnp::session::Owned as CPSession;
use api::auth_capnp::authentication::{
AbortParams, AbortResults, Server as AuthenticationSystem, StepParams, StepResults, AbortParams, AbortResults, Server as AuthenticationSystem, StepParams, StepResults,
}; };
use api::authenticationsystem_capnp::{response, response::Error as ErrorCode}; use api::auth_capnp::{response, response::Reason as ErrorCode};
const TARGET: &str = "bffh::api::authenticationsystem"; const TARGET: &str = "bffh::api::authenticationsystem";
@ -62,16 +63,16 @@ impl Authentication {
} }
} }
fn build_error(&self, response: response::Builder) { fn build_error(&self, response: response::Builder<CPSession>) {
if let State::Running(_, _) = self.state { if let State::Running(_, _) = self.state {
return; return;
} }
let mut builder = response.init_failed(); let mut builder = response.init_error();
match self.state { match self.state {
State::InvalidMechanism => builder.set_code(ErrorCode::BadMechanism), State::InvalidMechanism => builder.set_reason(ErrorCode::BadMechanism),
State::Finished => builder.set_code(ErrorCode::Aborted), State::Finished => builder.set_reason(ErrorCode::Aborted),
State::Aborted => builder.set_code(ErrorCode::Aborted), State::Aborted => builder.set_reason(ErrorCode::Aborted),
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -97,8 +98,8 @@ enum State {
Running(Session<V>, SessionManager), Running(Session<V>, SessionManager),
} }
impl AuthenticationSystem for Authentication { impl AuthenticationSystem<CPSession> for Authentication {
fn step(&mut self, params: StepParams, mut results: StepResults) -> Promise<(), Error> { fn step(&mut self, params: StepParams<CPSession>, mut results: StepResults<CPSession>) -> Promise<(), Error> {
let _guard = self.span.enter(); let _guard = self.span.enter();
let _span = tracing::trace_span!(target: TARGET, "step",).entered(); let _span = tracing::trace_span!(target: TARGET, "step",).entered();
@ -141,8 +142,8 @@ impl AuthenticationSystem for Authentication {
APISession::build(session, builder) APISession::build(session, builder)
} else { } else {
let mut builder = builder.init_failed(); let mut builder = builder.init_error();
builder.set_code(ErrorCode::InvalidCredentials); builder.set_reason(ErrorCode::InvalidCredentials);
response = Response { response = Response {
union_field: "error", union_field: "error",
@ -181,7 +182,7 @@ impl AuthenticationSystem for Authentication {
Promise::ok(()) Promise::ok(())
} }
fn abort(&mut self, _: AbortParams, _: AbortResults) -> Promise<(), Error> { fn abort(&mut self, _: AbortParams<CPSession>, _: AbortResults<CPSession>) -> Promise<(), Error> {
let _guard = self.span.enter(); let _guard = self.span.enter();
let _span = tracing::trace_span!( let _span = tracing::trace_span!(
target: TARGET, target: TARGET,

View File

@ -1,5 +1,5 @@
use api::connection_capnp::bootstrap; use api::main_capnp::bootstrap;
pub use api::connection_capnp::bootstrap::Client; pub use api::main_capnp::bootstrap::Client;
use std::fmt; use std::fmt;
use std::fmt::{Formatter, Write}; use std::fmt::{Formatter, Write};
use std::net::SocketAddr; use std::net::SocketAddr;
@ -102,7 +102,8 @@ impl bootstrap::Server for BootCap {
.collect(); .collect();
let mut mechbuilder = builder.init_mechs(mechs.len() as u32); let mut mechbuilder = builder.init_mechs(mechs.len() as u32);
for (i, m) in mechs.iter().enumerate() { for (i, m) in mechs.iter().enumerate() {
mechbuilder.set(i as u32, m); let mut b = mechbuilder.reborrow().get(i as u32);
b.set_name(m);
} }
struct DisMechs<'a>(Vec<&'a str>); struct DisMechs<'a>(Vec<&'a str>);

View File

@ -22,14 +22,15 @@ use crate::session::SessionManager;
mod config; mod config;
pub use config::{Listen, TlsListen}; pub use config::{Listen, TlsListen};
mod authenticationsystem;
mod connection; mod connection;
mod authenticationsystem;
mod session;
/*
mod machine; mod machine;
mod machinesystem; mod machinesystem;
mod permissionsystem; mod permissionsystem;
mod session;
mod user; mod user;
mod user_system; mod user_system;*/
pub struct APIServer { pub struct APIServer {
executor: Executor<'static>, executor: Executor<'static>,

View File

@ -1,9 +1,7 @@
use crate::authorization::permissions::Permission; use crate::authorization::permissions::Permission;
use api::authenticationsystem_capnp::response::successful::Builder; use api::main_capnp::session::Owned as CPSession;
use api::auth_capnp::response::successful::Builder;
use crate::capnp::machinesystem::Machines;
use crate::capnp::permissionsystem::Permissions;
use crate::capnp::user_system::Users;
use crate::session::SessionHandle; use crate::session::SessionHandle;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -14,27 +12,8 @@ impl APISession {
Self Self
} }
pub fn build(session: SessionHandle, builder: Builder) { pub fn build(session: SessionHandle, builder: Builder<CPSession>) {
let mut builder = builder.init_session(); let mut builder = builder.init_session();
{
let mut b = builder.reborrow().init_machine_system();
b.set_info(capnp_rpc::new_client(Machines::new(session.clone())));
}
{
let mut b = builder.reborrow().init_user_system();
let u = Users::new(session.clone());
if session.has_perm(Permission::new("bffh.users.manage")) {
b.set_manage(capnp_rpc::new_client(u.clone()));
b.set_search(capnp_rpc::new_client(u.clone()));
}
b.set_info(capnp_rpc::new_client(u));
}
{
let mut b = builder.init_permission_system();
b.set_info(capnp_rpc::new_client(Permissions::new(session)));
}
} }
} }

View File

@ -15,6 +15,7 @@ use std::sync::Arc;
use thiserror::Error; use thiserror::Error;
pub mod db; pub mod db;
pub mod traits;
use crate::users::db::UserData; use crate::users::db::UserData;
use crate::UserDB; use crate::UserDB;

16
bffhd/users/traits.rs Normal file
View File

@ -0,0 +1,16 @@
//! Core pluggable authentication traits
//!
//! Two traits are central to this module: [`AuthDB`] and [`UserDB`]. `AuthDB` handles identification
//! and authentication of an user, so is called first on SASL authentcation. It most importantly
//! returns the ID of the (authenticated) user, which is then passed to one or more `UserDB` to
//! look up information on that user.
use super::UserRef;
///
pub trait AuthDB {
}
pub trait UserDB {
}

View File

@ -1,17 +1,17 @@
use api::general_capnp::u_u_i_d::{Builder, Reader}; use api::utils_capnp::u_u_i_d::{Builder, Reader};
use uuid::Uuid; use uuid::Uuid;
pub fn uuid_to_api(uuid: Uuid, mut builder: Builder) { pub fn uuid_to_api(uuid: Uuid, mut builder: Builder) {
let [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = uuid.as_u128().to_ne_bytes(); let [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = uuid.as_u128().to_ne_bytes();
let lower = u64::from_ne_bytes([a, b, c, d, e, f, g, h]); let lower = u64::from_ne_bytes([a, b, c, d, e, f, g, h]);
let upper = u64::from_ne_bytes([i, j, k, l, m, n, o, p]); let upper = u64::from_ne_bytes([i, j, k, l, m, n, o, p]);
builder.set_uuid0(lower); builder.set_lower(lower);
builder.set_uuid1(upper); builder.set_upper(upper);
} }
pub fn api_to_uuid(reader: Reader) -> Uuid { pub fn api_to_uuid(reader: Reader) -> Uuid {
let lower: u64 = reader.reborrow().get_uuid0(); let lower: u64 = reader.reborrow().get_lower();
let upper: u64 = reader.get_uuid1(); let upper: u64 = reader.get_upper();
let [a, b, c, d, e, f, g, h] = lower.to_ne_bytes(); let [a, b, c, d, e, f, g, h] = lower.to_ne_bytes();
let [i, j, k, l, m, n, o, p] = upper.to_ne_bytes(); let [i, j, k, l, m, n, o, p] = upper.to_ne_bytes();
let num = u128::from_ne_bytes([a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p]); let num = u128::from_ne_bytes([a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p]);

View File

@ -1,2 +0,0 @@
[toolchain]
channel = "1.66"