20240926 tech debt (#3066)

Large clean up
This commit is contained in:
Firstyear 2024-10-01 10:07:08 +10:00 committed by GitHub
parent 23636acbf7
commit 90afc8207c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 801 additions and 959 deletions

View file

@ -598,10 +598,17 @@ impl fmt::Display for Attribute {
mod test { mod test {
use super::Attribute; use super::Attribute;
#[test]
fn test_valueattribute_from_str() {
assert_eq!(Attribute::Uuid, Attribute::from_str("UUID"));
assert_eq!(Attribute::Uuid, Attribute::from_str("UuiD"));
assert_eq!(Attribute::Uuid, Attribute::from_str("uuid"));
}
#[test] #[test]
fn test_valueattribute_as_str() { fn test_valueattribute_as_str() {
assert!(Attribute::Class.as_str() == "class"); assert_eq!(Attribute::Class.as_str(), "class");
assert!(Attribute::Class.to_string() == *"class"); assert_eq!(Attribute::Class.to_string(), "class".to_string());
} }
#[test] #[test]

View file

@ -351,178 +351,6 @@ impl Entry<EntryInit, EntryNew> {
Self::from_proto_entry(&pe, qs) Self::from_proto_entry(&pe, qs)
} }
#[cfg(test)]
// TODO: #[deprecated(note = "Use entry_init! macro instead or like... anything else")]
pub(crate) fn unsafe_from_entry_str(es: &str) -> Self {
// Just use log directly here, it's testing
// str -> proto entry
let pe: ProtoEntry = serde_json::from_str(es).expect("Invalid Proto Entry");
// use a const map to convert str -> ava
let x: Eattrs = pe.attrs.into_iter()
.filter_map(|(k, vs)| {
if vs.is_empty() {
None
} else {
let attr = Attribute::from(k.to_lowercase().as_str());
let vv: ValueSet = match attr.as_str() {
kanidm_proto::constants::ATTR_ATTRIBUTENAME | kanidm_proto::constants::ATTR_CLASSNAME | kanidm_proto::constants::ATTR_DOMAIN => {
valueset::from_value_iter(
vs.into_iter().map(|v| Value::new_iutf8(&v))
)
}
kanidm_proto::constants::ATTR_NAME | kanidm_proto::constants::ATTR_DOMAIN_NAME => {
valueset::from_value_iter(
vs.into_iter().map(|v| Value::new_iname(&v))
)
}
kanidm_proto::constants::ATTR_USERID | kanidm_proto::constants::ATTR_UIDNUMBER => {
warn!("WARNING: Use of unstabilised attributes userid/uidnumber");
valueset::from_value_iter(
vs.into_iter().map(|v| Value::new_iutf8(&v))
)
}
kanidm_proto::constants::ATTR_CLASS | kanidm_proto::constants::ATTR_ACP_CREATE_CLASS | kanidm_proto::constants::ATTR_ACP_MODIFY_CLASS => {
valueset::from_value_iter(
vs.into_iter().map(|v| Value::new_class(v.as_str()))
)
}
kanidm_proto::constants::ATTR_ACP_CREATE_ATTR |
kanidm_proto::constants::ATTR_ACP_SEARCH_ATTR |
kanidm_proto::constants::ATTR_ACP_MODIFY_REMOVEDATTR |
kanidm_proto::constants::ATTR_ACP_MODIFY_PRESENTATTR |
kanidm_proto::constants::ATTR_SYSTEMMAY |
kanidm_proto::constants::ATTR_SYSTEMMUST |
kanidm_proto::constants::ATTR_MAY |
kanidm_proto::constants::ATTR_MUST
=> {
valueset::from_value_iter(
vs.into_iter().map(|v| Value::new_attr(v.as_str()))
)
}
kanidm_proto::constants::ATTR_UUID |
kanidm_proto::constants::ATTR_DOMAIN_UUID => {
valueset::from_value_iter(
vs.into_iter().map(|v| Value::new_uuid_s(v.as_str())
.unwrap_or_else(|| {
warn!("WARNING: Allowing syntax incorrect attribute to be presented UTF8 string");
Value::new_utf8(v)
})
)
)
}
kanidm_proto::constants::ATTR_MEMBER |
kanidm_proto::constants::ATTR_MEMBEROF |
kanidm_proto::constants::ATTR_DIRECTMEMBEROF |
kanidm_proto::constants::ATTR_ACP_RECEIVER_GROUP => {
valueset::from_value_iter(
vs.into_iter().map(|v| Value::new_refer_s(v.as_str()).expect("Failed to convert value") )
)
}
kanidm_proto::constants::ATTR_ACP_ENABLE |
kanidm_proto::constants::ATTR_MULTIVALUE |
kanidm_proto::constants::ATTR_UNIQUE => {
valueset::from_value_iter(
vs.into_iter().map(|v| Value::new_bools(v.as_str())
.unwrap_or_else(|| {
warn!("WARNING: Allowing syntax incorrect attribute to be presented UTF8 string");
Value::new_utf8(v)
})
)
)
}
kanidm_proto::constants::ATTR_SYNTAX => {
valueset::from_value_iter(
vs.into_iter().map(|v| Value::new_syntaxs(v.as_str())
.unwrap_or_else(|| {
warn!("WARNING: Allowing syntax incorrect attribute to be presented UTF8 string");
Value::new_utf8(v)
})
)
)
}
kanidm_proto::constants::ATTR_INDEX => {
valueset::from_value_iter(
vs.into_iter().map(|v| Value::new_indexes(v.as_str())
.unwrap_or_else(|| {
warn!("WARNING: Allowing syntax incorrect attribute to be presented UTF8 string");
Value::new_utf8(v)
})
)
)
}
kanidm_proto::constants::ATTR_ACP_TARGET_SCOPE |
kanidm_proto::constants::ATTR_ACP_RECEIVER
=> {
valueset::from_value_iter(
vs.into_iter().map(|v| Value::new_json_filter_s(v.as_str())
.unwrap_or_else(|| {
warn!("WARNING: Allowing syntax incorrect attribute to be presented UTF8 string");
Value::new_utf8(v)
})
)
)
}
kanidm_proto::constants::ATTR_DISPLAYNAME | kanidm_proto::constants::ATTR_DESCRIPTION | kanidm_proto::constants::ATTR_DOMAIN_DISPLAY_NAME => {
valueset::from_value_iter(
vs.into_iter().map(Value::new_utf8)
)
}
kanidm_proto::constants::ATTR_SPN => {
valueset::from_value_iter(
vs.into_iter().map(|v| {
Value::new_spn_parse(v.as_str())
.unwrap_or_else(|| {
warn!("WARNING: Allowing syntax incorrect SPN attribute to be presented UTF8 string");
Value::new_utf8(v)
})
})
)
}
kanidm_proto::constants::ATTR_GIDNUMBER |
kanidm_proto::constants::ATTR_VERSION => {
valueset::from_value_iter(
vs.into_iter().map(|v| {
Value::new_uint32_str(v.as_str())
.unwrap_or_else(|| {
warn!("WARNING: Allowing syntax incorrect UINT32 attribute to be presented UTF8 string");
Value::new_utf8(v)
})
})
)
}
kanidm_proto::constants::ATTR_DOMAIN_TOKEN_KEY |
kanidm_proto::constants::ATTR_FERNET_PRIVATE_KEY_STR => {
valueset::from_value_iter(
vs.into_iter().map(|v| Value::new_secret_str(&v))
)
}
kanidm_proto::constants::ATTR_ES256_PRIVATE_KEY_DER |
kanidm_proto::constants::ATTR_PRIVATE_COOKIE_KEY => {
valueset::from_value_iter(
vs.into_iter().map(|v| Value::new_privatebinary_base64(&v))
)
}
ia => {
error!("WARNING: Allowing invalid attribute {} to be interpreted as UTF8 string. YOU MAY ENCOUNTER ODD BEHAVIOUR!!!", ia);
valueset::from_value_iter(
vs.into_iter().map(Value::new_utf8)
)
}
}
.expect("Failed to convert value from string");
Some((attr, vv))
}
})
.collect();
// return the entry!
Entry {
valid: EntryInit,
state: EntryNew,
attrs: x,
}
}
/// Assign the Change Identifier to this Entry, allowing it to be modified and then /// Assign the Change Identifier to this Entry, allowing it to be modified and then
/// written to the `Backend` /// written to the `Backend`
pub fn assign_cid( pub fn assign_cid(

View file

@ -205,20 +205,6 @@ impl SearchEvent {
}) })
} }
/// ⚠️ - Bypass the schema state machine and force the filter to be considered valid.
/// This is a TEST ONLY method and will never be exposed in production.
#[cfg(test)]
pub fn new_impersonate_entry_ser(e: &str, filter: Filter<FilterInvalid>) -> Self {
// Just impersonate the account with no filter changes.
let ei: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(e);
SearchEvent {
ident: Identity::from_impersonate_entry_readonly(Arc::new(ei.into_sealed_committed())),
filter: filter.clone().into_valid(),
filter_orig: filter.into_valid(),
attrs: None,
}
}
/// ⚠️ - Bypass the schema state machine and force the filter to be considered valid. /// ⚠️ - Bypass the schema state machine and force the filter to be considered valid.
/// This is a TEST ONLY method and will never be exposed in production. /// This is a TEST ONLY method and will never be exposed in production.
#[cfg(test)] #[cfg(test)]
@ -372,17 +358,6 @@ impl CreateEvent {
} }
} }
/// ⚠️ - Use an unsafe entry impersonation method.
/// This is a TEST ONLY method and will never be exposed in production.
#[cfg(test)]
pub fn new_impersonate_entry_ser(e: &str, entries: Vec<Entry<EntryInit, EntryNew>>) -> Self {
let ei: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(e);
CreateEvent {
ident: Identity::from_impersonate_entry_readwrite(Arc::new(ei.into_sealed_committed())),
entries,
}
}
#[cfg(test)] #[cfg(test)]
pub fn new_impersonate_identity( pub fn new_impersonate_identity(
ident: Identity, ident: Identity,
@ -501,18 +476,6 @@ impl DeleteEvent {
} }
} }
/// ⚠️ - Bypass the schema state machine and force the filter to be considered valid.
/// This is a TEST ONLY method and will never be exposed in production.
#[cfg(test)]
pub fn new_impersonate_entry_ser(e: &str, filter: Filter<FilterInvalid>) -> Self {
let ei: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(e);
DeleteEvent {
ident: Identity::from_impersonate_entry_readwrite(Arc::new(ei.into_sealed_committed())),
filter: filter.clone().into_valid(),
filter_orig: filter.into_valid(),
}
}
/// ⚠️ - Bypass the schema state machine and force the filter to be considered valid. /// ⚠️ - Bypass the schema state machine and force the filter to be considered valid.
/// This is a TEST ONLY method and will never be exposed in production. /// This is a TEST ONLY method and will never be exposed in production.
#[cfg(test)] #[cfg(test)]

