mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-22 14:57: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
|
/// 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));
|
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)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
pub db: PathBuf,
|
||||||
pub machinedb: PathBuf,
|
pub machinedb: PathBuf,
|
||||||
pub passdb: PathBuf,
|
pub passdb: PathBuf,
|
||||||
pub(crate) access: Access,
|
pub(crate) access: Access,
|
||||||
@ -40,6 +41,7 @@ pub struct Listen {
|
|||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Config {
|
Config {
|
||||||
|
db: PathBuf::from_str("/tmp/bffh.db").unwrap(),
|
||||||
machinedb: PathBuf::from_str("/tmp/machines.db").unwrap(),
|
machinedb: PathBuf::from_str("/tmp/machines.db").unwrap(),
|
||||||
access: Access {
|
access: Access {
|
||||||
model: PathBuf::from_str("/tmp/model.conf").unwrap(),
|
model: PathBuf::from_str("/tmp/model.conf").unwrap(),
|
||||||
|
@ -12,6 +12,7 @@ pub enum Error {
|
|||||||
IO(io::Error),
|
IO(io::Error),
|
||||||
Boxed(Box<dyn std::error::Error>),
|
Boxed(Box<dyn std::error::Error>),
|
||||||
Capnp(capnp::Error),
|
Capnp(capnp::Error),
|
||||||
|
LMDB(lmdb::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for 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>;
|
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;
|
use error::Error;
|
||||||
|
|
||||||
|
const LMDB_MAX_DB: u32 = 16;
|
||||||
|
|
||||||
// Returning a `Result` from `main` allows us to use the `?` shorthand.
|
// Returning a `Result` from `main` allows us to use the `?` shorthand.
|
||||||
// In the case of an Err it will be printed using `fmt::Debug`
|
// In the case of an Err it will be printed using `fmt::Debug`
|
||||||
fn main() -> Result<(), Error> {
|
fn main() -> Result<(), Error> {
|
||||||
@ -95,11 +97,18 @@ fn main() -> Result<(), Error> {
|
|||||||
// asyncronous fashion.
|
// asyncronous fashion.
|
||||||
let mut exec = LocalPool::new();
|
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
|
// 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
|
// All of those get a custom logger so the source of a log message can be better traced and
|
||||||
// filtered
|
// filtered
|
||||||
let machinedb_f = machine::init(log.new(o!("system" => "machines")), &config);
|
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());
|
let authentication_f = auth::init(log.new(o!("system" => "authentication")), config.clone());
|
||||||
|
|
||||||
// Bind to each address in config.listen.
|
// Bind to each address in config.listen.
|
||||||
@ -124,15 +133,15 @@ fn main() -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
let (mach, pdb, auth) = exec.run_until(async {
|
let (mach, auth) = exec.run_until(async {
|
||||||
// Rull all futures to completion in parallel.
|
// Rull all futures to completion in parallel.
|
||||||
// This will block until all three are done starting up.
|
// 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.
|
// Error out if any of the subsystems failed to start.
|
||||||
let mach = mach?;
|
let mach = mach?;
|
||||||
let pdb = pdb.unwrap();
|
let pdb = pdb?;
|
||||||
let auth = auth?;
|
let auth = auth?;
|
||||||
|
|
||||||
// Since the below closures will happen at a much later time we need to make sure all pointers
|
// 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