mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-23 23:27:57 +01:00
We don't use remote roles for now
This commit is contained in:
parent
4aaa281303
commit
9c87c192fa
@ -1,18 +1,17 @@
|
|||||||
|
[anotherrole]
|
||||||
|
|
||||||
[testrole]
|
[testrole]
|
||||||
name = "Testrole"
|
|
||||||
permissions = [
|
permissions = [
|
||||||
"lab.test.*"
|
"lab.test.*"
|
||||||
]
|
]
|
||||||
|
|
||||||
[somerole]
|
[somerole]
|
||||||
name = "Somerole"
|
parents = ["testparent/lmdb"]
|
||||||
parents = ["testparent%lmdb"]
|
|
||||||
permissions = [
|
permissions = [
|
||||||
"lab.some.admin"
|
"lab.some.admin"
|
||||||
]
|
]
|
||||||
|
|
||||||
[testparent]
|
[testparent]
|
||||||
name = "Testparent"
|
|
||||||
permissions = [
|
permissions = [
|
||||||
"lab.some.write",
|
"lab.some.write",
|
||||||
"lab.some.read",
|
"lab.some.read",
|
||||||
|
2
schema
2
schema
@ -1 +1 @@
|
|||||||
Subproject commit 83cd61e299230f33474e2efa950667d1acfbe085
|
Subproject commit 4adb05341763b96a43440a6a96e0d9959ba71e89
|
@ -42,7 +42,8 @@ impl machines::Server for Machines {
|
|||||||
let res = results.get();
|
let res = results.get();
|
||||||
let mut machines = res.init_machines(v.len() as u32);
|
let mut machines = res.init_machines(v.len() as u32);
|
||||||
|
|
||||||
for (i, (_name, machine)) in v.into_iter().enumerate() {
|
for (i, (name, machine)) in v.into_iter().enumerate() {
|
||||||
|
debug!(self.session.log, "Adding machine {}: {:?}", name, machine);
|
||||||
let machine = Arc::new(Machine::new(self.session.clone(), machine, self.db.clone()));
|
let machine = Arc::new(Machine::new(self.session.clone(), machine, self.db.clone()));
|
||||||
let mut builder = machines.reborrow().get(i as u32);
|
let mut builder = machines.reborrow().get(i as u32);
|
||||||
Machine::fill(machine, &mut builder);
|
Machine::fill(machine, &mut builder);
|
||||||
|
@ -50,6 +50,10 @@ impl AccessControl {
|
|||||||
pub fn dump_roles(&self) -> Result<Vec<(RoleIdentifier, Role)>> {
|
pub fn dump_roles(&self) -> Result<Vec<(RoleIdentifier, Role)>> {
|
||||||
self.internal.dump_roles()
|
self.internal.dump_roles()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_role(&self, role_id: &RoleIdentifier) -> Result<Option<Role>> {
|
||||||
|
self.internal.get_role(role_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for AccessControl {
|
impl fmt::Debug for AccessControl {
|
||||||
@ -162,37 +166,24 @@ type SourceID = String;
|
|||||||
fn split_once(s: &str, split: char) -> Option<(&str, &str)> {
|
fn split_once(s: &str, split: char) -> Option<(&str, &str)> {
|
||||||
s
|
s
|
||||||
.find(split)
|
.find(split)
|
||||||
.map(|idx| s.split_at(idx))
|
.map(|idx| (&s[..idx], &s[(idx+1)..]))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
#[serde(try_from = "String")]
|
#[serde(try_from = "String")]
|
||||||
|
#[serde(into = "String")]
|
||||||
/// Universal (relative) id of a role
|
/// Universal (relative) id of a role
|
||||||
pub enum RoleIdentifier {
|
pub struct RoleIdentifier {
|
||||||
/// The role comes from this instance
|
|
||||||
Local {
|
|
||||||
/// Locally unique name for the role. No other role at this instance no matter the source
|
/// Locally unique name for the role. No other role at this instance no matter the source
|
||||||
/// may have the same name
|
/// may have the same name
|
||||||
name: String,
|
name: String,
|
||||||
/// Role Source, i.e. the database the role comes from
|
/// Role Source, i.e. the database the role comes from
|
||||||
source: SourceID,
|
source: SourceID,
|
||||||
},
|
|
||||||
/// The role comes from a federated instance
|
|
||||||
Remote {
|
|
||||||
/// Name of the role. This role is unique in that instance so the tuple (name, location)
|
|
||||||
/// refers to a unique role
|
|
||||||
name: String,
|
|
||||||
/// The federated instance this role comes from
|
|
||||||
location: String,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for RoleIdentifier {
|
impl fmt::Display for RoleIdentifier {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
write!(f, "{}/{}", self.name, self.source)
|
||||||
RoleIdentifier::Local {name, source} => write!(f, "{}/{}@local", name, source),
|
|
||||||
RoleIdentifier::Remote {name, location} => write!(f, "{}@{}", name, location),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,10 +191,8 @@ impl std::str::FromStr for RoleIdentifier {
|
|||||||
type Err = RoleFromStrError;
|
type Err = RoleFromStrError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||||
if let Some((name, location)) = split_once(s, '@') {
|
if let Some((name, source)) = split_once(s, '/') {
|
||||||
Ok(RoleIdentifier::Remote { name: name.to_string(), location: location.to_string() })
|
Ok(RoleIdentifier { name: name.to_string(), source: source.to_string() })
|
||||||
} else if let Some((name, source)) = split_once(s, '%') {
|
|
||||||
Ok(RoleIdentifier::Local { name: name.to_string(), source: source.to_string() })
|
|
||||||
} else {
|
} else {
|
||||||
Err(RoleFromStrError::Invalid)
|
Err(RoleFromStrError::Invalid)
|
||||||
}
|
}
|
||||||
@ -214,21 +203,18 @@ impl TryFrom<String> for RoleIdentifier {
|
|||||||
type Error = RoleFromStrError;
|
type Error = RoleFromStrError;
|
||||||
|
|
||||||
fn try_from(s: String) -> std::result::Result<Self, Self::Error> {
|
fn try_from(s: String) -> std::result::Result<Self, Self::Error> {
|
||||||
if let Some((name, location)) = split_once(&s, '@') {
|
<RoleIdentifier as std::str::FromStr>::from_str(&s)
|
||||||
let location = &location[1..];
|
|
||||||
Ok(RoleIdentifier::Remote { name: name.to_string(), location: location.to_string() })
|
|
||||||
} else if let Some((name, source)) = split_once(&s, '%') {
|
|
||||||
let source = &source[1..];
|
|
||||||
Ok(RoleIdentifier::Local { name: name.to_string(), source: source.to_string() })
|
|
||||||
} else {
|
|
||||||
Err(RoleFromStrError::Invalid)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl Into<String> for RoleIdentifier {
|
||||||
|
fn into(self) -> String {
|
||||||
|
format!("{}", self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RoleIdentifier {
|
impl RoleIdentifier {
|
||||||
pub fn local_from_str(source: String, name: String) -> Self {
|
pub fn local_from_str(source: String, name: String) -> Self {
|
||||||
RoleIdentifier::Local { name, source }
|
RoleIdentifier { name, source }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,7 +491,7 @@ impl TryFrom<String> for PermRule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test_DISABLED)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -532,23 +518,46 @@ mod tests {
|
|||||||
assert!(rule.match_perm(&perm));
|
assert!(rule.match_perm(&perm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn format_and_read_compatible() {
|
||||||
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
let testdata = vec![
|
||||||
|
("testrole", "testsource"),
|
||||||
|
("", "norole"),
|
||||||
|
("nosource", "")
|
||||||
|
].into_iter().map(|(n,s)| (n.to_string(), s.to_string()));
|
||||||
|
|
||||||
|
for (name, source) in testdata {
|
||||||
|
let role = RoleIdentifier { name, source };
|
||||||
|
|
||||||
|
let fmt_string = format!("{}", &role);
|
||||||
|
|
||||||
|
println!("{:?} is formatted: {}", &role, &fmt_string);
|
||||||
|
|
||||||
|
let parsed: RoleIdentifier = fmt_string.try_into().unwrap();
|
||||||
|
|
||||||
|
println!("Which parses into {:?}", &parsed);
|
||||||
|
|
||||||
|
assert_eq!(role, parsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn load_examples_roles_test() {
|
fn load_examples_roles_test() {
|
||||||
let mut roles = Role::load_file("examples/roles.toml")
|
let mut roles = Role::load_file("examples/roles.toml")
|
||||||
.expect("Couldn't load the example role defs. Does `examples/roles.toml` exist?");
|
.expect("Couldn't load the example role defs. Does `examples/roles.toml` exist?");
|
||||||
|
|
||||||
let expected = vec![
|
let expected = vec![
|
||||||
(RoleIdentifier::Local { name: "testrole".to_string(), source: "lmdb".to_string() },
|
(RoleIdentifier { name: "testrole".to_string(), source: "lmdb".to_string() },
|
||||||
Role {
|
Role {
|
||||||
name: "Testrole".to_string(),
|
|
||||||
parents: vec![],
|
parents: vec![],
|
||||||
permissions: vec![
|
permissions: vec![
|
||||||
PermRule::Subtree(PermissionBuf::from_string("lab.test".to_string()))
|
PermRule::Subtree(PermissionBuf::from_string("lab.test".to_string()))
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
(RoleIdentifier::Local { name: "somerole".to_string(), source: "lmdb".to_string() },
|
(RoleIdentifier { name: "somerole".to_string(), source: "lmdb".to_string() },
|
||||||
Role {
|
Role {
|
||||||
name: "Somerole".to_string(),
|
|
||||||
parents: vec![
|
parents: vec![
|
||||||
RoleIdentifier::local_from_str("lmdb".to_string(), "testparent".to_string()),
|
RoleIdentifier::local_from_str("lmdb".to_string(), "testparent".to_string()),
|
||||||
],
|
],
|
||||||
@ -556,9 +565,8 @@ mod tests {
|
|||||||
PermRule::Base(PermissionBuf::from_string("lab.some.admin".to_string()))
|
PermRule::Base(PermissionBuf::from_string("lab.some.admin".to_string()))
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
(RoleIdentifier::Local { name: "testparent".to_string(), source: "lmdb".to_string() },
|
(RoleIdentifier { name: "testparent".to_string(), source: "lmdb".to_string() },
|
||||||
Role {
|
Role {
|
||||||
name: "Testparent".to_string(),
|
|
||||||
parents: vec![],
|
parents: vec![],
|
||||||
permissions: vec![
|
permissions: vec![
|
||||||
PermRule::Base(PermissionBuf::from_string("lab.some.write".to_string())),
|
PermRule::Base(PermissionBuf::from_string("lab.some.write".to_string())),
|
||||||
|
@ -77,6 +77,7 @@ impl Internal {
|
|||||||
|
|
||||||
pub fn _get_role<'txn, T: Transaction>(&self, txn: &'txn T, role_id: &RoleIdentifier) -> Result<Option<Role>> {
|
pub fn _get_role<'txn, T: Transaction>(&self, txn: &'txn T, role_id: &RoleIdentifier) -> Result<Option<Role>> {
|
||||||
let string = format!("{}", role_id);
|
let string = format!("{}", role_id);
|
||||||
|
debug!(self.log, "Reading role '{}'", &string);
|
||||||
match txn.get(self.roledb, &string.as_bytes()) {
|
match txn.get(self.roledb, &string.as_bytes()) {
|
||||||
Ok(bytes) => {
|
Ok(bytes) => {
|
||||||
Ok(Some(flexbuffers::from_slice(bytes)?))
|
Ok(Some(flexbuffers::from_slice(bytes)?))
|
||||||
@ -108,8 +109,10 @@ impl Internal {
|
|||||||
Ok( (k,v) ) => {
|
Ok( (k,v) ) => {
|
||||||
let role_id_str = unsafe { std::str::from_utf8_unchecked(k) };
|
let role_id_str = unsafe { std::str::from_utf8_unchecked(k) };
|
||||||
let role_id = role_id_str.parse::<RoleIdentifier>().unwrap();
|
let role_id = role_id_str.parse::<RoleIdentifier>().unwrap();
|
||||||
let role = flexbuffers::from_slice(v)?;
|
match flexbuffers::from_slice(v) {
|
||||||
vec.push((role_id, role));
|
Ok(role) => vec.push((role_id, role)),
|
||||||
|
Err(e) => error!(self.log, "Bad format for roleid {}: {}", role_id, e),
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user