View file

@ -2,7 +2,7 @@
//! which is used to process authentication, store identities and enforce access controls. //! which is used to process authentication, store identities and enforce access controls.
#![deny(warnings)] #![deny(warnings)]
#![allow(deprecated)] #![deny(deprecated)]
#![recursion_limit = "512"] #![recursion_limit = "512"]
#![warn(unused_extern_crates)] #![warn(unused_extern_crates)]
// Enable some groups of clippy lints. // Enable some groups of clippy lints.

View file

@ -350,15 +350,14 @@ mod tests {
fn test_pre_create_no_uuid() { fn test_pre_create_no_uuid() {
let preload: Vec<Entry<EntryInit, EntryNew>> = Vec::with_capacity(0); let preload: Vec<Entry<EntryInit, EntryNew>> = Vec::with_capacity(0);
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let e = entry_init!(
r#"{ (Attribute::Class, EntryClass::Person.to_value()),
"attrs": { (Attribute::Class, EntryClass::Account.to_value()),
"class": ["person", "account"], (Attribute::Name, Value::new_iname("testperson")),
"name": ["testperson"], (
"description": ["testperson"], Attribute::DisplayName,
"displayname": ["testperson"] Value::Utf8("Test Person".to_string())
} )
}"#,
); );
let create = vec![e]; let create = vec![e];
@ -386,16 +385,15 @@ mod tests {
fn test_pre_create_uuid_invalid() { fn test_pre_create_uuid_invalid() {
let preload: Vec<Entry<EntryInit, EntryNew>> = Vec::with_capacity(0); let preload: Vec<Entry<EntryInit, EntryNew>> = Vec::with_capacity(0);
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let e = entry_init!(
r#"{ (Attribute::Class, EntryClass::Person.to_value()),
"attrs": { (Attribute::Class, EntryClass::Account.to_value()),
"class": ["person", "account"], (Attribute::Name, Value::new_iname("testperson")),
"name": ["testperson"], (
"description": ["testperson"], Attribute::DisplayName,
"displayname": ["testperson"], Value::Utf8("Test Person".to_string())
"uuid": ["xxxxxx"] ),
} (Attribute::Uuid, Value::Utf8("xxxxxx".to_string()))
}"#,
); );
let create = vec![e]; let create = vec![e];
@ -416,16 +414,18 @@ mod tests {
fn test_pre_create_uuid_empty() { fn test_pre_create_uuid_empty() {
let preload: Vec<Entry<EntryInit, EntryNew>> = Vec::with_capacity(0); let preload: Vec<Entry<EntryInit, EntryNew>> = Vec::with_capacity(0);
let mut e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let mut e = entry_init!(
r#"{ (Attribute::Class, EntryClass::Person.to_value()),
"attrs": { (Attribute::Class, EntryClass::Account.to_value()),
"class": ["person", "account"], (Attribute::Name, Value::new_iname("testperson")),
"name": ["testperson"], (
"description": ["testperson"], Attribute::DisplayName,
"displayname": ["testperson"], Value::Utf8("Test Person".to_string())
"uuid": ["79724141-3603-4060-b6bb-35c72772611d"] ),
} (
}"#, Attribute::Uuid,
Value::Uuid(uuid::uuid!("79724141-3603-4060-b6bb-35c72772611d"))
)
); );
let vs = e.get_ava_mut(Attribute::Uuid).unwrap(); let vs = e.get_ava_mut(Attribute::Uuid).unwrap();
@ -449,16 +449,18 @@ mod tests {
fn test_pre_create_uuid_valid() { fn test_pre_create_uuid_valid() {
let preload: Vec<Entry<EntryInit, EntryNew>> = Vec::with_capacity(0); let preload: Vec<Entry<EntryInit, EntryNew>> = Vec::with_capacity(0);
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let e = entry_init!(
r#"{ (Attribute::Class, EntryClass::Person.to_value()),
"attrs": { (Attribute::Class, EntryClass::Account.to_value()),
"class": ["person", "account"], (Attribute::Name, Value::new_iname("testperson")),
"name": ["testperson"], (
"description": ["testperson"], Attribute::DisplayName,
"displayname": ["testperson"], Value::Utf8("Test Person".to_string())
"uuid": ["79724141-3603-4060-b6bb-35c72772611d"] ),
} (
}"#, Attribute::Uuid,
Value::Uuid(uuid::uuid!("79724141-3603-4060-b6bb-35c72772611d"))
)
); );
let create = vec![e]; let create = vec![e];
@ -488,16 +490,22 @@ mod tests {
fn test_pre_create_uuid_valid_multi() { fn test_pre_create_uuid_valid_multi() {
let preload: Vec<Entry<EntryInit, EntryNew>> = Vec::with_capacity(0); let preload: Vec<Entry<EntryInit, EntryNew>> = Vec::with_capacity(0);
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let e = entry_init!(
r#"{ (Attribute::Class, EntryClass::Person.to_value()),
"attrs": { (Attribute::Class, EntryClass::Account.to_value()),
"class": ["person"], (Attribute::Name, Value::new_iname("testperson")),
"name": ["testperson"], (
"description": ["testperson"], Attribute::DisplayName,
"displayname": ["testperson"], Value::Utf8("Test Person".to_string())
"uuid": ["79724141-3603-4060-b6bb-35c72772611d", "79724141-3603-4060-b6bb-35c72772611e"] ),
} (
}"#, Attribute::Uuid,
Value::Uuid(uuid::uuid!("79724141-3603-4060-b6bb-35c72772611e"))
),
(
Attribute::Uuid,
Value::Uuid(uuid::uuid!("79724141-3603-4060-b6bb-35c72772611d"))
)
); );
let create = vec![e]; let create = vec![e];
@ -523,16 +531,18 @@ mod tests {
// to ensure we always have a name space to draw from? // to ensure we always have a name space to draw from?
#[test] #[test]
fn test_pre_create_uuid_exist() { fn test_pre_create_uuid_exist() {
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let e = entry_init!(
r#"{ (Attribute::Class, EntryClass::Person.to_value()),
"attrs": { (Attribute::Class, EntryClass::Account.to_value()),
"class": ["account", "person"], (Attribute::Name, Value::new_iname("testperson")),
"name": ["testperson"], (
"description": ["testperson"], Attribute::DisplayName,
"displayname": ["testperson"], Value::Utf8("Test Person".to_string())
"uuid": ["79724141-3603-4060-b6bb-35c72772611d"] ),
} (
}"#, Attribute::Uuid,
Value::Uuid(uuid::uuid!("79724141-3603-4060-b6bb-35c72772611d"))
)
); );
let create = vec![e.clone()]; let create = vec![e.clone()];
@ -554,29 +564,21 @@ mod tests {
// Test adding two entries with the same uuid // Test adding two entries with the same uuid
let preload: Vec<Entry<EntryInit, EntryNew>> = Vec::with_capacity(0); let preload: Vec<Entry<EntryInit, EntryNew>> = Vec::with_capacity(0);
let ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let ea = entry_init!(
r#"{ (Attribute::Class, EntryClass::Person.to_value()),
"attrs": { (Attribute::Class, EntryClass::Account.to_value()),
"class": ["person"], (Attribute::Name, Value::new_iname("testperson")),
"name": ["testperson_a"], (
"description": ["testperson"], Attribute::DisplayName,
"displayname": ["testperson"], Value::Utf8("Test Person".to_string())
"uuid": ["79724141-3603-4060-b6bb-35c72772611d"] ),
} (
}"#, Attribute::Uuid,
Value::Uuid(uuid::uuid!("79724141-3603-4060-b6bb-35c72772611d"))
)
); );
let eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let eb = ea.clone();
r#"{
"attrs": {
"class": ["person"],
"name": ["testperson_a"],
"description": ["testperson"],
"displayname": ["testperson"],
"uuid": ["79724141-3603-4060-b6bb-35c72772611d"]
}
}"#,
);
let create = vec![ea, eb]; let create = vec![ea, eb];
@ -595,15 +597,13 @@ mod tests {
#[test] #[test]
fn test_modify_uuid_present() { fn test_modify_uuid_present() {
// Add another uuid to a type // Add another uuid to a type
let ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let ea = entry_init!(
r#"{ (Attribute::Class, EntryClass::Group.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("testgroup_a")),
"class": ["group"], (
"name": ["testgroup_a"], Attribute::Uuid,
"description": ["testgroup"], Value::Uuid(uuid::uuid!("79724141-3603-4060-b6bb-35c72772611d"))
"uuid": ["d2b496bd-8493-47b7-8142-f568b5cf47ee"] )
}
}"#,
); );
let preload = vec![ea]; let preload = vec![ea];
@ -628,15 +628,13 @@ mod tests {
#[test] #[test]
fn test_modify_uuid_removed() { fn test_modify_uuid_removed() {
// Test attempting to remove a uuid // Test attempting to remove a uuid
let ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let ea = entry_init!(
r#"{ (Attribute::Class, EntryClass::Group.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("testgroup_a")),
"class": ["group"], (
"name": ["testgroup_a"], Attribute::Uuid,
"description": ["testgroup"], Value::Uuid(uuid::uuid!("79724141-3603-4060-b6bb-35c72772611d"))
"uuid": ["d2b496bd-8493-47b7-8142-f568b5cf47ee"] )
}
}"#,
); );
let preload = vec![ea]; let preload = vec![ea];
@ -661,15 +659,13 @@ mod tests {
#[test] #[test]
fn test_modify_uuid_purged() { fn test_modify_uuid_purged() {
// Test attempting to purge uuid // Test attempting to purge uuid
let ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let ea = entry_init!(
r#"{ (Attribute::Class, EntryClass::Group.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("testgroup_a")),
"class": ["group"], (
"name": ["testgroup_a"], Attribute::Uuid,
"description": ["testgroup"], Value::Uuid(uuid::uuid!("79724141-3603-4060-b6bb-35c72772611d"))
"uuid": ["d2b496bd-8493-47b7-8142-f568b5cf47ee"] )
}
}"#,
); );
let preload = vec![ea]; let preload = vec![ea];
@ -695,16 +691,15 @@ mod tests {
// up testing this every time we run :P // up testing this every time we run :P
let preload = PRELOAD.clone(); let preload = PRELOAD.clone();
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let e = entry_init!(
r#"{ (Attribute::Class, EntryClass::Person.to_value()),
"attrs": { (Attribute::Class, EntryClass::System.to_value()),
"class": ["person", "system"], (Attribute::Name, Value::new_iname("testperson")),
"name": ["testperson"], (Attribute::DisplayName, Value::new_iname("testperson")),
"uuid": ["00000000-0000-0000-0000-f0f0f0f0f0f0"], (
"description": ["testperson"], Attribute::Uuid,
"displayname": ["testperson"] Value::Uuid(uuid::uuid!("00000000-0000-0000-0000-f0f0f0f0f0f0"))
} )
}"#,
); );
let create = vec![e]; let create = vec![e];
@ -727,16 +722,15 @@ mod tests {
// up testing this every time we run :P // up testing this every time we run :P
let preload = PRELOAD.clone(); let preload = PRELOAD.clone();
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let e = entry_init!(
r#"{ (Attribute::Class, EntryClass::Person.to_value()),
"attrs": { (Attribute::Class, EntryClass::System.to_value()),
"class": ["person", "system"], (Attribute::Name, Value::new_iname("testperson")),
"name": ["testperson"], (Attribute::DisplayName, Value::new_iname("testperson")),
"uuid": ["00000000-0000-0000-0000-ffff00000088"], (
"description": ["testperson"], Attribute::Uuid,
"displayname": ["testperson"] Value::Uuid(uuid::uuid!("00000000-0000-0000-0000-f0f0f0f0f0f0"))
} )
}"#,
); );
let create = vec![e]; let create = vec![e];
@ -757,16 +751,15 @@ mod tests {
// Test that internal create of "does not exist" will fail. // Test that internal create of "does not exist" will fail.
let preload = Vec::with_capacity(0); let preload = Vec::with_capacity(0);
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let e = entry_init!(
r#"{ (Attribute::Class, EntryClass::Person.to_value()),
"attrs": { (Attribute::Class, EntryClass::System.to_value()),
"class": ["person", "system"], (Attribute::Name, Value::new_iname("testperson")),
"name": ["testperson"], (Attribute::DisplayName, Value::new_iname("testperson")),
"uuid": ["00000000-0000-0000-0000-fffffffffffe"], (
"description": ["testperson"], Attribute::Uuid,
"displayname": ["testperson"] Value::Uuid(uuid::uuid!("00000000-0000-0000-0000-fffffffffffe"))
} )
}"#,
); );
let create = vec![e]; let create = vec![e];

