mirror of
https://github.com/kanidm/kanidm.git
synced 2025-05-24 18:03:54 +02:00
Review feedback
This commit is contained in:
parent
a9c2e9f8da
commit
229f0514d4
74
Cargo.lock
generated
74
Cargo.lock
generated
|
@ -232,9 +232,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "async-compression"
|
||||
version = "0.4.21"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0cf008e5e1a9e9e22a7d3c9a4992e21a350290069e36d8fb72304ed17e8f2d2"
|
||||
checksum = "59a194f9d963d8099596278594b3107448656ba73831c9d8c783e613ce86da64"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"futures-core",
|
||||
|
@ -724,9 +724,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.32"
|
||||
version = "4.5.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83"
|
||||
checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
@ -734,9 +734,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.32"
|
||||
version = "4.5.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8"
|
||||
checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
@ -1167,9 +1167,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
|
||||
checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
"serde",
|
||||
|
@ -1441,13 +1441,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "fantoccini"
|
||||
version = "0.21.4"
|
||||
version = "0.21.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7722aeee9c2be6fa131166990295089d73d973012b758a2208b9ba51af5dd024"
|
||||
checksum = "e3a6a7a9a454c24453f9807c7f12b37e31ae43f3eb41888ae1f79a9a3e3be3f5"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"cookie 0.18.1",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http 1.3.1",
|
||||
"http-body-util",
|
||||
|
@ -2533,14 +2532,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.61"
|
||||
version = "0.1.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
|
||||
checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"log",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
@ -2595,9 +2595,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "icu_locid_transform_data"
|
||||
version = "1.5.0"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
|
||||
checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d"
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer"
|
||||
|
@ -2619,9 +2619,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "icu_normalizer_data"
|
||||
version = "1.5.0"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
|
||||
checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7"
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties"
|
||||
|
@ -2640,9 +2640,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "icu_properties_data"
|
||||
version = "1.5.0"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
|
||||
checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2"
|
||||
|
||||
[[package]]
|
||||
name = "icu_provider"
|
||||
|
@ -2843,9 +2843,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "jsonschema"
|
||||
version = "0.29.0"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c59cb1733c34377b6067a0419befd7f25073c5249ec3b0614a482bf499e1df5"
|
||||
checksum = "161c33c3ec738cfea3288c5c53dfcdb32fd4fc2954de86ea06f71b5a1a40bfcd"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"base64 0.22.1",
|
||||
|
@ -3493,9 +3493,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.26"
|
||||
version = "0.4.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
|
||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
|
@ -3967,9 +3967,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.1"
|
||||
version = "1.21.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc"
|
||||
checksum = "c2806eaa3524762875e21c3dcd057bc4b7bfa01ce4da8d46be1cd43649e1cc6b"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
|
@ -4502,9 +4502,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quinn-udp"
|
||||
version = "0.5.10"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e46f3055866785f6b92bc6164b76be02ca8f2eb4b002c0354b28cf4c119e5944"
|
||||
checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5"
|
||||
dependencies = [
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
|
@ -4637,9 +4637,9 @@ checksum = "5daffa8f5ca827e146485577fa9dba9bd9c6921e06e954ab8f6408c10f753086"
|
|||
|
||||
[[package]]
|
||||
name = "referencing"
|
||||
version = "0.29.0"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce52678d53e5ee37e4af0a9036ca834d0cd34b33c82457c6b06a24f8d783344"
|
||||
checksum = "40a64b3a635fad9000648b4d8a59c8710c523ab61a23d392a7d91d47683f5adc"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"fluent-uri",
|
||||
|
@ -4966,9 +4966,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.103.0"
|
||||
version = "0.103.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f"
|
||||
checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
|
@ -5595,9 +5595,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.40"
|
||||
version = "0.3.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618"
|
||||
checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
|
@ -5618,9 +5618,9 @@ checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
|
|||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.21"
|
||||
version = "0.2.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04"
|
||||
checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
|
@ -6482,9 +6482,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "whoami"
|
||||
version = "1.5.2"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d"
|
||||
checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7"
|
||||
dependencies = [
|
||||
"redox_syscall",
|
||||
"wasite",
|
||||
|
|
|
@ -33,7 +33,7 @@ pub enum ScimAttributeEffectiveAccess {
|
|||
/// All attributes on the entry have this permission granted
|
||||
Grant,
|
||||
/// All attributes on the entry have this permission denied
|
||||
Denied,
|
||||
Deny,
|
||||
/// The following attributes on the entry have this permission granted
|
||||
Allow(BTreeSet<Attribute>),
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ impl ScimAttributeEffectiveAccess {
|
|||
pub fn check(&self, attr: &Attribute) -> bool {
|
||||
match self {
|
||||
Self::Grant => true,
|
||||
Self::Denied => false,
|
||||
Self::Deny => false,
|
||||
Self::Allow(set) => set.contains(attr),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -599,19 +599,19 @@ impl IdmServerProxyWriteTransaction<'_> {
|
|||
}
|
||||
|
||||
let eperm_search_primary_cred = match &eperm.search {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::PrimaryCredential),
|
||||
};
|
||||
|
||||
let eperm_mod_primary_cred = match &eperm.modify_pres {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::PrimaryCredential),
|
||||
};
|
||||
|
||||
let eperm_rem_primary_cred = match &eperm.modify_rem {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::PrimaryCredential),
|
||||
};
|
||||
|
@ -620,19 +620,19 @@ impl IdmServerProxyWriteTransaction<'_> {
|
|||
eperm_search_primary_cred && eperm_mod_primary_cred && eperm_rem_primary_cred;
|
||||
|
||||
let eperm_search_passkeys = match &eperm.search {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::PassKeys),
|
||||
};
|
||||
|
||||
let eperm_mod_passkeys = match &eperm.modify_pres {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::PassKeys),
|
||||
};
|
||||
|
||||
let eperm_rem_passkeys = match &eperm.modify_rem {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::PassKeys),
|
||||
};
|
||||
|
@ -640,19 +640,19 @@ impl IdmServerProxyWriteTransaction<'_> {
|
|||
let passkeys_can_edit = eperm_search_passkeys && eperm_mod_passkeys && eperm_rem_passkeys;
|
||||
|
||||
let eperm_search_attested_passkeys = match &eperm.search {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::AttestedPasskeys),
|
||||
};
|
||||
|
||||
let eperm_mod_attested_passkeys = match &eperm.modify_pres {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::AttestedPasskeys),
|
||||
};
|
||||
|
||||
let eperm_rem_attested_passkeys = match &eperm.modify_rem {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::AttestedPasskeys),
|
||||
};
|
||||
|
@ -662,19 +662,19 @@ impl IdmServerProxyWriteTransaction<'_> {
|
|||
&& eperm_rem_attested_passkeys;
|
||||
|
||||
let eperm_search_unixcred = match &eperm.search {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::UnixPassword),
|
||||
};
|
||||
|
||||
let eperm_mod_unixcred = match &eperm.modify_pres {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::UnixPassword),
|
||||
};
|
||||
|
||||
let eperm_rem_unixcred = match &eperm.modify_rem {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::UnixPassword),
|
||||
};
|
||||
|
@ -685,19 +685,19 @@ impl IdmServerProxyWriteTransaction<'_> {
|
|||
&& eperm_rem_unixcred;
|
||||
|
||||
let eperm_search_sshpubkey = match &eperm.search {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::SshPublicKey),
|
||||
};
|
||||
|
||||
let eperm_mod_sshpubkey = match &eperm.modify_pres {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::SshPublicKey),
|
||||
};
|
||||
|
||||
let eperm_rem_sshpubkey = match &eperm.modify_rem {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::SshPublicKey),
|
||||
};
|
||||
|
@ -726,7 +726,7 @@ impl IdmServerProxyWriteTransaction<'_> {
|
|||
})?;
|
||||
|
||||
match &eperm.search {
|
||||
Access::Denied => false,
|
||||
Access::Deny => false,
|
||||
Access::Grant => true,
|
||||
Access::Allow(attrs) => attrs.contains(&Attribute::SyncCredentialPortal),
|
||||
}
|
||||
|
|
|
@ -6,12 +6,12 @@ use crate::prelude::*;
|
|||
use std::collections::BTreeSet;
|
||||
|
||||
pub(super) enum CreateResult {
|
||||
Denied,
|
||||
Deny,
|
||||
Grant,
|
||||
}
|
||||
|
||||
enum IResult {
|
||||
Denied,
|
||||
Deny,
|
||||
Grant,
|
||||
Ignore,
|
||||
}
|
||||
|
@ -26,25 +26,25 @@ pub(super) fn apply_create_access<'a>(
|
|||
|
||||
// This module can never yield a grant.
|
||||
match protected_filter_entry(ident, entry) {
|
||||
IResult::Denied => denied = true,
|
||||
IResult::Deny => denied = true,
|
||||
IResult::Grant | IResult::Ignore => {}
|
||||
}
|
||||
|
||||
match create_filter_entry(ident, related_acp, entry) {
|
||||
IResult::Denied => denied = true,
|
||||
IResult::Deny => denied = true,
|
||||
IResult::Grant => grant = true,
|
||||
IResult::Ignore => {}
|
||||
}
|
||||
|
||||
if denied {
|
||||
// Something explicitly said no.
|
||||
CreateResult::Denied
|
||||
CreateResult::Deny
|
||||
} else if grant {
|
||||
// Something said yes
|
||||
CreateResult::Grant
|
||||
} else {
|
||||
// Nothing said yes.
|
||||
CreateResult::Denied
|
||||
CreateResult::Deny
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ fn create_filter_entry<'a>(
|
|||
}
|
||||
IdentType::Synch(_) => {
|
||||
security_critical!("Blocking sync check");
|
||||
return IResult::Denied;
|
||||
return IResult::Deny;
|
||||
}
|
||||
IdentType::User(_) => {}
|
||||
};
|
||||
|
@ -70,7 +70,7 @@ fn create_filter_entry<'a>(
|
|||
match ident.access_scope() {
|
||||
AccessScope::ReadOnly | AccessScope::Synchronise => {
|
||||
security_access!("denied ❌ - identity access scope is not permitted to create");
|
||||
return IResult::Denied;
|
||||
return IResult::Deny;
|
||||
}
|
||||
AccessScope::ReadWrite => {
|
||||
// As you were
|
||||
|
@ -97,7 +97,7 @@ fn create_filter_entry<'a>(
|
|||
Some(s) => s.collect(),
|
||||
None => {
|
||||
admin_error!("Class set failed to build - corrupted entry?");
|
||||
return IResult::Denied;
|
||||
return IResult::Deny;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -174,7 +174,7 @@ fn protected_filter_entry(ident: &Identity, entry: &Entry<EntryInit, EntryNew>)
|
|||
}
|
||||
IdentType::Synch(_) => {
|
||||
security_access!("sync agreements may not directly create entities");
|
||||
IResult::Denied
|
||||
IResult::Deny
|
||||
}
|
||||
IdentType::User(_) => {
|
||||
// Now check things ...
|
||||
|
@ -185,7 +185,7 @@ fn protected_filter_entry(ident: &Identity, entry: &Entry<EntryInit, EntryNew>)
|
|||
} else {
|
||||
// Block the mod, something is present
|
||||
security_access!("attempt to create with protected class type");
|
||||
IResult::Denied
|
||||
IResult::Deny
|
||||
}
|
||||
} else {
|
||||
// Nothing to check - this entry will fail to create anyway because it has
|
||||
|
|
|
@ -6,12 +6,12 @@ use crate::prelude::*;
|
|||
use std::sync::Arc;
|
||||
|
||||
pub(super) enum DeleteResult {
|
||||
Denied,
|
||||
Deny,
|
||||
Grant,
|
||||
}
|
||||
|
||||
enum IResult {
|
||||
Denied,
|
||||
Deny,
|
||||
Grant,
|
||||
Ignore,
|
||||
}
|
||||
|
@ -25,25 +25,25 @@ pub(super) fn apply_delete_access<'a>(
|
|||
let mut grant = false;
|
||||
|
||||
match protected_filter_entry(ident, entry) {
|
||||
IResult::Denied => denied = true,
|
||||
IResult::Deny => denied = true,
|
||||
IResult::Grant | IResult::Ignore => {}
|
||||
}
|
||||
|
||||
match delete_filter_entry(ident, related_acp, entry) {
|
||||
IResult::Denied => denied = true,
|
||||
IResult::Deny => denied = true,
|
||||
IResult::Grant => grant = true,
|
||||
IResult::Ignore => {}
|
||||
}
|
||||
|
||||
if denied {
|
||||
// Something explicitly said no.
|
||||
DeleteResult::Denied
|
||||
DeleteResult::Deny
|
||||
} else if grant {
|
||||
// Something said yes
|
||||
DeleteResult::Grant
|
||||
} else {
|
||||
// Nothing said yes.
|
||||
DeleteResult::Denied
|
||||
DeleteResult::Deny
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ fn delete_filter_entry<'a>(
|
|||
}
|
||||
IdentType::Synch(_) => {
|
||||
security_critical!("Blocking sync check");
|
||||
return IResult::Denied;
|
||||
return IResult::Deny;
|
||||
}
|
||||
IdentType::User(_) => {}
|
||||
};
|
||||
|
@ -69,7 +69,7 @@ fn delete_filter_entry<'a>(
|
|||
match ident.access_scope() {
|
||||
AccessScope::ReadOnly | AccessScope::Synchronise => {
|
||||
security_access!("denied ❌ - identity access scope is not permitted to delete");
|
||||
return IResult::Denied;
|
||||
return IResult::Deny;
|
||||
}
|
||||
AccessScope::ReadWrite => {
|
||||
// As you were
|
||||
|
@ -153,13 +153,13 @@ fn protected_filter_entry(ident: &Identity, entry: &Arc<EntrySealedCommitted>) -
|
|||
}
|
||||
IdentType::Synch(_) => {
|
||||
security_access!("sync agreements may not directly delete entities");
|
||||
IResult::Denied
|
||||
IResult::Deny
|
||||
}
|
||||
IdentType::User(_) => {
|
||||
// Prevent deletion of entries that exist in the system controlled entry range.
|
||||
if entry.get_uuid() <= UUID_ANONYMOUS {
|
||||
security_access!("attempt to delete system builtin entry");
|
||||
return IResult::Denied;
|
||||
return IResult::Deny;
|
||||
}
|
||||
|
||||
// Prevent deleting some protected types.
|
||||
|
@ -170,7 +170,7 @@ fn protected_filter_entry(ident: &Identity, entry: &Arc<EntrySealedCommitted>) -
|
|||
} else {
|
||||
// Block the mod, something is present
|
||||
security_access!("attempt to create with protected class type");
|
||||
IResult::Denied
|
||||
IResult::Deny
|
||||
}
|
||||
} else {
|
||||
// Nothing to check - this entry will fail to create anyway because it has
|
||||
|
|
|
@ -56,7 +56,7 @@ mod search;
|
|||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Access {
|
||||
Grant,
|
||||
Denied,
|
||||
Deny,
|
||||
Allow(BTreeSet<Attribute>),
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ impl From<&Access> for ScimAttributeEffectiveAccess {
|
|||
fn from(value: &Access) -> Self {
|
||||
match value {
|
||||
Access::Grant => Self::Grant,
|
||||
Access::Denied => Self::Denied,
|
||||
Access::Deny => Self::Deny,
|
||||
Access::Allow(set) => Self::Allow(set.clone()),
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ impl From<&Access> for ScimAttributeEffectiveAccess {
|
|||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum AccessClass {
|
||||
Grant,
|
||||
Denied,
|
||||
Deny,
|
||||
Allow(BTreeSet<AttrString>),
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ pub struct AccessEffectivePermission {
|
|||
|
||||
pub enum AccessBasicResult {
|
||||
// Deny this operation unconditionally.
|
||||
Denied,
|
||||
Deny,
|
||||
// Unbounded allow, provided no deny state exists.
|
||||
Grant,
|
||||
// This module makes no decisions about this entry.
|
||||
|
@ -102,7 +102,7 @@ pub enum AccessBasicResult {
|
|||
|
||||
pub enum AccessSrchResult {
|
||||
// Deny this operation unconditionally.
|
||||
Denied,
|
||||
Deny,
|
||||
// Unbounded allow, provided no deny state exists.
|
||||
Grant,
|
||||
// This module makes no decisions about this entry.
|
||||
|
@ -120,7 +120,7 @@ pub enum AccessSrchResult {
|
|||
|
||||
pub enum AccessModResult<'a> {
|
||||
// Deny this operation unconditionally.
|
||||
Denied,
|
||||
Deny,
|
||||
// Unbounded allow, provided no deny state exists.
|
||||
// Grant,
|
||||
// This module makes no decisions about this entry.
|
||||
|
@ -327,7 +327,7 @@ pub trait AccessControlsTransaction<'a> {
|
|||
.into_iter()
|
||||
.filter(|e| {
|
||||
match apply_search_access(ident, related_acp.as_slice(), e) {
|
||||
SearchResult::Denied => false,
|
||||
SearchResult::Deny => false,
|
||||
SearchResult::Grant => true,
|
||||
SearchResult::Allow(allowed_attrs) => {
|
||||
// The allow set constrained.
|
||||
|
@ -425,7 +425,7 @@ pub trait AccessControlsTransaction<'a> {
|
|||
.into_iter()
|
||||
.filter_map(|entry| {
|
||||
match apply_search_access(&se.ident, &search_related_acp, &entry) {
|
||||
SearchResult::Denied => {
|
||||
SearchResult::Deny => {
|
||||
None
|
||||
}
|
||||
SearchResult::Grant => {
|
||||
|
@ -607,7 +607,7 @@ pub trait AccessControlsTransaction<'a> {
|
|||
debug!(entry_id = %e.get_display_id());
|
||||
|
||||
match apply_modify_access(&me.ident, related_acp.as_slice(), sync_agmts, e) {
|
||||
ModifyResult::Denied => false,
|
||||
ModifyResult::Deny => false,
|
||||
ModifyResult::Grant => true,
|
||||
ModifyResult::Allow {
|
||||
pres,
|
||||
|
@ -763,7 +763,7 @@ pub trait AccessControlsTransaction<'a> {
|
|||
let sync_agmts = self.get_sync_agreements();
|
||||
|
||||
match apply_modify_access(&me.ident, related_acp.as_slice(), sync_agmts, e) {
|
||||
ModifyResult::Denied => false,
|
||||
ModifyResult::Deny => false,
|
||||
ModifyResult::Grant => true,
|
||||
ModifyResult::Allow {
|
||||
pres,
|
||||
|
@ -862,7 +862,7 @@ pub trait AccessControlsTransaction<'a> {
|
|||
// For each entry
|
||||
let r = entries.iter().all(|e| {
|
||||
match apply_create_access(&ce.ident, related_acp.as_slice(), e) {
|
||||
CreateResult::Denied => false,
|
||||
CreateResult::Deny => false,
|
||||
CreateResult::Grant => true,
|
||||
}
|
||||
});
|
||||
|
@ -918,7 +918,7 @@ pub trait AccessControlsTransaction<'a> {
|
|||
// For each entry
|
||||
let r = entries.iter().all(|e| {
|
||||
match apply_delete_access(&de.ident, related_acp.as_slice(), e) {
|
||||
DeleteResult::Denied => false,
|
||||
DeleteResult::Deny => false,
|
||||
DeleteResult::Grant => true,
|
||||
}
|
||||
});
|
||||
|
@ -1007,7 +1007,7 @@ pub trait AccessControlsTransaction<'a> {
|
|||
) -> AccessEffectivePermission {
|
||||
// == search ==
|
||||
let search_effective = match apply_search_access(ident, search_related_acp, entry) {
|
||||
SearchResult::Denied => Access::Denied,
|
||||
SearchResult::Deny => Access::Deny,
|
||||
SearchResult::Grant => Access::Grant,
|
||||
SearchResult::Allow(allowed_attrs) => {
|
||||
// Bound by requested attrs?
|
||||
|
@ -1018,11 +1018,11 @@ pub trait AccessControlsTransaction<'a> {
|
|||
// == modify ==
|
||||
let (modify_pres, modify_rem, modify_pres_class, modify_rem_class) =
|
||||
match apply_modify_access(ident, modify_related_acp, sync_agmts, entry) {
|
||||
ModifyResult::Denied => (
|
||||
Access::Denied,
|
||||
Access::Denied,
|
||||
AccessClass::Denied,
|
||||
AccessClass::Denied,
|
||||
ModifyResult::Deny => (
|
||||
Access::Deny,
|
||||
Access::Deny,
|
||||
AccessClass::Deny,
|
||||
AccessClass::Deny,
|
||||
),
|
||||
ModifyResult::Grant => (
|
||||
Access::Grant,
|
||||
|
@ -1047,7 +1047,7 @@ pub trait AccessControlsTransaction<'a> {
|
|||
let delete_status = apply_delete_access(ident, delete_related_acp, entry);
|
||||
|
||||
let delete = match delete_status {
|
||||
DeleteResult::Denied => false,
|
||||
DeleteResult::Deny => false,
|
||||
DeleteResult::Grant => true,
|
||||
};
|
||||
|
||||
|
@ -2283,8 +2283,8 @@ mod tests {
|
|||
"member class",
|
||||
// Allow rem name and class
|
||||
"member class",
|
||||
"group",
|
||||
"group",
|
||||
EntryClass::Group.into(),
|
||||
EntryClass::Group.into(),
|
||||
);
|
||||
// Does not have a pres or rem class in attrs
|
||||
let acp_no_class = AccessControlModify::from_raw(
|
||||
|
@ -2302,8 +2302,8 @@ mod tests {
|
|||
// Allow rem name and class
|
||||
"name class",
|
||||
// And the class allowed is NOT an account ...
|
||||
"group",
|
||||
"group",
|
||||
EntryClass::Group.into(),
|
||||
EntryClass::Group.into(),
|
||||
);
|
||||
|
||||
// Test allowed pres
|
||||
|
|
|
@ -13,7 +13,7 @@ use std::collections::BTreeSet;
|
|||
use std::sync::Arc;
|
||||
|
||||
pub(super) enum ModifyResult<'a> {
|
||||
Denied,
|
||||
Deny,
|
||||
Grant,
|
||||
Allow {
|
||||
pres: BTreeSet<Attribute>,
|
||||
|
@ -52,14 +52,14 @@ pub(super) fn apply_modify_access<'a>(
|
|||
// kind of being three operations all in one.
|
||||
|
||||
match modify_ident_test(ident) {
|
||||
AccessBasicResult::Denied => denied = true,
|
||||
AccessBasicResult::Deny => denied = true,
|
||||
AccessBasicResult::Grant => grant = true,
|
||||
AccessBasicResult::Ignore => {}
|
||||
}
|
||||
|
||||
// Check with protected if we should proceed.
|
||||
match modify_protected_attrs(ident, entry) {
|
||||
AccessModResult::Denied => denied = true,
|
||||
AccessModResult::Deny => denied = true,
|
||||
AccessModResult::Constrain {
|
||||
mut pres_attr,
|
||||
mut rem_attr,
|
||||
|
@ -86,7 +86,7 @@ pub(super) fn apply_modify_access<'a>(
|
|||
if !grant && !denied {
|
||||
// If it's a sync entry, constrain it.
|
||||
match modify_sync_constrain(ident, entry, sync_agreements) {
|
||||
AccessModResult::Denied => denied = true,
|
||||
AccessModResult::Deny => denied = true,
|
||||
AccessModResult::Constrain {
|
||||
mut pres_attr,
|
||||
mut rem_attr,
|
||||
|
@ -156,7 +156,7 @@ pub(super) fn apply_modify_access<'a>(
|
|||
.collect();
|
||||
|
||||
match modify_pres_test(scoped_acp.as_slice()) {
|
||||
AccessModResult::Denied => denied = true,
|
||||
AccessModResult::Deny => denied = true,
|
||||
// Can never return a unilateral grant.
|
||||
// AccessModResult::Grant => {}
|
||||
AccessModResult::Ignore => {}
|
||||
|
@ -176,7 +176,7 @@ pub(super) fn apply_modify_access<'a>(
|
|||
}
|
||||
|
||||
if denied {
|
||||
ModifyResult::Denied
|
||||
ModifyResult::Deny
|
||||
} else if grant {
|
||||
ModifyResult::Grant
|
||||
} else {
|
||||
|
@ -235,7 +235,7 @@ fn modify_ident_test(ident: &Identity) -> AccessBasicResult {
|
|||
}
|
||||
IdentType::Synch(_) => {
|
||||
security_critical!("Blocking sync check");
|
||||
return AccessBasicResult::Denied;
|
||||
return AccessBasicResult::Deny;
|
||||
}
|
||||
IdentType::User(_) => {}
|
||||
};
|
||||
|
@ -244,7 +244,7 @@ fn modify_ident_test(ident: &Identity) -> AccessBasicResult {
|
|||
match ident.access_scope() {
|
||||
AccessScope::ReadOnly | AccessScope::Synchronise => {
|
||||
security_access!("denied ❌ - identity access scope is not permitted to modify");
|
||||
return AccessBasicResult::Denied;
|
||||
return AccessBasicResult::Deny;
|
||||
}
|
||||
AccessScope::ReadWrite => {
|
||||
// As you were
|
||||
|
@ -328,7 +328,7 @@ fn modify_sync_constrain<'a>(
|
|||
}
|
||||
} else {
|
||||
warn!(entry = ?entry.get_uuid(), "sync_parent_uuid not found on sync object, preventing all access");
|
||||
AccessModResult::Denied
|
||||
AccessModResult::Deny
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ fn modify_protected_entry_attrs<'a>(classes: &BTreeSet<String>) -> AccessModResu
|
|||
// First check for the hard-deny rules.
|
||||
if !classes.is_disjoint(&LOCKED_ENTRY_CLASSES) {
|
||||
// Hard deny attribute modifications to these types.
|
||||
return AccessModResult::Denied;
|
||||
return AccessModResult::Deny;
|
||||
}
|
||||
|
||||
let mut constrain_attrs = BTreeSet::default();
|
||||
|
@ -422,7 +422,7 @@ fn modify_protected_entry_attrs<'a>(classes: &BTreeSet<String>) -> AccessModResu
|
|||
// If we don't constrain the attributes at all, we have to deny the change
|
||||
// from proceeding.
|
||||
if constrain_attrs.is_empty() {
|
||||
AccessModResult::Denied
|
||||
AccessModResult::Deny
|
||||
} else {
|
||||
AccessModResult::Constrain {
|
||||
pres_attr: constrain_attrs.clone(),
|
||||
|
|
|
@ -1,89 +1,83 @@
|
|||
use crate::prelude::EntryClass;
|
||||
use std::collections::BTreeSet;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
lazy_static! {
|
||||
/// These entry classes may not be created or deleted, and may invoke some protection rules
|
||||
/// if on an entry.
|
||||
pub static ref PROTECTED_ENTRY_CLASSES: BTreeSet<String> = {
|
||||
let classes = vec![
|
||||
EntryClass::System,
|
||||
EntryClass::DomainInfo,
|
||||
EntryClass::SystemInfo,
|
||||
EntryClass::SystemConfig,
|
||||
EntryClass::DynGroup,
|
||||
EntryClass::SyncObject,
|
||||
EntryClass::Tombstone,
|
||||
EntryClass::Recycled,
|
||||
];
|
||||
/// These entry classes may not be created or deleted, and may invoke some protection rules
|
||||
/// if on an entry.
|
||||
pub static PROTECTED_ENTRY_CLASSES: LazyLock<BTreeSet<String>> = LazyLock::new(|| {
|
||||
let classes = vec![
|
||||
EntryClass::System,
|
||||
EntryClass::DomainInfo,
|
||||
EntryClass::SystemInfo,
|
||||
EntryClass::SystemConfig,
|
||||
EntryClass::DynGroup,
|
||||
EntryClass::SyncObject,
|
||||
EntryClass::Tombstone,
|
||||
EntryClass::Recycled,
|
||||
];
|
||||
|
||||
BTreeSet::from_iter(classes.into_iter()
|
||||
.map(|ec| ec.into()))
|
||||
};
|
||||
BTreeSet::from_iter(classes.into_iter().map(|ec| ec.into()))
|
||||
});
|
||||
|
||||
/// Entries with these classes are protected from modifications - not that
|
||||
/// sync object is not present here as there are separate rules for that in
|
||||
/// the modification access module.
|
||||
///
|
||||
/// Recycled is also not protected here as it needs to be able to be removed
|
||||
/// by a recycle bin admin.
|
||||
pub static ref PROTECTED_MOD_ENTRY_CLASSES: BTreeSet<String> = {
|
||||
let classes = vec![
|
||||
EntryClass::System,
|
||||
EntryClass::DomainInfo,
|
||||
EntryClass::SystemInfo,
|
||||
EntryClass::SystemConfig,
|
||||
EntryClass::DynGroup,
|
||||
// EntryClass::SyncObject,
|
||||
EntryClass::Tombstone,
|
||||
EntryClass::Recycled,
|
||||
];
|
||||
/// Entries with these classes are protected from modifications - not that
|
||||
/// sync object is not present here as there are separate rules for that in
|
||||
/// the modification access module.
|
||||
///
|
||||
/// Recycled is also not protected here as it needs to be able to be removed
|
||||
/// by a recycle bin admin.
|
||||
pub static PROTECTED_MOD_ENTRY_CLASSES: LazyLock<BTreeSet<String>> = LazyLock::new(|| {
|
||||
let classes = vec![
|
||||
EntryClass::System,
|
||||
EntryClass::DomainInfo,
|
||||
EntryClass::SystemInfo,
|
||||
EntryClass::SystemConfig,
|
||||
EntryClass::DynGroup,
|
||||
// EntryClass::SyncObject,
|
||||
EntryClass::Tombstone,
|
||||
EntryClass::Recycled,
|
||||
];
|
||||
|
||||
BTreeSet::from_iter(classes.into_iter()
|
||||
.map(|ec| ec.into()))
|
||||
};
|
||||
BTreeSet::from_iter(classes.into_iter().map(|ec| ec.into()))
|
||||
});
|
||||
|
||||
/// These classes may NOT be added to ANY ENTRY
|
||||
pub static ref PROTECTED_MOD_PRES_ENTRY_CLASSES: BTreeSet<String> = {
|
||||
let classes = vec![
|
||||
EntryClass::System,
|
||||
EntryClass::DomainInfo,
|
||||
EntryClass::SystemInfo,
|
||||
EntryClass::SystemConfig,
|
||||
EntryClass::DynGroup,
|
||||
EntryClass::SyncObject,
|
||||
EntryClass::Tombstone,
|
||||
EntryClass::Recycled,
|
||||
];
|
||||
/// These classes may NOT be added to ANY ENTRY
|
||||
pub static PROTECTED_MOD_PRES_ENTRY_CLASSES: LazyLock<BTreeSet<String>> = LazyLock::new(|| {
|
||||
let classes = vec![
|
||||
EntryClass::System,
|
||||
EntryClass::DomainInfo,
|
||||
EntryClass::SystemInfo,
|
||||
EntryClass::SystemConfig,
|
||||
EntryClass::DynGroup,
|
||||
EntryClass::SyncObject,
|
||||
EntryClass::Tombstone,
|
||||
EntryClass::Recycled,
|
||||
];
|
||||
|
||||
BTreeSet::from_iter(classes.into_iter()
|
||||
.map(|ec| ec.into()))
|
||||
};
|
||||
BTreeSet::from_iter(classes.into_iter().map(|ec| ec.into()))
|
||||
});
|
||||
|
||||
/// These classes may NOT be removed from ANY ENTRY
|
||||
pub static ref PROTECTED_MOD_REM_ENTRY_CLASSES: BTreeSet<String> = {
|
||||
let classes = vec![
|
||||
EntryClass::System,
|
||||
EntryClass::DomainInfo,
|
||||
EntryClass::SystemInfo,
|
||||
EntryClass::SystemConfig,
|
||||
EntryClass::DynGroup,
|
||||
EntryClass::SyncObject,
|
||||
EntryClass::Tombstone,
|
||||
// EntryClass::Recycled,
|
||||
];
|
||||
/// These classes may NOT be removed from ANY ENTRY
|
||||
pub static PROTECTED_MOD_REM_ENTRY_CLASSES: LazyLock<BTreeSet<String>> = LazyLock::new(|| {
|
||||
let classes = vec![
|
||||
EntryClass::System,
|
||||
EntryClass::DomainInfo,
|
||||
EntryClass::SystemInfo,
|
||||
EntryClass::SystemConfig,
|
||||
EntryClass::DynGroup,
|
||||
EntryClass::SyncObject,
|
||||
EntryClass::Tombstone,
|
||||
// EntryClass::Recycled,
|
||||
];
|
||||
|
||||
BTreeSet::from_iter(classes.into_iter()
|
||||
.map(|ec| ec.into()))
|
||||
};
|
||||
BTreeSet::from_iter(classes.into_iter().map(|ec| ec.into()))
|
||||
});
|
||||
|
||||
/// Entries with these classes may not be modified under any circumstance.
|
||||
pub static ref LOCKED_ENTRY_CLASSES: BTreeSet<String> = {
|
||||
let classes = vec![
|
||||
EntryClass::Tombstone,
|
||||
// EntryClass::Recycled,
|
||||
];
|
||||
/// Entries with these classes may not be modified under any circumstance.
|
||||
pub static LOCKED_ENTRY_CLASSES: LazyLock<BTreeSet<String>> = LazyLock::new(|| {
|
||||
let classes = vec![
|
||||
EntryClass::Tombstone,
|
||||
// EntryClass::Recycled,
|
||||
];
|
||||
|
||||
BTreeSet::from_iter(classes.into_iter()
|
||||
.map(|ec| ec.into()))
|
||||
};
|
||||
}
|
||||
BTreeSet::from_iter(classes.into_iter().map(|ec| ec.into()))
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@ use super::AccessSrchResult;
|
|||
use std::sync::Arc;
|
||||
|
||||
pub(super) enum SearchResult {
|
||||
Denied,
|
||||
Deny,
|
||||
Grant,
|
||||
Allow(BTreeSet<Attribute>),
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ pub(super) fn apply_search_access(
|
|||
|
||||
// The access control profile
|
||||
match search_filter_entry(ident, related_acp, entry) {
|
||||
AccessSrchResult::Denied => denied = true,
|
||||
AccessSrchResult::Deny => denied = true,
|
||||
AccessSrchResult::Grant => grant = true,
|
||||
AccessSrchResult::Ignore => {}
|
||||
// AccessSrchResult::Constrain { mut attr } => constrain.append(&mut attr),
|
||||
|
@ -36,7 +36,7 @@ pub(super) fn apply_search_access(
|
|||
};
|
||||
|
||||
match search_oauth2_filter_entry(ident, entry) {
|
||||
AccessSrchResult::Denied => denied = true,
|
||||
AccessSrchResult::Deny => denied = true,
|
||||
AccessSrchResult::Grant => grant = true,
|
||||
AccessSrchResult::Ignore => {}
|
||||
// AccessSrchResult::Constrain { mut attr } => constrain.append(&mut attr),
|
||||
|
@ -44,7 +44,7 @@ pub(super) fn apply_search_access(
|
|||
};
|
||||
|
||||
match search_sync_account_filter_entry(ident, entry) {
|
||||
AccessSrchResult::Denied => denied = true,
|
||||
AccessSrchResult::Deny => denied = true,
|
||||
AccessSrchResult::Grant => grant = true,
|
||||
AccessSrchResult::Ignore => {}
|
||||
// AccessSrchResult::Constrain{ mut attr } => constrain.append(&mut attr),
|
||||
|
@ -56,7 +56,7 @@ pub(super) fn apply_search_access(
|
|||
// Now finalise the decision.
|
||||
|
||||
if denied {
|
||||
SearchResult::Denied
|
||||
SearchResult::Deny
|
||||
} else if grant {
|
||||
SearchResult::Grant
|
||||
} else {
|
||||
|
@ -84,7 +84,7 @@ fn search_filter_entry(
|
|||
}
|
||||
IdentType::Synch(_) => {
|
||||
security_debug!(uuid = ?entry.get_display_id(), "Blocking sync check");
|
||||
return AccessSrchResult::Denied;
|
||||
return AccessSrchResult::Deny;
|
||||
}
|
||||
IdentType::User(_) => {}
|
||||
};
|
||||
|
@ -95,7 +95,7 @@ fn search_filter_entry(
|
|||
security_debug!(
|
||||
"denied ❌ - identity access scope 'Synchronise' is not permitted to search"
|
||||
);
|
||||
return AccessSrchResult::Denied;
|
||||
return AccessSrchResult::Deny;
|
||||
}
|
||||
AccessScope::ReadOnly | AccessScope::ReadWrite => {
|
||||
// As you were
|
||||
|
|
Loading…
Reference in a new issue