mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-25 16:17:56 +01:00
Starts using LMDB
This commit is contained in:
parent
3ac60bacb0
commit
808386d17a
@ -17,6 +17,50 @@ impl PermissionsProvider {
|
||||
}
|
||||
|
||||
/// This line documents init
|
||||
pub async fn init(log: Logger, config: &Config) -> std::result::Result<PermissionsProvider, Box<dyn std::error::Error>> {
|
||||
pub fn init(log: Logger, config: &Config, env: &lmdb::Environment) -> std::result::Result<PermissionsProvider, crate::error::Error> {
|
||||
return Ok(PermissionsProvider::new(log));
|
||||
}
|
||||
|
||||
type RoleIdentifier = u64;
|
||||
type PermIdentifier = u64;
|
||||
|
||||
/// A Person, from the Authorization perspective
|
||||
struct Person {
|
||||
name: String,
|
||||
|
||||
/// A Person has N ≥ 0 roles.
|
||||
/// Persons are only ever given roles, not permissions directly
|
||||
roles: Vec<RoleIdentifier>
|
||||
}
|
||||
|
||||
/// A "Role" from the Authorization perspective
|
||||
///
|
||||
/// You can think of a role as a bundle of permissions relating to other roles. In most cases a
|
||||
/// role represents a real-world education or apprenticeship, which gives a person the education
|
||||
/// necessary to use a machine safely.
|
||||
/// Roles are assigned permissions which in most cases evaluate to granting a person the right to
|
||||
/// use certain (potentially) dangerous machines.
|
||||
/// Using this indirection makes administration easier in certain ways; instead of maintaining
|
||||
/// permissions on users directly the user is given a role after having been educated on the safety
|
||||
/// of a machine; if later on a similar enough machine is put to use the administrator can just add
|
||||
/// the permission for that machine to an already existing role instead of manually having to
|
||||
/// assign to all users.
|
||||
struct Role {
|
||||
name: String,
|
||||
|
||||
/// A Role can have parents, inheriting all permissions
|
||||
///
|
||||
/// This makes situations where different levels of access are required easier: Each higher
|
||||
/// level of access sets the lower levels of access as parent, inheriting their permission; if
|
||||
/// you are allowed to manage a machine you are then also allowed to use it and so on
|
||||
parents: Vec<RoleIdentifier>,
|
||||
permissions: Vec<PermIdentifier>,
|
||||
}
|
||||
|
||||
/// A Permission from the Authorization perspective
|
||||
///
|
||||
/// Permissions are rather simple flags. A person can have or not have a permission, dictated by
|
||||
/// its roles and the permissions assigned to those roles.
|
||||
struct Permission {
|
||||
name: String,
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ pub fn read(path: &Path) -> Result<Config> {
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
pub db: PathBuf,
|
||||
pub machinedb: PathBuf,
|
||||
pub passdb: PathBuf,
|
||||
pub(crate) access: Access,
|
||||
@ -40,6 +41,7 @@ pub struct Listen {
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Config {
|
||||
db: PathBuf::from_str("/tmp/bffh.db").unwrap(),
|
||||
machinedb: PathBuf::from_str("/tmp/machines.db").unwrap(),
|
||||
access: Access {
|
||||
model: PathBuf::from_str("/tmp/model.conf").unwrap(),
|
||||
|
@ -12,6 +12,7 @@ pub enum Error {
|
||||
IO(io::Error),
|
||||
Boxed(Box<dyn std::error::Error>),
|
||||
Capnp(capnp::Error),
|
||||
LMDB(lmdb::Error),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
@ -75,4 +76,10 @@ impl From<capnp::Error> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<lmdb::Error> for Error {
|
||||
fn from(e: lmdb::Error) -> Error {
|
||||
Error::LMDB(e)
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
17
src/main.rs
17
src/main.rs
@ -35,6 +35,8 @@ use std::sync::Arc;
|
||||
|
||||
use error::Error;
|
||||
|
||||
const LMDB_MAX_DB: u32 = 16;
|
||||
|
||||
// Returning a `Result` from `main` allows us to use the `?` shorthand.
|
||||
// In the case of an Err it will be printed using `fmt::Debug`
|
||||
fn main() -> Result<(), Error> {
|
||||
@ -95,11 +97,18 @@ fn main() -> Result<(), Error> {
|
||||
// asyncronous fashion.
|
||||
let mut exec = LocalPool::new();
|
||||
|
||||
// Initialize the LMDB environment. Since this would usually block untill the mmap() finishes
|
||||
// we wrap it in smol::unblock which runs this as future in a different thread.
|
||||
let e_config = config.clone();
|
||||
let env = lmdb::Environment::new()
|
||||
.set_max_dbs(LMDB_MAX_DB as libc::c_uint)
|
||||
.open(&e_config.db)?;
|
||||
|
||||
// Start loading the machine database, authentication system and permission system
|
||||
// All of those get a custom logger so the source of a log message can be better traced and
|
||||
// filtered
|
||||
let machinedb_f = machine::init(log.new(o!("system" => "machines")), &config);
|
||||
let permission_f = access::init(log.new(o!("system" => "permissions")), &config);
|
||||
let pdb = access::init(log.new(o!("system" => "permissions")), &config, &env);
|
||||
let authentication_f = auth::init(log.new(o!("system" => "authentication")), config.clone());
|
||||
|
||||
// Bind to each address in config.listen.
|
||||
@ -124,15 +133,15 @@ fn main() -> Result<(), Error> {
|
||||
}
|
||||
}).collect();
|
||||
|
||||
let (mach, pdb, auth) = exec.run_until(async {
|
||||
let (mach, auth) = exec.run_until(async {
|
||||
// Rull all futures to completion in parallel.
|
||||
// This will block until all three are done starting up.
|
||||
join!(machinedb_f, permission_f, authentication_f)
|
||||
join!(machinedb_f, authentication_f)
|
||||
});
|
||||
|
||||
// Error out if any of the subsystems failed to start.
|
||||
let mach = mach?;
|
||||
let pdb = pdb.unwrap();
|
||||
let pdb = pdb?;
|
||||
let auth = auth?;
|
||||
|
||||
// Since the below closures will happen at a much later time we need to make sure all pointers
|
||||
|
Loading…
Reference in New Issue
Block a user