View file

@ -763,37 +763,32 @@ mod tests {
const UUID_C: &str = "cccccccc-9b01-423f-9ba6-51aa4bbd5dd2"; const UUID_C: &str = "cccccccc-9b01-423f-9ba6-51aa4bbd5dd2";
const UUID_D: &str = "dddddddd-2ab3-48e3-938d-1b4754cd2984"; const UUID_D: &str = "dddddddd-2ab3-48e3-938d-1b4754cd2984";
const EA: &str = r#"{ lazy_static! {
"attrs": { static ref EA: EntryInitNew = entry_init!(
"class": ["group", "memberof"], (Attribute::Class, EntryClass::Group.to_value()),
"name": ["testgroup_a"], (Attribute::Class, EntryClass::MemberOf.to_value()),
"uuid": ["aaaaaaaa-f82e-4484-a407-181aa03bda5c"] (Attribute::Name, Value::new_iname("testgroup_a")),
} (Attribute::Uuid, Value::Uuid(uuid::uuid!(UUID_A)))
}"#; );
static ref EB: EntryInitNew = entry_init!(
const EB: &str = r#"{ (Attribute::Class, EntryClass::Group.to_value()),
"attrs": { (Attribute::Class, EntryClass::MemberOf.to_value()),
"class": ["group", "memberof"], (Attribute::Name, Value::new_iname("testgroup_b")),
"name": ["testgroup_b"], (Attribute::Uuid, Value::Uuid(uuid::uuid!(UUID_B)))
"uuid": ["bbbbbbbb-2438-4384-9891-48f4c8172e9b"] );
} static ref EC: EntryInitNew = entry_init!(
}"#; (Attribute::Class, EntryClass::Group.to_value()),
(Attribute::Class, EntryClass::MemberOf.to_value()),
const EC: &str = r#"{ (Attribute::Name, Value::new_iname("testgroup_c")),
"attrs": { (Attribute::Uuid, Value::Uuid(uuid::uuid!(UUID_C)))
"class": ["group", "memberof"], );
"name": ["testgroup_c"], static ref ED: EntryInitNew = entry_init!(
"uuid": ["cccccccc-9b01-423f-9ba6-51aa4bbd5dd2"] (Attribute::Class, EntryClass::Group.to_value()),
} (Attribute::Class, EntryClass::MemberOf.to_value()),
}"#; (Attribute::Name, Value::new_iname("testgroup_d")),
(Attribute::Uuid, Value::Uuid(uuid::uuid!(UUID_D)))
const ED: &str = r#"{ );
"attrs": { }
"class": ["group", "memberof"],
"name": ["testgroup_d"],
"uuid": ["dddddddd-2ab3-48e3-938d-1b4754cd2984"]
}
}"#;
macro_rules! assert_memberof_int { macro_rules! assert_memberof_int {
( (
@ -856,9 +851,8 @@ mod tests {
#[test] #[test]
fn test_create_mo_single() { fn test_create_mo_single() {
// A -> B // A -> B
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let eb = EB.clone();
let eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB);
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
@ -884,11 +878,11 @@ mod tests {
#[test] #[test]
fn test_create_mo_nested() { fn test_create_mo_nested() {
// A -> B -> C // A -> B -> C
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let mut eb = EB.clone();
let ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC); let ec = EC.clone();
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
eb.add_ava(Attribute::Member, Value::new_refer_s(UUID_C).unwrap()); eb.add_ava(Attribute::Member, Value::new_refer_s(UUID_C).unwrap());
@ -935,11 +929,11 @@ mod tests {
fn test_create_mo_cycle() { fn test_create_mo_cycle() {
// A -> B -> C - // A -> B -> C -
// ^-----------/ // ^-----------/
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let mut eb = EB.clone();
let mut ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC); let mut ec = EC.clone();
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
eb.add_ava(Attribute::Member, Value::new_refer_s(UUID_C).unwrap()); eb.add_ava(Attribute::Member, Value::new_refer_s(UUID_C).unwrap());
@ -987,13 +981,13 @@ mod tests {
// A -> B -> C --> D - // A -> B -> C --> D -
// ^-----------/ / // ^-----------/ /
// |---------------/ // |---------------/
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let mut eb = EB.clone();
let mut ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC); let mut ec = EC.clone();
let mut ed: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(ED); let mut ed = ED.clone();
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
eb.add_ava(Attribute::Member, Value::new_refer_s(UUID_C).unwrap()); eb.add_ava(Attribute::Member, Value::new_refer_s(UUID_C).unwrap());
@ -1061,9 +1055,8 @@ mod tests {
// A B // A B
// Add member // Add member
// A -> B // A -> B
let ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let ea = EA.clone();
let eb = EB.clone();
let eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB);
let preload = vec![ea, eb]; let preload = vec![ea, eb];
run_modify_test!( run_modify_test!(
@ -1096,11 +1089,9 @@ mod tests {
// A B -> C // A B -> C
// Add member A -> B // Add member A -> B
// A -> B -> C // A -> B -> C
let ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let ea = EA.clone();
let mut eb = EB.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let ec = EC.clone();
let ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC);
eb.add_ava(Attribute::Member, Value::new_refer_s(UUID_C).unwrap()); eb.add_ava(Attribute::Member, Value::new_refer_s(UUID_C).unwrap());
@ -1153,11 +1144,9 @@ mod tests {
// A -> B C // A -> B C
// Add member B -> C // Add member B -> C
// A -> B -> C // A -> B -> C
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let eb = EB.clone();
let eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let ec = EC.clone();
let ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC);
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
@ -1212,11 +1201,9 @@ mod tests {
// Add member C -> A // Add member C -> A
// A -> B -> C - // A -> B -> C -
// ^-----------/ // ^-----------/
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb = EB.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let ec = EC.clone();
let ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC);
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
eb.add_ava(Attribute::Member, Value::new_refer_s(UUID_C).unwrap()); eb.add_ava(Attribute::Member, Value::new_refer_s(UUID_C).unwrap());
@ -1276,13 +1263,10 @@ mod tests {
// A -> B -> C --> D - // A -> B -> C --> D -
// ^-----------/ / // ^-----------/ /
// |---------------/ // |---------------/
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb = EB.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let mut ec = EC.clone();
let ed = ED.clone();
let mut ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC);
let ed: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(ED);
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
eb.add_ava(Attribute::Member, Value::new_refer_s(UUID_C).unwrap()); eb.add_ava(Attribute::Member, Value::new_refer_s(UUID_C).unwrap());
@ -1353,9 +1337,8 @@ mod tests {
// A -> B // A -> B
// remove member A -> B // remove member A -> B
// A B // A B
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb = EB.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB);
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
eb.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap()); eb.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap());
@ -1391,11 +1374,9 @@ mod tests {
// A -> B -> C // A -> B -> C
// Remove A -> B // Remove A -> B
// A B -> C // A B -> C
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb = EB.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let mut ec = EC.clone();
let mut ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC);
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
eb.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap()); eb.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap());
@ -1451,11 +1432,9 @@ mod tests {
// A -> B -> C // A -> B -> C
// Remove B -> C // Remove B -> C
// A -> B C // A -> B C
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb = EB.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let mut ec = EC.clone();
let mut ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC);
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
eb.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap()); eb.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap());
@ -1513,11 +1492,9 @@ mod tests {
// ^-----------/ // ^-----------/
// Remove C -> A // Remove C -> A
// A -> B -> C // A -> B -> C
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb = EB.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let mut ec = EC.clone();
let mut ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC);
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
ea.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_C).unwrap()); ea.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_C).unwrap());
@ -1590,13 +1567,10 @@ mod tests {
// A -> B -> C D - // A -> B -> C D -
// ^ / // ^ /
// |---------------/ // |---------------/
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb = EB.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let mut ec = EC.clone();
let mut ed = ED.clone();
let mut ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC);
let mut ed: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(ED);
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
ea.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_D).unwrap()); ea.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_D).unwrap());
@ -1692,9 +1666,8 @@ mod tests {
#[test] #[test]
fn test_delete_mo_simple() { fn test_delete_mo_simple() {
// X -> B // X -> B
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb = EB.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB);
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
eb.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap()); eb.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap());
@ -1723,11 +1696,9 @@ mod tests {
#[test] #[test]
fn test_delete_mo_nested_head() { fn test_delete_mo_nested_head() {
// X -> B -> C // X -> B -> C
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb = EB.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let mut ec = EC.clone();
let mut ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC);
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
eb.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap()); eb.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap());
@ -1770,11 +1741,9 @@ mod tests {
#[test] #[test]
fn test_delete_mo_nested_branch() { fn test_delete_mo_nested_branch() {
// A -> X -> C // A -> X -> C
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb = EB.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let mut ec = EC.clone();
let mut ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC);
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
eb.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap()); eb.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap());
@ -1818,11 +1787,9 @@ mod tests {
fn test_delete_mo_cycle() { fn test_delete_mo_cycle() {
// X -> B -> C - // X -> B -> C -
// ^-----------/ // ^-----------/
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb = EB.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let mut ec = EC.clone();
let mut ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC);
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
ea.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap()); ea.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap());
@ -1875,13 +1842,10 @@ mod tests {
// A -> X -> C --> D - // A -> X -> C --> D -
// ^-----------/ / // ^-----------/ /
// |---------------/ // |---------------/
let mut ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EA); let mut ea = EA.clone();
let mut eb = EB.clone();
let mut eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EB); let mut ec = EC.clone();
let mut ed = ED.clone();
let mut ec: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(EC);
let mut ed: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(ED);
ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap()); ea.add_ava(Attribute::Member, Value::new_refer_s(UUID_B).unwrap());
ea.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap()); ea.add_ava(Attribute::MemberOf, Value::new_refer_s(UUID_A).unwrap());

View file

@ -461,15 +461,15 @@ mod tests {
#[test] #[test]
fn test_pre_create_deny() { fn test_pre_create_deny() {
// Test creating with class: system is rejected. // Test creating with class: system is rejected.
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let e = entry_init!(
r#"{ (Attribute::Class, EntryClass::Account.to_value()),
"attrs": { (Attribute::Class, EntryClass::Person.to_value()),
"class": ["account", "person", "system"], (Attribute::Class, EntryClass::System.to_value()),
"name": ["testperson"], (Attribute::Name, Value::new_iname("testperson")),
"description": ["testperson"], (
"displayname": ["testperson"] Attribute::DisplayName,
} Value::Utf8("testperson".to_string())
}"#, )
); );
let create = vec![e]; let create = vec![e];
@ -487,15 +487,15 @@ mod tests {
#[test] #[test]
fn test_pre_modify_system_deny() { fn test_pre_modify_system_deny() {
// Test modify of class to a system is denied // Test modify of class to a system is denied
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let e = entry_init!(
r#"{ (Attribute::Class, EntryClass::Account.to_value()),
"attrs": { (Attribute::Class, EntryClass::Person.to_value()),
"class": ["account", "person", "system"], (Attribute::Class, EntryClass::System.to_value()),
"name": ["testperson"], (Attribute::Name, Value::new_iname("testperson")),
"description": ["testperson"], (
"displayname": ["testperson"] Attribute::DisplayName,
} Value::Utf8("testperson".to_string())
}"#, )
); );
let mut preload = PRELOAD.clone(); let mut preload = PRELOAD.clone();
@ -519,15 +519,18 @@ mod tests {
fn test_pre_modify_class_add_deny() { fn test_pre_modify_class_add_deny() {
// Show that adding a system class is denied // Show that adding a system class is denied
// TODO: replace this with a `SchemaClass` object // TODO: replace this with a `SchemaClass` object
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let e = entry_init!(
r#"{ (Attribute::Class, EntryClass::Object.to_value()),
"attrs": { (Attribute::Class, EntryClass::ClassType.to_value()),
"class": ["object", "classtype"], (Attribute::ClassName, Value::new_iutf8("testclass")),
"classname": ["testclass"], (
"uuid": ["cfcae205-31c3-484b-8ced-667d1709c5e3"], Attribute::Uuid,
"description": ["Test Class"] Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
} ),
}"#, (
Attribute::Description,
Value::Utf8("class test".to_string())
)
); );
let mut preload = PRELOAD.clone(); let mut preload = PRELOAD.clone();
preload.push(e); preload.push(e);
@ -535,7 +538,10 @@ mod tests {
run_modify_test!( run_modify_test!(
Ok(()), Ok(()),
preload, preload,
filter!(f_eq(Attribute::ClassName, EntryClass::TestClass.into())), filter!(f_eq(
Attribute::ClassName,
PartialValue::new_iutf8("testclass")
)),
modlist!([ modlist!([
m_pres(Attribute::May, &Value::from(Attribute::Name)), m_pres(Attribute::May, &Value::from(Attribute::Name)),
m_pres(Attribute::Must, &Value::from(Attribute::Name)), m_pres(Attribute::Must, &Value::from(Attribute::Name)),
@ -549,15 +555,15 @@ mod tests {
#[test] #[test]
fn test_pre_delete_deny() { fn test_pre_delete_deny() {
// Test deleting with class: system is rejected. // Test deleting with class: system is rejected.
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let e = entry_init!(
r#"{ (Attribute::Class, EntryClass::Account.to_value()),
"attrs": { (Attribute::Class, EntryClass::Person.to_value()),
"class": ["account", "person", "system"], (Attribute::Class, EntryClass::System.to_value()),
"name": ["testperson"], (Attribute::Name, Value::new_iname("testperson")),
"description": ["testperson"], (
"displayname": ["testperson"] Attribute::DisplayName,
} Value::Utf8("testperson".to_string())
}"#, )
); );
let mut preload = PRELOAD.clone(); let mut preload = PRELOAD.clone();
@ -576,20 +582,19 @@ mod tests {
fn test_modify_domain() { fn test_modify_domain() {
// Can edit *my* domain_ssid and domain_name // Can edit *my* domain_ssid and domain_name
// Show that adding a system class is denied // Show that adding a system class is denied
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let e = entry_init!(
r#"{ (Attribute::Class, EntryClass::DomainInfo.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("domain_example.net.au")),
"class": ["domain_info"], (Attribute::Uuid, Value::Uuid(uuid::uuid!("96fd1112-28bc-48ae-9dda-5acb4719aaba"))),
"name": ["domain_example.net.au"], (
"uuid": ["96fd1112-28bc-48ae-9dda-5acb4719aaba"], Attribute::Description,
"domain_uuid": ["96fd1112-28bc-48ae-9dda-5acb4719aaba"], Value::new_utf8s("Demonstration of a remote domain's info being created for uuid generation in test_modify_domain")
"description": ["Demonstration of a remote domain's info being created for uuid generation in test_modify_domain"], ),
"domain_name": ["example.net.au"], (Attribute::DomainUuid, Value::Uuid(uuid::uuid!("96fd1112-28bc-48ae-9dda-5acb4719aaba"))),
"domain_display_name": ["example.net.au"], (Attribute::DomainName, Value::new_iname("example.net.au")),
"domain_ssid": ["Example_Wifi"], (Attribute::DomainDisplayName, Value::Utf8("example.net.au".to_string())),
"version": ["1"] (Attribute::DomainSsid, Value::Utf8("Example_Wifi".to_string())),
} (Attribute::Version, Value::Uint32(1))
}"#,
); );
let mut preload = PRELOAD.clone(); let mut preload = PRELOAD.clone();
@ -615,22 +620,21 @@ mod tests {
#[test] #[test]
fn test_ext_create_domain() { fn test_ext_create_domain() {
// can not add a domain_info type - note the lack of class: system // can not add a domain_info type - note the lack of class: system
let e = entry_init!(
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( (Attribute::Class, EntryClass::DomainInfo.to_value()),
r#"{ (Attribute::Name, Value::new_iname("domain_example.net.au")),
"attrs": { (Attribute::Uuid, Value::Uuid(uuid::uuid!("96fd1112-28bc-48ae-9dda-5acb4719aaba"))),
"class": ["domain_info"], (
"name": ["domain_example.net.au"], Attribute::Description,
"uuid": ["96fd1112-28bc-48ae-9dda-5acb4719aaba"], Value::new_utf8s("Demonstration of a remote domain's info being created for uuid generation in test_modify_domain")
"domain_uuid": ["96fd1112-28bc-48ae-9dda-5acb4719aaba"], ),
"description": ["Demonstration of a remote domain's info being created for uuid generation in test_ext_create_domain"], (Attribute::DomainUuid, Value::Uuid(uuid::uuid!("96fd1112-28bc-48ae-9dda-5acb4719aaba"))),
"domain_name": ["example.net.au"], (Attribute::DomainName, Value::new_iname("example.net.au")),
"domain_display_name": ["example.net.au"], (Attribute::DomainDisplayName, Value::Utf8("example.net.au".to_string())),
"domain_ssid": ["Example_Wifi"], (Attribute::DomainSsid, Value::Utf8("Example_Wifi".to_string())),
"version": ["1"] (Attribute::Version, Value::Uint32(1))
}
}"#,
); );
let create = vec![e]; let create = vec![e];
let preload = PRELOAD.clone(); let preload = PRELOAD.clone();
@ -646,20 +650,19 @@ mod tests {
#[test] #[test]
fn test_delete_domain() { fn test_delete_domain() {
// On the real thing we have a class: system, but to prove the point ... // On the real thing we have a class: system, but to prove the point ...
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let e = entry_init!(
r#"{ (Attribute::Class, EntryClass::DomainInfo.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("domain_example.net.au")),
"class": ["domain_info"], (Attribute::Uuid, Value::Uuid(uuid::uuid!("96fd1112-28bc-48ae-9dda-5acb4719aaba"))),
"name": ["domain_example.net.au"], (
"uuid": ["96fd1112-28bc-48ae-9dda-5acb4719aaba"], Attribute::Description,
"domain_uuid": ["96fd1112-28bc-48ae-9dda-5acb4719aaba"], Value::new_utf8s("Demonstration of a remote domain's info being created for uuid generation in test_modify_domain")
"description": ["Demonstration of a remote domain's info being created for uuid generation in test_delete_domain"], ),
"domain_name": ["example.net.au"], (Attribute::DomainUuid, Value::Uuid(uuid::uuid!("96fd1112-28bc-48ae-9dda-5acb4719aaba"))),
"domain_display_name": ["example.net.au"], (Attribute::DomainName, Value::new_iname("example.net.au")),
"domain_ssid": ["Example_Wifi"], (Attribute::DomainDisplayName, Value::Utf8("example.net.au".to_string())),
"version": ["1"] (Attribute::DomainSsid, Value::Utf8("Example_Wifi".to_string())),
} (Attribute::Version, Value::Uint32(1))
}"#,
); );
let mut preload = PRELOAD.clone(); let mut preload = PRELOAD.clone();

View file

@ -522,19 +522,16 @@ mod tests {
fn test_create_uuid_reference_self() { fn test_create_uuid_reference_self() {
let preload: Vec<Entry<EntryInit, EntryNew>> = Vec::with_capacity(0); let preload: Vec<Entry<EntryInit, EntryNew>> = Vec::with_capacity(0);
let e: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let id = uuid::uuid!("8cef42bc-2cac-43e4-96b3-8f54561885ca");
r#"{
"attrs": { let e_group = entry_init!(
"class": ["group"], (Attribute::Class, EntryClass::Group.to_value()),
"name": ["testgroup"], (Attribute::Name, Value::new_iname("testgroup")),
"description": ["testgroup"], (Attribute::Uuid, Value::Uuid(id)),
"uuid": ["8cef42bc-2cac-43e4-96b3-8f54561885ca"], (Attribute::Member, Value::Refer(id))
"member": ["8cef42bc-2cac-43e4-96b3-8f54561885ca"]
}
}"#,
); );
let create = vec![e]; let create = vec![e_group];
run_create_test!( run_create_test!(
Ok(()), Ok(()),
@ -556,25 +553,18 @@ mod tests {
// Modify references a different object - allow // Modify references a different object - allow
#[test] #[test]
fn test_modify_uuid_reference_exist() { fn test_modify_uuid_reference_exist() {
let ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let ea = entry_init!(
r#"{ (Attribute::Class, EntryClass::Group.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("testgroup_a")),
"class": ["group"], (
"name": ["testgroup_a"], Attribute::Uuid,
"description": ["testgroup"], Value::Uuid(uuid::uuid!(TEST_TESTGROUP_A_UUID))
"uuid": ["d2b496bd-8493-47b7-8142-f568b5cf47ee"] )
}
}"#,
); );
let eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let eb = entry_init!(
r#"{ (Attribute::Class, EntryClass::Group.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("testgroup_b"))
"class": ["group"],
"name": ["testgroup_b"],
"description": ["testgroup"]
}
}"#,
); );
let preload = vec![ea, eb]; let preload = vec![ea, eb];
@ -599,14 +589,9 @@ mod tests {
// Modify reference something that doesn't exist - must be rejected // Modify reference something that doesn't exist - must be rejected
#[test] #[test]
fn test_modify_uuid_reference_not_exist() { fn test_modify_uuid_reference_not_exist() {
let eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let eb = entry_init!(
r#"{ (Attribute::Class, EntryClass::Group.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("testgroup_b"))
"class": ["group"],
"name": ["testgroup_b"],
"description": ["testgroup"]
}
}"#,
); );
let preload = vec![eb]; let preload = vec![eb];
@ -634,25 +619,18 @@ mod tests {
// we fail. // we fail.
#[test] #[test]
fn test_modify_uuid_reference_partial_not_exist() { fn test_modify_uuid_reference_partial_not_exist() {
let ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let ea = entry_init!(
r#"{ (Attribute::Class, EntryClass::Group.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("testgroup_a")),
"class": ["group"], (
"name": ["testgroup_a"], Attribute::Uuid,
"description": ["testgroup"], Value::Uuid(uuid::uuid!(TEST_TESTGROUP_A_UUID))
"uuid": ["d2b496bd-8493-47b7-8142-f568b5cf47ee"] )
}
}"#,
); );
let eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let eb = entry_init!(
r#"{ (Attribute::Class, EntryClass::Group.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("testgroup_b"))
"class": ["group"],
"name": ["testgroup_b"],
"description": ["testgroup"]
}
}"#,
); );
let preload = vec![ea, eb]; let preload = vec![ea, eb];
@ -682,26 +660,22 @@ mod tests {
// Modify removes the reference to an entry // Modify removes the reference to an entry
#[test] #[test]
fn test_modify_remove_referee() { fn test_modify_remove_referee() {
let ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let ea = entry_init!(
r#"{ (Attribute::Class, EntryClass::Group.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("testgroup_a")),
"class": ["group"], (
"name": ["testgroup_a"], Attribute::Uuid,
"description": ["testgroup"], Value::Uuid(uuid::uuid!(TEST_TESTGROUP_A_UUID))
"uuid": ["d2b496bd-8493-47b7-8142-f568b5cf47ee"] )
}
}"#,
); );
let eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let eb = entry_init!(
r#"{ (Attribute::Class, EntryClass::Group.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("testgroup_b")),
"class": ["group"], (
"name": ["testgroup_b"], Attribute::Member,
"description": ["testgroup"], Value::Refer(uuid::uuid!(TEST_TESTGROUP_A_UUID))
"member": ["d2b496bd-8493-47b7-8142-f568b5cf47ee"] )
}
}"#,
); );
let preload = vec![ea, eb]; let preload = vec![ea, eb];
@ -723,15 +697,13 @@ mod tests {
// Modify adds reference to self - allow // Modify adds reference to self - allow
#[test] #[test]
fn test_modify_uuid_reference_self() { fn test_modify_uuid_reference_self() {
let ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let ea = entry_init!(
r#"{ (Attribute::Class, EntryClass::Group.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("testgroup_a")),
"class": ["group"], (
"name": ["testgroup_a"], Attribute::Uuid,
"description": ["testgroup"], Value::Uuid(uuid::uuid!(TEST_TESTGROUP_A_UUID))
"uuid": ["d2b496bd-8493-47b7-8142-f568b5cf47ee"] )
}
}"#,
); );
let preload = vec![ea]; let preload = vec![ea];
@ -756,25 +728,18 @@ mod tests {
// Test that deleted entries can not be referenced // Test that deleted entries can not be referenced
#[test] #[test]
fn test_modify_reference_deleted() { fn test_modify_reference_deleted() {
let ea: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let ea = entry_init!(
r#"{ (Attribute::Class, EntryClass::Group.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("testgroup_a")),
"class": ["group"], (
"name": ["testgroup_a"], Attribute::Uuid,
"description": ["testgroup"], Value::Uuid(uuid::uuid!(TEST_TESTGROUP_A_UUID))
"uuid": ["d2b496bd-8493-47b7-8142-f568b5cf47ee"] )
}
}"#,
); );
let eb: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str( let eb = entry_init!(
r#"{ (Attribute::Class, EntryClass::Group.to_value()),
"attrs": { (Attribute::Name, Value::new_iname("testgroup_b"))
"class": ["group"],
"name": ["testgroup_b"],
"description": ["testgroup"]
}
}"#,
); );
let preload = vec![ea, eb]; let preload = vec![ea, eb];

View file

@ -2332,8 +2332,7 @@ mod tests {
$e:expr, $e:expr,
$type:ty $type:ty
) => {{ ) => {{
let e1: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str($e); let ev1 = $e.into_sealed_committed();
let ev1 = e1.into_sealed_committed();
let r1 = <$type>::try_from(&ev1); let r1 = <$type>::try_from(&ev1);
assert!(r1.is_ok()); assert!(r1.is_ok());
@ -2345,8 +2344,7 @@ mod tests {
$e:expr, $e:expr,
$type:ty $type:ty
) => {{ ) => {{
let e1: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str($e); let ev1 = $e.into_sealed_committed();
let ev1 = e1.into_sealed_committed();
let r1 = <$type>::try_from(&ev1); let r1 = <$type>::try_from(&ev1);
assert!(r1.is_err()); assert!(r1.is_err());
@ -2356,110 +2354,160 @@ mod tests {
#[test] #[test]
fn test_schema_attribute_from_entry() { fn test_schema_attribute_from_entry() {
sch_from_entry_err!( sch_from_entry_err!(
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "attributetype"], (Attribute::Class, EntryClass::AttributeType.to_value()),
"attributename": ["schema_attr_test"], (
"unique": ["false"], Attribute::AttributeName,
"uuid": ["66c68b2f-d02c-4243-8013-7946e40fe321"] Value::new_iutf8("schema_attr_test")
} ),
}"#, (
Attribute::Uuid,
Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
),
(Attribute::Unique, Value::Bool(false))
),
SchemaAttribute SchemaAttribute
); );
sch_from_entry_err!( sch_from_entry_err!(
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "attributetype"], (Attribute::Class, EntryClass::AttributeType.to_value()),
"attributename": ["schema_attr_test"], (
"uuid": ["66c68b2f-d02c-4243-8013-7946e40fe321"], Attribute::AttributeName,
"multivalue": ["false"], Value::new_iutf8("schema_attr_test")
"unique": ["false"], ),
"index": ["EQUALITY"], (
"syntax": ["UTF8STRING"] Attribute::Uuid,
} Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
}"#, ),
(Attribute::MultiValue, Value::Bool(false)),
(Attribute::Unique, Value::Bool(false)),
(Attribute::Syntax, Value::Syntax(SyntaxType::Utf8String)),
(Attribute::Index, Value::Index(IndexType::Equality))
),
SchemaAttribute SchemaAttribute
); );
sch_from_entry_err!( sch_from_entry_err!(
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "attributetype"], (Attribute::Class, EntryClass::AttributeType.to_value()),
"attributename": ["schema_attr_test"], (
"uuid": ["66c68b2f-d02c-4243-8013-7946e40fe321"], Attribute::AttributeName,
"description": ["Test attr parsing"], Value::new_iutf8("schema_attr_test")
"multivalue": ["htouaoeu"], ),
"unique": ["false"], (
"index": ["EQUALITY"], Attribute::Uuid,
"syntax": ["UTF8STRING"] Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
} ),
}"#, (
Attribute::Description,
Value::Utf8("Test attr parsing".to_string())
),
(Attribute::MultiValue, Value::Utf8("htouaoeu".to_string())),
(Attribute::Unique, Value::Bool(false)),
(Attribute::Syntax, Value::Syntax(SyntaxType::Utf8String)),
(Attribute::Index, Value::Index(IndexType::Equality))
),
SchemaAttribute SchemaAttribute
); );
sch_from_entry_err!( sch_from_entry_err!(
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "attributetype"], (Attribute::Class, EntryClass::AttributeType.to_value()),
"attributename": ["schema_attr_test"], (
"uuid": ["66c68b2f-d02c-4243-8013-7946e40fe321"], Attribute::AttributeName,
"description": ["Test attr parsing"], Value::new_iutf8("schema_attr_test")
"multivalue": ["false"], ),
"unique": ["false"], (
"index": ["NTEHNOU"], Attribute::Uuid,
"syntax": ["UTF8STRING"] Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
} ),
}"#, (
Attribute::Description,
Value::Utf8("Test attr parsing".to_string())
),
(Attribute::MultiValue, Value::Bool(false)),
(Attribute::Unique, Value::Bool(false)),
(Attribute::Syntax, Value::Syntax(SyntaxType::Utf8String)),
(Attribute::Index, Value::Utf8("NTEHNOU".to_string()))
),
SchemaAttribute SchemaAttribute
); );
sch_from_entry_err!( sch_from_entry_err!(
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "attributetype"], (Attribute::Class, EntryClass::AttributeType.to_value()),
"attributename": ["schema_attr_test"], (
"uuid": ["66c68b2f-d02c-4243-8013-7946e40fe321"], Attribute::AttributeName,
"description": ["Test attr parsing"], Value::new_iutf8("schema_attr_test")
"multivalue": ["false"], ),
"unique": ["false"], (
"index": ["EQUALITY"], Attribute::Uuid,
"syntax": ["TNEOUNTUH"] Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
} ),
}"#, (
Attribute::Description,
Value::Utf8("Test attr parsing".to_string())
),
(Attribute::MultiValue, Value::Bool(false)),
(Attribute::Unique, Value::Bool(false)),
(Attribute::Syntax, Value::Utf8("TNEOUNTUH".to_string())),
(Attribute::Index, Value::Index(IndexType::Equality))
),
SchemaAttribute SchemaAttribute
); );
// Index is allowed to be empty // Index is allowed to be empty
sch_from_entry_ok!( sch_from_entry_ok!(
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "attributetype"], (Attribute::Class, EntryClass::AttributeType.to_value()),
"attributename": ["schema_attr_test"], (
"uuid": ["66c68b2f-d02c-4243-8013-7946e40fe321"], Attribute::AttributeName,
"description": ["Test attr parsing"], Value::new_iutf8("schema_attr_test")
"multivalue": ["false"], ),
"unique": ["false"], (
"syntax": ["UTF8STRING"] Attribute::Uuid,
} Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
}"#, ),
(
Attribute::Description,
Value::Utf8("Test attr parsing".to_string())
),
(Attribute::MultiValue, Value::Bool(false)),
(Attribute::Unique, Value::Bool(false)),
(Attribute::Syntax, Value::Syntax(SyntaxType::Utf8String))
),
SchemaAttribute SchemaAttribute
); );
// Index present // Index present
sch_from_entry_ok!( sch_from_entry_ok!(
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "attributetype"], (Attribute::Class, EntryClass::AttributeType.to_value()),
"attributename": ["schema_attr_test"], (
"uuid": ["66c68b2f-d02c-4243-8013-7946e40fe321"], Attribute::AttributeName,
"description": ["Test attr parsing"], Value::new_iutf8("schema_attr_test")
"multivalue": ["false"], ),
"unique": ["false"], (
"index": ["EQUALITY"], Attribute::Uuid,
"syntax": ["UTF8STRING"] Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
} ),
}"#, (
Attribute::Description,
Value::Utf8("Test attr parsing".to_string())
),
(Attribute::MultiValue, Value::Bool(false)),
(Attribute::Unique, Value::Bool(false)),
(Attribute::Syntax, Value::Syntax(SyntaxType::Utf8String)),
(Attribute::Index, Value::Index(IndexType::Equality))
),
SchemaAttribute SchemaAttribute
); );
} }
@ -2467,95 +2515,126 @@ mod tests {
#[test] #[test]
fn test_schema_class_from_entry() { fn test_schema_class_from_entry() {
sch_from_entry_err!( sch_from_entry_err!(
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "classtype"], (Attribute::Class, EntryClass::ClassType.to_value()),
"classname": ["schema_class_test"], (Attribute::ClassName, Value::new_iutf8("schema_class_test")),
"uuid": ["66c68b2f-d02c-4243-8013-7946e40fe321"] (
} Attribute::Uuid,
}"#, Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
)
),
SchemaClass SchemaClass
); );
sch_from_entry_err!( sch_from_entry_err!(
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object"], (Attribute::ClassName, Value::new_iutf8("schema_class_test")),
"classname": ["schema_class_test"], (
"description": ["class test"], Attribute::Uuid,
"uuid": ["66c68b2f-d02c-4243-8013-7946e40fe321"] Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
} ),
}"#, (
Attribute::Description,
Value::Utf8("class test".to_string())
)
),
SchemaClass SchemaClass
); );
// Classes can be valid with no attributes provided. // Classes can be valid with no attributes provided.
sch_from_entry_ok!( sch_from_entry_ok!(
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "classtype"], (Attribute::Class, EntryClass::ClassType.to_value()),
"classname": ["schema_class_test"], (Attribute::ClassName, Value::new_iutf8("schema_class_test")),
"description": ["class test"], (
"uuid": ["66c68b2f-d02c-4243-8013-7946e40fe321"] Attribute::Uuid,
} Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
}"#, ),
(
Attribute::Description,
Value::Utf8("class test".to_string())
)
),
SchemaClass SchemaClass
); );
// Classes with various may/must // Classes with various may/must
sch_from_entry_ok!( sch_from_entry_ok!(
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "classtype"], (Attribute::Class, EntryClass::ClassType.to_value()),
"classname": ["schema_class_test"], (Attribute::ClassName, Value::new_iutf8("schema_class_test")),
"description": ["class test"], (
"uuid": ["66c68b2f-d02c-4243-8013-7946e40fe321"], Attribute::Uuid,
"systemmust": ["d"] Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
} ),
}"#, (
Attribute::Description,
Value::Utf8("class test".to_string())
),
(Attribute::SystemMust, Value::new_iutf8("a"))
),
SchemaClass SchemaClass
); );
sch_from_entry_ok!( sch_from_entry_ok!(
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "classtype"], (Attribute::Class, EntryClass::ClassType.to_value()),
"classname": ["schema_class_test"], (Attribute::ClassName, Value::new_iutf8("schema_class_test")),
"description": ["class test"], (
"uuid": ["66c68b2f-d02c-4243-8013-7946e40fe321"], Attribute::Uuid,
"systemmay": ["c"] Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
} ),
}"#, (
Attribute::Description,
Value::Utf8("class test".to_string())
),
(Attribute::SystemMay, Value::new_iutf8("a"))
),
SchemaClass SchemaClass
); );
sch_from_entry_ok!( sch_from_entry_ok!(
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "classtype"], (Attribute::Class, EntryClass::ClassType.to_value()),
"classname": ["schema_class_test"], (Attribute::ClassName, Value::new_iutf8("schema_class_test")),
"description": ["class test"], (
"uuid": ["66c68b2f-d02c-4243-8013-7946e40fe321"], Attribute::Uuid,
"may": ["a"], Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
"must": ["b"] ),
} (
}"#, Attribute::Description,
Value::Utf8("class test".to_string())
),
(Attribute::May, Value::new_iutf8("a")),
(Attribute::Must, Value::new_iutf8("b"))
),
SchemaClass SchemaClass
); );
sch_from_entry_ok!( sch_from_entry_ok!(
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "classtype"], (Attribute::Class, EntryClass::ClassType.to_value()),
"classname": ["schema_class_test"], (Attribute::ClassName, Value::new_iutf8("schema_class_test")),
"description": ["class test"], (
"uuid": ["66c68b2f-d02c-4243-8013-7946e40fe321"], Attribute::Uuid,
"may": ["a"], Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
"must": ["b"], ),
"systemmay": ["c"], (
"systemmust": ["d"] Attribute::Description,
} Value::Utf8("class test".to_string())
}"#, ),
(Attribute::May, Value::new_iutf8("a")),
(Attribute::Must, Value::new_iutf8("b")),
(Attribute::SystemMay, Value::new_iutf8("c")),
(Attribute::SystemMust, Value::new_iutf8("d"))
),
SchemaClass SchemaClass
); );
} }
@ -2813,61 +2892,18 @@ mod tests {
assert!(e_ok.validate(&schema).is_ok()); assert!(e_ok.validate(&schema).is_ok());
} }
#[test]
fn test_schema_entry_validate() {
// Check that entries can be normalised and validated sanely
let schema_outer = Schema::new().expect("failed to create schema");
let schema = schema_outer.write_blocking();
// Check syntax to upper
// check index to upper
// insense to lower
// attr name to lower
let e_test: Entry<EntryInvalid, EntryNew> = Entry::unsafe_from_entry_str(
r#"{
"attrs": {
"class": ["extensibleobject"],
"attributename": ["TestPerson"],
"syntax": ["utf8string"],
"UUID": ["db237e8a-0079-4b8c-8a56-593b22aa44d1"],
"InDeX": ["equality"]
}
}"#,
)
.into_invalid_new();
let e_expect: Entry<EntryValid, EntryNew> = Entry::unsafe_from_entry_str(
r#"{
"attrs": {
"class": ["extensibleobject"],
"attributename": ["testperson"],
"syntax": ["UTF8STRING"],
"uuid": ["db237e8a-0079-4b8c-8a56-593b22aa44d1"],
"index": ["EQUALITY"]
}
}"#,
)
.into_valid_new();
let e_valid = e_test.validate(&schema).expect("validation failure");
assert_eq!(e_expect, e_valid);
}
#[test] #[test]
fn test_schema_extensible() { fn test_schema_extensible() {
let schema_outer = Schema::new().expect("failed to create schema"); let schema_outer = Schema::new().expect("failed to create schema");
let schema = schema_outer.read(); let schema = schema_outer.read();
// Just because you are extensible, doesn't mean you can be lazy // Just because you are extensible, doesn't mean you can be lazy
let e_extensible_bad = entry_init!(
let e_extensible_bad: Entry<EntryInvalid, EntryNew> = Entry::unsafe_from_entry_str( (Attribute::Class, EntryClass::ExtensibleObject.to_value()),
r#"{ (
"attrs": { Attribute::Uuid,
"class": ["extensibleobject"], Value::Uuid(uuid::uuid!("db237e8a-0079-4b8c-8a56-593b22aa44d1"))
"uuid": ["db237e8a-0079-4b8c-8a56-593b22aa44d1"], ),
"multivalue": ["zzzz"] (Attribute::MultiValue, Value::Utf8("zzzz".to_string()))
}
}"#,
) )
.into_invalid_new(); .into_invalid_new();
@ -2879,14 +2915,13 @@ mod tests {
); );
// Extensible doesn't mean you can have the phantoms // Extensible doesn't mean you can have the phantoms
let e_extensible_phantom: Entry<EntryInvalid, EntryNew> = Entry::unsafe_from_entry_str( let e_extensible_phantom = entry_init!(
r#"{ (Attribute::Class, EntryClass::ExtensibleObject.to_value()),
"attrs": { (
"class": ["extensibleobject"], Attribute::Uuid,
"uuid": ["db237e8a-0079-4b8c-8a56-593b22aa44d1"], Value::Uuid(uuid::uuid!("db237e8a-0079-4b8c-8a56-593b22aa44d1"))
"password_import": ["zzzz"] ),
} (Attribute::PasswordImport, Value::Utf8("zzzz".to_string()))
}"#,
) )
.into_invalid_new(); .into_invalid_new();
@ -2897,14 +2932,13 @@ mod tests {
)) ))
); );
let e_extensible: Entry<EntryInvalid, EntryNew> = Entry::unsafe_from_entry_str( let e_extensible = entry_init!(
r#"{ (Attribute::Class, EntryClass::ExtensibleObject.to_value()),
"attrs": { (
"class": ["extensibleobject"], Attribute::Uuid,
"uuid": ["db237e8a-0079-4b8c-8a56-593b22aa44d1"], Value::Uuid(uuid::uuid!("db237e8a-0079-4b8c-8a56-593b22aa44d1"))
"multivalue": ["true"] ),
} (Attribute::MultiValue, Value::Bool(true))
}"#,
) )
.into_invalid_new(); .into_invalid_new();

View file

@ -1110,8 +1110,7 @@ mod tests {
$e:expr, $e:expr,
$type:ty $type:ty
) => {{ ) => {{
let e1: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str($e); let ev1 = $e.into_sealed_committed();
let ev1 = e1.into_sealed_committed();
let r1 = <$type>::try_from($qs, &ev1); let r1 = <$type>::try_from($qs, &ev1);
error!(?r1); error!(?r1);
@ -1147,39 +1146,66 @@ mod tests {
acp_from_entry_err!( acp_from_entry_err!(
&mut qs_write, &mut qs_write,
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object"], (Attribute::Name, Value::new_iname("acp_invalid")),
"name": ["acp_invalid"], (
"uuid": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"] Attribute::Uuid,
} Value::Uuid(uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
}"#, )
),
AccessControlProfile AccessControlProfile
); );
acp_from_entry_err!( acp_from_entry_err!(
&mut qs_write, &mut qs_write,
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "access_control_profile", "access_control_receiver_g", "access_control_target_scope"], (
"name": ["acp_invalid"], Attribute::Class,
"uuid": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"] EntryClass::AccessControlProfile.to_value()
} ),
}"#, (
Attribute::Class,
EntryClass::AccessControlReceiverGroup.to_value()
),
(
Attribute::Class,
EntryClass::AccessControlTargetScope.to_value()
),
(Attribute::Name, Value::new_iname("acp_invalid")),
(
Attribute::Uuid,
Value::Uuid(uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
)
),
AccessControlProfile AccessControlProfile
); );
acp_from_entry_err!( acp_from_entry_err!(
&mut qs_write, &mut qs_write,
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "access_control_profile", "access_control_receiver_g", "access_control_target_scope"], (
"name": ["acp_invalid"], Attribute::Class,
"uuid": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"], EntryClass::AccessControlProfile.to_value()
"acp_receiver_group": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"], ),
"acp_targetscope": [""] (
} Attribute::Class,
}"#, EntryClass::AccessControlReceiverGroup.to_value()
),
(
Attribute::Class,
EntryClass::AccessControlTargetScope.to_value()
),
(Attribute::Name, Value::new_iname("acp_invalid")),
(
Attribute::Uuid,
Value::Uuid(uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
),
(Attribute::AcpReceiverGroup, Value::Bool(true)),
(Attribute::AcpTargetScope, Value::Bool(true))
),
AccessControlProfile AccessControlProfile
); );
@ -1192,6 +1218,14 @@ mod tests {
Attribute::Class, Attribute::Class,
EntryClass::AccessControlProfile.to_value() EntryClass::AccessControlProfile.to_value()
), ),
(
Attribute::Class,
EntryClass::AccessControlReceiverGroup.to_value()
),
(
Attribute::Class,
EntryClass::AccessControlTargetScope.to_value()
),
(Attribute::Name, Value::new_iname("acp_valid")), (Attribute::Name, Value::new_iname("acp_valid")),
( (
Attribute::Uuid, Attribute::Uuid,
@ -1216,17 +1250,26 @@ mod tests {
acp_from_entry_err!( acp_from_entry_err!(
&mut qs_write, &mut qs_write,
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "access_control_profile"], (
"name": ["acp_valid"], Attribute::Class,
"uuid": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"], EntryClass::AccessControlProfile.to_value()
"acp_receiver_group": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"], ),
"acp_targetscope": [ (Attribute::Name, Value::new_iname("acp_valid")),
"{\"eq\":[\"name\",\"a\"]}" (
] Attribute::Uuid,
} Value::Uuid(uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
}"#, ),
(
Attribute::AcpReceiverGroup,
Value::Refer(uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
),
(
Attribute::AcpTargetScope,
Value::new_json_filter_s("{\"eq\":[\"name\",\"a\"]}").expect("filter")
)
),
AccessControlDelete AccessControlDelete
); );
@ -1265,53 +1308,80 @@ mod tests {
// Missing class acp // Missing class acp
acp_from_entry_err!( acp_from_entry_err!(
&mut qs_write, &mut qs_write,
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "access_control_search"], (Attribute::Class, EntryClass::AccessControlSearch.to_value()),
"name": ["acp_invalid"], (Attribute::Name, Value::new_iname("acp_valid")),
"uuid": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"], (
"acp_receiver_group": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"], Attribute::Uuid,
"acp_targetscope": [ Value::Uuid(uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
"{\"eq\":[\"name\",\"a\"]}" ),
], (
"acp_search_attr": ["name", "class"] Attribute::AcpReceiverGroup,
} Value::Refer(uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
}"#, ),
(
Attribute::AcpTargetScope,
Value::new_json_filter_s("{\"eq\":[\"name\",\"a\"]}").expect("filter")
),
(Attribute::AcpSearchAttr, Value::from(Attribute::Name)),
(Attribute::AcpSearchAttr, Value::new_iutf8("class"))
),
AccessControlSearch AccessControlSearch
); );
// Missing class acs // Missing class acs
acp_from_entry_err!( acp_from_entry_err!(
&mut qs_write, &mut qs_write,
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "access_control_profile"], (
"name": ["acp_invalid"], Attribute::Class,
"uuid": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"], EntryClass::AccessControlProfile.to_value()
"acp_receiver_group": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"], ),
"acp_targetscope": [ (Attribute::Name, Value::new_iname("acp_valid")),
"{\"eq\":[\"name\",\"a\"]}" (
], Attribute::Uuid,
"acp_search_attr": ["name", "class"] Value::Uuid(uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
} ),
}"#, (
Attribute::AcpReceiverGroup,
Value::Refer(uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
),
(
Attribute::AcpTargetScope,
Value::new_json_filter_s("{\"eq\":[\"name\",\"a\"]}").expect("filter")
),
(Attribute::AcpSearchAttr, Value::from(Attribute::Name)),
(Attribute::AcpSearchAttr, Value::new_iutf8("class"))
),
AccessControlSearch AccessControlSearch
); );
// Missing attr acp_search_attr // Missing attr acp_search_attr
acp_from_entry_err!( acp_from_entry_err!(
&mut qs_write, &mut qs_write,
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "access_control_profile", "access_control_search"], (
"name": ["acp_invalid"], Attribute::Class,
"uuid": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"], EntryClass::AccessControlProfile.to_value()
"acp_receiver_group": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"], ),
"acp_targetscope": [ (Attribute::Class, EntryClass::AccessControlSearch.to_value()),
"{\"eq\":[\"name\",\"a\"]}" (Attribute::Name, Value::new_iname("acp_valid")),
] (
} Attribute::Uuid,
}"#, Value::Uuid(uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
),
(
Attribute::AcpReceiverGroup,
Value::Refer(uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
),
(
Attribute::AcpTargetScope,
Value::new_json_filter_s("{\"eq\":[\"name\",\"a\"]}").expect("filter")
)
),
AccessControlSearch AccessControlSearch
); );
@ -1352,20 +1422,26 @@ mod tests {
acp_from_entry_err!( acp_from_entry_err!(
&mut qs_write, &mut qs_write,
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "access_control_profile"], (
"name": ["acp_valid"], Attribute::Class,
"uuid": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"], EntryClass::AccessControlProfile.to_value()
"acp_receiver_group": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"], ),
"acp_targetscope": [ (Attribute::Name, Value::new_iname("acp_invalid")),
"{\"eq\":[\"name\",\"a\"]}" (
], Attribute::Uuid,
"acp_modify_removedattr": ["name"], Value::Uuid(uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
"acp_modify_presentattr": ["name"], ),
"acp_modify_class": ["object"] (
} Attribute::AcpReceiverGroup,
}"#, Value::Refer(uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
),
(
Attribute::AcpTargetScope,
Value::new_json_filter_s("{\"eq\":[\"name\",\"a\"]}").expect("filter")
)
),
AccessControlModify AccessControlModify
); );
@ -1438,19 +1514,28 @@ mod tests {
acp_from_entry_err!( acp_from_entry_err!(
&mut qs_write, &mut qs_write,
r#"{ entry_init!(
"attrs": { (Attribute::Class, EntryClass::Object.to_value()),
"class": ["object", "access_control_profile"], (
"name": ["acp_valid"], Attribute::Class,
"uuid": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"], EntryClass::AccessControlProfile.to_value()
"acp_receiver_group": ["cc8e95b4-c24f-4d68-ba54-8bed76f63930"], ),
"acp_targetscope": [ (Attribute::Name, Value::new_iname("acp_invalid")),
"{\"eq\":[\"name\",\"a\"]}" (
], Attribute::Uuid,
"acp_create_class": ["object"], Value::Uuid(uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
"acp_create_attr": ["name"] ),
} (
}"#, Attribute::AcpReceiverGroup,
Value::Refer(uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
),
(
Attribute::AcpTargetScope,
Value::new_json_filter_s("{\"eq\":[\"name\",\"a\"]}").expect("filter")
),
(Attribute::AcpCreateAttr, Value::from(Attribute::Name)),
(Attribute::AcpCreateClass, EntryClass::Object.to_value())
),
AccessControlCreate AccessControlCreate
); );

View file

@ -2193,13 +2193,13 @@ mod tests {
#[test] #[test]
fn test_value_index_tryfrom() { fn test_value_index_tryfrom() {
let r1 = IndexType::try_from("EQUALITY"); let r1 = IndexType::try_from("EQualiTY");
assert_eq!(r1, Ok(IndexType::Equality)); assert_eq!(r1, Ok(IndexType::Equality));
let r2 = IndexType::try_from("PRESENCE"); let r2 = IndexType::try_from("PResenCE");
assert_eq!(r2, Ok(IndexType::Presence)); assert_eq!(r2, Ok(IndexType::Presence));
let r3 = IndexType::try_from("SUBSTRING"); let r3 = IndexType::try_from("SUbstrING");
assert_eq!(r3, Ok(IndexType::SubString)); assert_eq!(r3, Ok(IndexType::SubString));
let r4 = IndexType::try_from("thaoeusaneuh"); let r4 = IndexType::try_from("thaoeusaneuh");
@ -2208,10 +2208,10 @@ mod tests {
#[test] #[test]
fn test_value_syntax_tryfrom() { fn test_value_syntax_tryfrom() {
let r1 = SyntaxType::try_from("UTF8STRING"); let r1 = SyntaxType::try_from("UTF8strinG");
assert_eq!(r1, Ok(SyntaxType::Utf8String)); assert_eq!(r1, Ok(SyntaxType::Utf8String));
let r2 = SyntaxType::try_from("UTF8STRING_INSENSITIVE"); let r2 = SyntaxType::try_from("UTF8STRING_INSensitIVE");
assert_eq!(r2, Ok(SyntaxType::Utf8StringInsensitive)); assert_eq!(r2, Ok(SyntaxType::Utf8StringInsensitive));
let r3 = SyntaxType::try_from("BOOLEAN"); let r3 = SyntaxType::try_from("BOOLEAN");