mirror of
https://github.com/kanidm/kanidm.git
synced 2025-05-22 00:43:54 +02:00
Schema dooby doo part two (#2071)
* scim strings! * mapmapmap * mapmapmap -comments and map * updating delete teest * fixing some tests
This commit is contained in:
parent
436a3f0307
commit
d5d76d1a3c
|
@ -24,6 +24,7 @@ pub const ATTR_ACP_TARGET_SCOPE: &str = "acp_targetscope";
|
|||
pub const ATTR_API_TOKEN_SESSION: &str = "api_token_session";
|
||||
pub const ATTR_ATTR: &str = "attr";
|
||||
pub const ATTR_ATTRIBUTENAME: &str = "attributename";
|
||||
pub const ATTR_ATTRIBUTETYPE: &str = "attributetype";
|
||||
pub const ATTR_AUTH_SESSION_EXPIRY: &str = "authsession_expiry";
|
||||
pub const ATTR_BADLIST_PASSWORD: &str = "badlist_password";
|
||||
pub const ATTR_CLAIM: &str = "claim";
|
||||
|
@ -36,6 +37,7 @@ pub const ATTR_DESCRIPTION: &str = "description";
|
|||
pub const ATTR_DEVICEKEYS: &str = "devicekeys";
|
||||
pub const ATTR_DIRECTMEMBEROF: &str = "directmemberof";
|
||||
pub const ATTR_DISPLAYNAME: &str = "displayname";
|
||||
pub const ATTR_DN: &str = "dn";
|
||||
pub const ATTR_DOMAIN_DISPLAY_NAME: &str = "domain_display_name";
|
||||
pub const ATTR_DOMAIN_LDAP_BASEDN: &str = "domain_ldap_basedn";
|
||||
pub const ATTR_DOMAIN_NAME: &str = "domain_name";
|
||||
|
@ -46,9 +48,14 @@ pub const ATTR_DOMAIN: &str = "domain";
|
|||
pub const ATTR_DYNGROUP_FILTER: &str = "dyngroup_filter";
|
||||
pub const ATTR_DYNGROUP: &str = "dyngroup";
|
||||
pub const ATTR_DYNMEMBER: &str = "dynmember";
|
||||
pub const ATTR_LDAP_EMAIL_ADDRESS: &str = "emailaddress";
|
||||
pub const ATTR_EMAIL_ALTERNATIVE: &str = "emailalternative";
|
||||
pub const ATTR_EMAIL_PRIMARY: &str = "emailprimary";
|
||||
pub const ATTR_EMAIL: &str = "email";
|
||||
pub const ATTR_ENTRYDN: &str = "entrydn";
|
||||
pub const ATTR_ENTRYUUID: &str = "entryuuid";
|
||||
pub const ATTR_LDAP_KEYS: &str = "keys";
|
||||
pub const ATTR_EXCLUDES: &str = "excludes";
|
||||
pub const ATTR_ES256_PRIVATE_KEY_DER: &str = "es256_private_key_der";
|
||||
pub const ATTR_FERNET_PRIVATE_KEY_STR: &str = "fernet_private_key_str";
|
||||
pub const ATTR_GIDNUMBER: &str = "gidnumber";
|
||||
|
@ -71,6 +78,7 @@ pub const ATTR_NAME_HISTORY: &str = "name_history";
|
|||
pub const ATTR_NAME: &str = "name";
|
||||
pub const ATTR_NO_INDEX: &str = "no-index";
|
||||
pub const ATTR_NSUNIQUEID: &str = "nsuniqueid";
|
||||
|
||||
pub const ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE: &str =
|
||||
"oauth2_allow_insecure_client_disable_pkce";
|
||||
pub const ATTR_OAUTH2_CONSENT_SCOPE_MAP: &str = "oauth2_consent_scope_map";
|
||||
|
@ -91,26 +99,34 @@ pub const ATTR_PASSKEYS: &str = "passkeys";
|
|||
pub const ATTR_PASSWORD_IMPORT: &str = "password_import";
|
||||
pub const ATTR_PHANTOM: &str = "phantom";
|
||||
pub const ATTR_PRIMARY_CREDENTIAL: &str = "primary_credential";
|
||||
pub const ATTR_TOTP_IMPORT: &str = "totp_import";
|
||||
pub const ATTR_PRIVATE_COOKIE_KEY: &str = "private_cookie_key";
|
||||
pub const ATTR_PRIVILEGE_EXPIRY: &str = "privilege_expiry";
|
||||
pub const ATTR_RADIUS_SECRET: &str = "radius_secret";
|
||||
pub const ATTR_RECYCLED: &str = "recycled";
|
||||
pub const ATTR_REPLICATED: &str = "replicated";
|
||||
pub const ATTR_RS256_PRIVATE_KEY_DER: &str = "rs256_private_key_der";
|
||||
pub const ATTR_SCOPE: &str = "scope";
|
||||
pub const ATTR_SELF: &str = "self";
|
||||
pub const ATTR_SOURCE_UUID: &str = "source_uuid";
|
||||
pub const ATTR_SPN: &str = "spn";
|
||||
pub const ATTR_SUPPLEMENTS: &str = "supplements";
|
||||
pub const ATTR_LDAP_SSH_PUBLICKEY: &str = "ssh_publickey";
|
||||
pub const ATTR_SSHPUBLICKEY: &str = "sshpublickey";
|
||||
pub const ATTR_SYNC_ALLOWED: &str = "sync_allowed";
|
||||
pub const ATTR_SYNC_CLASS: &str = "sync_class";
|
||||
pub const ATTR_SYNC_COOKIE: &str = "sync_cookie";
|
||||
pub const ATTR_SYNC_CREDENTIAL_PORTAL: &str = "sync_credential_portal";
|
||||
pub const ATTR_SYNC_EXTERNAL_ID: &str = "sync_external_id";
|
||||
pub const ATTR_SYNC_EXTERNAL_UUID: &str = "sync_external_uuid";
|
||||
pub const ATTR_SYNC_PARENT_UUID: &str = "sync_parent_uuid";
|
||||
pub const ATTR_SYNC_TOKEN_SESSION: &str = "sync_token_session";
|
||||
pub const ATTR_SYNC_YIELD_AUTHORITY: &str = "sync_yield_authority";
|
||||
pub const ATTR_SYNTAX: &str = "syntax";
|
||||
pub const ATTR_SYSTEMEXCLUDES: &str = "systemexcludes";
|
||||
pub const ATTR_SYSTEMMAY: &str = "systemmay";
|
||||
pub const ATTR_SYSTEMMUST: &str = "systemmust";
|
||||
pub const ATTR_SYSTEMSUPPLEMENTS: &str = "systemsupplements";
|
||||
pub const ATTR_TERM: &str = "term";
|
||||
pub const ATTR_UID: &str = "uid";
|
||||
pub const ATTR_UIDNUMBER: &str = "uidnumber";
|
||||
|
@ -126,6 +142,8 @@ pub const ATTR_VERSION: &str = "version";
|
|||
pub const TEST_ATTR_NON_EXIST: &str = "non-exist";
|
||||
pub const TEST_ATTR_TEST_ATTR: &str = "testattr";
|
||||
pub const TEST_ATTR_EXTRA: &str = "extra";
|
||||
pub const TEST_ATTR_NUMBER: &str = "testattrnumber";
|
||||
pub const TEST_ATTR_NOTALLOWED: &str = "notallowed";
|
||||
|
||||
pub const OAUTH2_SCOPE_EMAIL: &str = ATTR_EMAIL;
|
||||
pub const OAUTH2_SCOPE_GROUPS: &str = "groups";
|
||||
|
|
|
@ -53,6 +53,11 @@ impl ScimSyncRequest {
|
|||
}
|
||||
}
|
||||
|
||||
pub const SCIM_ALGO: &str = "algo";
|
||||
pub const SCIM_DIGITS: &str = "digits";
|
||||
pub const SCIM_SECRET: &str = "secret";
|
||||
pub const SCIM_STEP: &str = "step";
|
||||
|
||||
pub const SCIM_SCHEMA_SYNC: &str = "urn:ietf:params:scim:schemas:kanidm:1.0:";
|
||||
pub const SCIM_SCHEMA_SYNC_PERSON: &str = "urn:ietf:params:scim:schemas:kanidm:1.0:person";
|
||||
pub const SCIM_SCHEMA_SYNC_ACCOUNT: &str = "urn:ietf:params:scim:schemas:kanidm:1.0:account";
|
||||
|
@ -88,13 +93,16 @@ impl Into<ScimComplexAttr> for ScimTotp {
|
|||
ScimSimpleAttr::String(external_id),
|
||||
);
|
||||
|
||||
attrs.insert("secret".to_string(), ScimSimpleAttr::String(secret));
|
||||
attrs.insert(SCIM_SECRET.to_string(), ScimSimpleAttr::String(secret));
|
||||
|
||||
attrs.insert("algo".to_string(), ScimSimpleAttr::String(algo));
|
||||
attrs.insert(SCIM_ALGO.to_string(), ScimSimpleAttr::String(algo));
|
||||
|
||||
attrs.insert("step".to_string(), ScimSimpleAttr::Number(step.into()));
|
||||
attrs.insert(SCIM_STEP.to_string(), ScimSimpleAttr::Number(step.into()));
|
||||
|
||||
attrs.insert("digits".to_string(), ScimSimpleAttr::Number(digits.into()));
|
||||
attrs.insert(
|
||||
SCIM_DIGITS.to_string(),
|
||||
ScimSimpleAttr::Number(digits.into()),
|
||||
);
|
||||
|
||||
ScimComplexAttr { attrs }
|
||||
}
|
||||
|
|
|
@ -1242,7 +1242,7 @@ pub async fn recycle_bin_get(
|
|||
State(state): State<ServerState>,
|
||||
Extension(kopid): Extension<KOpId>,
|
||||
) -> impl IntoResponse {
|
||||
let filter = filter_all!(f_pres(Attribute::Class.as_ref()));
|
||||
let filter = filter_all!(f_pres(Attribute::Class));
|
||||
let attrs = None;
|
||||
let res = state
|
||||
.qe_r_ref
|
||||
|
@ -1434,7 +1434,7 @@ pub async fn debug_ipinfo(
|
|||
|
||||
#[instrument(skip(state))]
|
||||
pub fn router(state: ServerState) -> Router<ServerState> {
|
||||
let router = Router::new()
|
||||
Router::new()
|
||||
.route("/v1/oauth2", get(super::oauth2::oauth2_get))
|
||||
.route("/v1/oauth2/_basic", post(super::oauth2::oauth2_basic_post))
|
||||
.route(
|
||||
|
@ -1735,15 +1735,6 @@ pub fn router(state: ServerState) -> Router<ServerState> {
|
|||
post(sync_account_token_post).delete(sync_account_token_delete),
|
||||
)
|
||||
.with_state(state)
|
||||
.layer(from_fn(dont_cache_me));
|
||||
if cfg!(debug_assertions) || cfg!(test) {
|
||||
add_debug_info(router)
|
||||
} else {
|
||||
router
|
||||
}
|
||||
}
|
||||
|
||||
// #[cfg(any(debug_assertions, test))]
|
||||
fn add_debug_info(router: Router<ServerState>) -> Router<ServerState> {
|
||||
router.route("/v1/debug/ipinfo", get(debug_ipinfo))
|
||||
.layer(from_fn(dont_cache_me))
|
||||
.route("/v1/debug/ipinfo", get(debug_ipinfo))
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ use smartstring::alias::String as AttrString;
|
|||
use uuid::Uuid;
|
||||
|
||||
use crate::be::dbvalue::{DbValueEmailAddressV1, DbValuePhoneNumberV1, DbValueSetV2, DbValueV1};
|
||||
use crate::prelude::entries::Attribute;
|
||||
use crate::prelude::OperationError;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
@ -446,12 +447,12 @@ impl std::fmt::Display for DbEntry {
|
|||
}
|
||||
None => write!(f, "Uuid(INVALID), ")?,
|
||||
};
|
||||
if let Some(names) = dbe_v1.attrs.get("name") {
|
||||
if let Some(names) = dbe_v1.attrs.get(Attribute::Name.as_ref()) {
|
||||
for name in names {
|
||||
write!(f, "{name:?}, ")?;
|
||||
}
|
||||
}
|
||||
if let Some(names) = dbe_v1.attrs.get("attributename") {
|
||||
if let Some(names) = dbe_v1.attrs.get(Attribute::AttributeName.as_ref()) {
|
||||
for name in names {
|
||||
write!(f, "{name:?}, ")?;
|
||||
}
|
||||
|
@ -471,10 +472,10 @@ impl std::fmt::Display for DbEntry {
|
|||
}
|
||||
None => write!(f, "Uuid(INVALID), ")?,
|
||||
};
|
||||
if let Some(names) = dbe_v2.attrs.get("name") {
|
||||
if let Some(names) = dbe_v2.attrs.get(Attribute::Name.as_ref()) {
|
||||
write!(f, "{names:?}, ")?;
|
||||
}
|
||||
if let Some(names) = dbe_v2.attrs.get("attributename") {
|
||||
if let Some(names) = dbe_v2.attrs.get(Attribute::AttributeName.as_ref()) {
|
||||
write!(f, "{names:?}, ")?;
|
||||
}
|
||||
if let Some(names) = dbe_v2.attrs.get("classname") {
|
||||
|
|
|
@ -2046,31 +2046,31 @@ mod tests {
|
|||
// This is a demo idxmeta, purely for testing.
|
||||
let idxmeta = vec![
|
||||
IdxKey {
|
||||
attr: AttrString::from("name"),
|
||||
attr: Attribute::Name.into(),
|
||||
itype: IndexType::Equality,
|
||||
},
|
||||
IdxKey {
|
||||
attr: AttrString::from("name"),
|
||||
attr: Attribute::Name.into(),
|
||||
itype: IndexType::Presence,
|
||||
},
|
||||
IdxKey {
|
||||
attr: AttrString::from("name"),
|
||||
attr: Attribute::Name.into(),
|
||||
itype: IndexType::SubString,
|
||||
},
|
||||
IdxKey {
|
||||
attr: AttrString::from("uuid"),
|
||||
attr: Attribute::Uuid.into(),
|
||||
itype: IndexType::Equality,
|
||||
},
|
||||
IdxKey {
|
||||
attr: AttrString::from("uuid"),
|
||||
attr: Attribute::Uuid.into(),
|
||||
itype: IndexType::Presence,
|
||||
},
|
||||
IdxKey {
|
||||
attr: AttrString::from("ta"),
|
||||
attr: Attribute::TestAttr.into(),
|
||||
itype: IndexType::Equality,
|
||||
},
|
||||
IdxKey {
|
||||
attr: AttrString::from("tb"),
|
||||
attr: Attribute::TestNumber.into(),
|
||||
itype: IndexType::Equality,
|
||||
},
|
||||
];
|
||||
|
@ -2091,7 +2091,7 @@ mod tests {
|
|||
($be:expr, $ent:expr) => {{
|
||||
let ei = $ent.clone().into_sealed_committed();
|
||||
let filt = ei
|
||||
.filter_from_attrs(&vec![AttrString::from("uuid")])
|
||||
.filter_from_attrs(&vec![Attribute::Uuid.into()])
|
||||
.expect("failed to generate filter")
|
||||
.into_valid_resolved();
|
||||
let lims = Limits::unlimited();
|
||||
|
@ -2104,7 +2104,7 @@ mod tests {
|
|||
($be:expr, $ent:expr, $attr:expr) => {{
|
||||
let ei = $ent.clone().into_sealed_committed();
|
||||
let filt = ei
|
||||
.filter_from_attrs(&vec![AttrString::from("userid")])
|
||||
.filter_from_attrs(&vec![Attribute::UserId.into()])
|
||||
.expect("failed to generate filter")
|
||||
.into_valid_resolved();
|
||||
let lims = Limits::unlimited();
|
||||
|
@ -2136,8 +2136,11 @@ mod tests {
|
|||
assert_eq!(empty_result, Err(OperationError::EmptyRequest));
|
||||
|
||||
let mut e: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e.add_ava("userid", Value::from("william"));
|
||||
e.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e.add_ava(Attribute::UserId.as_ref(), Value::from("william"));
|
||||
e.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
let e = e.into_sealed_new();
|
||||
|
||||
let single_result = be.create(&CID_ZERO, vec![e.clone()]);
|
||||
|
@ -2155,8 +2158,11 @@ mod tests {
|
|||
trace!("Simple Search");
|
||||
|
||||
let mut e: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e.add_ava("userid", Value::from("claire"));
|
||||
e.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e.add_ava(Attribute::UserId.as_ref(), Value::from("claire"));
|
||||
e.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
let e = e.into_sealed_new();
|
||||
|
||||
let single_result = be.create(&CID_ZERO, vec![e]);
|
||||
|
@ -2185,12 +2191,18 @@ mod tests {
|
|||
let lims = Limits::unlimited();
|
||||
// First create some entries (3?)
|
||||
let mut e1: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e1.add_ava("userid", Value::from("william"));
|
||||
e1.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e1.add_ava(Attribute::UserId.as_ref(), Value::from("william"));
|
||||
e1.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
|
||||
let mut e2: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e2.add_ava("userid", Value::from("alice"));
|
||||
e2.add_ava("uuid", Value::from("4b6228ab-1dbe-42a4-a9f5-f6368222438e"));
|
||||
e2.add_ava(Attribute::UserId.as_ref(), Value::from("alice"));
|
||||
e2.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("4b6228ab-1dbe-42a4-a9f5-f6368222438e"),
|
||||
);
|
||||
|
||||
let ve1 = e1.clone().into_sealed_new();
|
||||
let ve2 = e2.clone().into_sealed_new();
|
||||
|
@ -2201,7 +2213,7 @@ mod tests {
|
|||
|
||||
// You need to now retrieve the entries back out to get the entry id's
|
||||
let mut results = be
|
||||
.search(&lims, &filter_resolved!(f_pres("userid")))
|
||||
.search(&lims, &filter_resolved!(f_pres(Attribute::UserId)))
|
||||
.expect("Failed to search");
|
||||
|
||||
// Get these out to usable entries.
|
||||
|
@ -2224,8 +2236,8 @@ mod tests {
|
|||
// Make some changes to r1, r2.
|
||||
let pre1 = Arc::new(r1.clone().into_sealed_committed());
|
||||
let pre2 = Arc::new(r2.clone().into_sealed_committed());
|
||||
r1.add_ava("desc", Value::from("modified"));
|
||||
r2.add_ava("desc", Value::from("modified"));
|
||||
r1.add_ava("testattr", Value::from("modified"));
|
||||
r2.add_ava("testattr", Value::from("modified"));
|
||||
|
||||
// Now ... cheat.
|
||||
|
||||
|
@ -2235,8 +2247,8 @@ mod tests {
|
|||
// Modify single
|
||||
assert!(be.modify(&CID_ZERO, &[pre1], &[vr1.clone()]).is_ok());
|
||||
// Assert no other changes
|
||||
assert!(entry_attr_pres!(be, vr1, "desc"));
|
||||
assert!(!entry_attr_pres!(be, vr2, "desc"));
|
||||
assert!(entry_attr_pres!(be, vr1, "testattr"));
|
||||
assert!(!entry_attr_pres!(be, vr2, "testattr"));
|
||||
|
||||
// Modify both
|
||||
assert!(be
|
||||
|
@ -2247,8 +2259,8 @@ mod tests {
|
|||
)
|
||||
.is_ok());
|
||||
|
||||
assert!(entry_attr_pres!(be, vr1, "desc"));
|
||||
assert!(entry_attr_pres!(be, vr2, "desc"));
|
||||
assert!(entry_attr_pres!(be, vr1, "testattr"));
|
||||
assert!(entry_attr_pres!(be, vr2, "testattr"));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2260,16 +2272,25 @@ mod tests {
|
|||
|
||||
// First create some entries (3?)
|
||||
let mut e1: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e1.add_ava("userid", Value::from("william"));
|
||||
e1.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e1.add_ava(Attribute::UserId.as_ref(), Value::from("william"));
|
||||
e1.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
|
||||
let mut e2: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e2.add_ava("userid", Value::from("alice"));
|
||||
e2.add_ava("uuid", Value::from("4b6228ab-1dbe-42a4-a9f5-f6368222438e"));
|
||||
e2.add_ava(Attribute::UserId.as_ref(), Value::from("alice"));
|
||||
e2.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("4b6228ab-1dbe-42a4-a9f5-f6368222438e"),
|
||||
);
|
||||
|
||||
let mut e3: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e3.add_ava("userid", Value::from("lucy"));
|
||||
e3.add_ava("uuid", Value::from("7b23c99d-c06b-4a9a-a958-3afa56383e1d"));
|
||||
e3.add_ava(Attribute::UserId.as_ref(), Value::from("lucy"));
|
||||
e3.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("7b23c99d-c06b-4a9a-a958-3afa56383e1d"),
|
||||
);
|
||||
|
||||
let ve1 = e1.clone().into_sealed_new();
|
||||
let ve2 = e2.clone().into_sealed_new();
|
||||
|
@ -2282,7 +2303,7 @@ mod tests {
|
|||
|
||||
// You need to now retrieve the entries back out to get the entry id's
|
||||
let mut results = be
|
||||
.search(&lims, &filter_resolved!(f_pres("userid")))
|
||||
.search(&lims, &filter_resolved!(f_pres(Attribute::UserId)))
|
||||
.expect("Failed to search");
|
||||
|
||||
// Get these out to usable entries.
|
||||
|
@ -2356,16 +2377,25 @@ mod tests {
|
|||
|
||||
// First create some entries (3?)
|
||||
let mut e1: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e1.add_ava("userid", Value::from("william"));
|
||||
e1.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e1.add_ava(Attribute::UserId.as_ref(), Value::from("william"));
|
||||
e1.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
|
||||
let mut e2: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e2.add_ava("userid", Value::from("alice"));
|
||||
e2.add_ava("uuid", Value::from("4b6228ab-1dbe-42a4-a9f5-f6368222438e"));
|
||||
e2.add_ava(Attribute::UserId.as_ref(), Value::from("alice"));
|
||||
e2.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("4b6228ab-1dbe-42a4-a9f5-f6368222438e"),
|
||||
);
|
||||
|
||||
let mut e3: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e3.add_ava("userid", Value::from("lucy"));
|
||||
e3.add_ava("uuid", Value::from("7b23c99d-c06b-4a9a-a958-3afa56383e1d"));
|
||||
e3.add_ava(Attribute::UserId.as_ref(), Value::from("lucy"));
|
||||
e3.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("7b23c99d-c06b-4a9a-a958-3afa56383e1d"),
|
||||
);
|
||||
|
||||
let ve1 = e1.clone().into_sealed_new();
|
||||
let ve2 = e2.clone().into_sealed_new();
|
||||
|
@ -2411,16 +2441,25 @@ mod tests {
|
|||
be.set_db_ts_max(Duration::from_secs(1)).unwrap();
|
||||
// First create some entries (3?)
|
||||
let mut e1: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e1.add_ava("userid", Value::from("william"));
|
||||
e1.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e1.add_ava(Attribute::UserId.as_ref(), Value::from("william"));
|
||||
e1.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
|
||||
let mut e2: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e2.add_ava("userid", Value::from("alice"));
|
||||
e2.add_ava("uuid", Value::from("4b6228ab-1dbe-42a4-a9f5-f6368222438e"));
|
||||
e2.add_ava(Attribute::UserId.as_ref(), Value::from("alice"));
|
||||
e2.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("4b6228ab-1dbe-42a4-a9f5-f6368222438e"),
|
||||
);
|
||||
|
||||
let mut e3: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e3.add_ava("userid", Value::from("lucy"));
|
||||
e3.add_ava("uuid", Value::from("7b23c99d-c06b-4a9a-a958-3afa56383e1d"));
|
||||
e3.add_ava(Attribute::UserId.as_ref(), Value::from("lucy"));
|
||||
e3.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("7b23c99d-c06b-4a9a-a958-3afa56383e1d"),
|
||||
);
|
||||
|
||||
let ve1 = e1.clone().into_sealed_new();
|
||||
let ve2 = e2.clone().into_sealed_new();
|
||||
|
@ -2506,13 +2545,19 @@ mod tests {
|
|||
run_test!(|be: &mut BackendWriteTransaction| {
|
||||
// Add some test data?
|
||||
let mut e1: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e1.add_ava("name", Value::new_iname("william"));
|
||||
e1.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e1.add_ava(Attribute::Name.as_ref(), Value::new_iname("william"));
|
||||
e1.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
let e1 = e1.into_sealed_new();
|
||||
|
||||
let mut e2: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e2.add_ava("name", Value::new_iname("claire"));
|
||||
e2.add_ava("uuid", Value::from("bd651620-00dd-426b-aaa0-4494f7b7906f"));
|
||||
e2.add_ava(Attribute::Name.as_ref(), Value::new_iname("claire"));
|
||||
e2.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("bd651620-00dd-426b-aaa0-4494f7b7906f"),
|
||||
);
|
||||
let e2 = e2.into_sealed_new();
|
||||
|
||||
be.create(&CID_ZERO, vec![e1, e2]).unwrap();
|
||||
|
@ -2603,8 +2648,11 @@ mod tests {
|
|||
// Test that on entry create, the indexes are made correctly.
|
||||
// this is a similar case to reindex.
|
||||
let mut e1: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e1.add_ava("name", Value::from("william"));
|
||||
e1.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e1.add_ava(Attribute::Name.as_ref(), Value::from("william"));
|
||||
e1.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
let e1 = e1.into_sealed_new();
|
||||
|
||||
let rset = be.create(&CID_ZERO, vec![e1]).unwrap();
|
||||
|
@ -2664,18 +2712,27 @@ mod tests {
|
|||
// Test that on entry create, the indexes are made correctly.
|
||||
// this is a similar case to reindex.
|
||||
let mut e1: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e1.add_ava("name", Value::new_iname("william"));
|
||||
e1.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e1.add_ava(Attribute::Name.as_ref(), Value::new_iname("william"));
|
||||
e1.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
let e1 = e1.into_sealed_new();
|
||||
|
||||
let mut e2: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e2.add_ava("name", Value::new_iname("claire"));
|
||||
e2.add_ava("uuid", Value::from("bd651620-00dd-426b-aaa0-4494f7b7906f"));
|
||||
e2.add_ava(Attribute::Name.as_ref(), Value::new_iname("claire"));
|
||||
e2.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("bd651620-00dd-426b-aaa0-4494f7b7906f"),
|
||||
);
|
||||
let e2 = e2.into_sealed_new();
|
||||
|
||||
let mut e3: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e3.add_ava("userid", Value::new_iname("lucy"));
|
||||
e3.add_ava("uuid", Value::from("7b23c99d-c06b-4a9a-a958-3afa56383e1d"));
|
||||
e3.add_ava(Attribute::UserId.as_ref(), Value::new_iname("lucy"));
|
||||
e3.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("7b23c99d-c06b-4a9a-a958-3afa56383e1d"),
|
||||
);
|
||||
let e3 = e3.into_sealed_new();
|
||||
|
||||
let mut rset = be.create(&CID_ZERO, vec![e1, e2, e3]).unwrap();
|
||||
|
@ -2732,9 +2789,12 @@ mod tests {
|
|||
// us. For the test to be "accurate" we must add one attr, remove one attr
|
||||
// and change one attr.
|
||||
let mut e1: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e1.add_ava("name", Value::new_iname("william"));
|
||||
e1.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e1.add_ava("ta", Value::from("test"));
|
||||
e1.add_ava(Attribute::Name.as_ref(), Value::new_iname("william"));
|
||||
e1.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
e1.add_ava("testattr", Value::from("test"));
|
||||
let e1 = e1.into_sealed_new();
|
||||
|
||||
let rset = be.create(&CID_ZERO, vec![e1]).unwrap();
|
||||
|
@ -2742,12 +2802,12 @@ mod tests {
|
|||
// Now, alter the new entry.
|
||||
let mut ce1 = rset[0].as_ref().clone().into_invalid();
|
||||
// add something.
|
||||
ce1.add_ava("tb", Value::from("test"));
|
||||
ce1.add_ava("testattrnumber", Value::from("test"));
|
||||
// remove something.
|
||||
ce1.purge_ava("ta");
|
||||
ce1.purge_ava("testattr");
|
||||
// mod something.
|
||||
ce1.purge_ava("name");
|
||||
ce1.add_ava("name", Value::new_iname("claire"));
|
||||
ce1.add_ava(Attribute::Name.as_ref(), Value::new_iname("claire"));
|
||||
|
||||
let ce1 = ce1.into_sealed_committed();
|
||||
|
||||
|
@ -2758,9 +2818,15 @@ mod tests {
|
|||
|
||||
idl_state!(be, "name", IndexType::Presence, "_", Some(vec![1]));
|
||||
|
||||
idl_state!(be, "tb", IndexType::Equality, "test", Some(vec![1]));
|
||||
idl_state!(
|
||||
be,
|
||||
"testattrnumber",
|
||||
IndexType::Equality,
|
||||
"test",
|
||||
Some(vec![1])
|
||||
);
|
||||
|
||||
idl_state!(be, "ta", IndexType::Equality, "test", Some(vec![]));
|
||||
idl_state!(be, "testattr", IndexType::Equality, "test", Some(vec![]));
|
||||
|
||||
let william_uuid = uuid!("db237e8a-0079-4b8c-8a56-593b22aa44d1");
|
||||
assert!(be.name2uuid("william") == Ok(None));
|
||||
|
@ -2778,8 +2844,11 @@ mod tests {
|
|||
// This will be needing to be correct for conflicts when we add
|
||||
// replication support!
|
||||
let mut e1: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e1.add_ava("name", Value::new_iname("william"));
|
||||
e1.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e1.add_ava(Attribute::Name.as_ref(), Value::new_iname("william"));
|
||||
e1.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
let e1 = e1.into_sealed_new();
|
||||
|
||||
let rset = be.create(&CID_ZERO, vec![e1]).unwrap();
|
||||
|
@ -2788,8 +2857,11 @@ mod tests {
|
|||
let mut ce1 = rset[0].as_ref().clone().into_invalid();
|
||||
ce1.purge_ava("name");
|
||||
ce1.purge_ava("uuid");
|
||||
ce1.add_ava("name", Value::new_iname("claire"));
|
||||
ce1.add_ava("uuid", Value::from("04091a7a-6ce4-42d2-abf5-c2ce244ac9e8"));
|
||||
ce1.add_ava(Attribute::Name.as_ref(), Value::new_iname("claire"));
|
||||
ce1.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("04091a7a-6ce4-42d2-abf5-c2ce244ac9e8"),
|
||||
);
|
||||
let ce1 = ce1.into_sealed_committed();
|
||||
|
||||
be.modify(&CID_ZERO, &rset, &[ce1]).unwrap();
|
||||
|
@ -2834,15 +2906,21 @@ mod tests {
|
|||
|
||||
// Create a test entry with some indexed / unindexed values.
|
||||
let mut e1: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e1.add_ava("name", Value::new_iname("william"));
|
||||
e1.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e1.add_ava(Attribute::Name.as_ref(), Value::new_iname("william"));
|
||||
e1.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
e1.add_ava("no-index", Value::from("william"));
|
||||
e1.add_ava("other-no-index", Value::from("william"));
|
||||
let e1 = e1.into_sealed_new();
|
||||
|
||||
let mut e2: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e2.add_ava("name", Value::new_iname("claire"));
|
||||
e2.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d2"));
|
||||
e2.add_ava(Attribute::Name.as_ref(), Value::new_iname("claire"));
|
||||
e2.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d2"),
|
||||
);
|
||||
let e2 = e2.into_sealed_new();
|
||||
|
||||
let _rset = be.create(&CID_ZERO, vec![e1, e2]).unwrap();
|
||||
|
@ -3015,7 +3093,7 @@ mod tests {
|
|||
// test andnot in and (first) with name
|
||||
let f_and_andnot = filter_resolved!(f_and!([
|
||||
f_andnot(f_eq(Attribute::Name, PartialValue::new_utf8s("claire"))),
|
||||
f_pres("name")
|
||||
f_pres(Attribute::Name)
|
||||
]));
|
||||
|
||||
let (r, _plan) = be.filter2idl(f_and_andnot.to_inner(), 0).unwrap();
|
||||
|
@ -3030,7 +3108,7 @@ mod tests {
|
|||
}
|
||||
// test andnot in and (last) with name
|
||||
let f_and_andnot = filter_resolved!(f_and!([
|
||||
f_pres("name"),
|
||||
f_pres(Attribute::Name),
|
||||
f_andnot(f_eq(Attribute::Name, PartialValue::new_utf8s("claire")))
|
||||
]));
|
||||
|
||||
|
@ -3046,7 +3124,7 @@ mod tests {
|
|||
// test andnot in and (first) with no-index
|
||||
let f_and_andnot = filter_resolved!(f_and!([
|
||||
f_andnot(f_eq(Attribute::Name, PartialValue::new_utf8s("claire"))),
|
||||
f_pres("no-index")
|
||||
f_pres(Attribute::NoIndex)
|
||||
]));
|
||||
|
||||
let (r, _plan) = be.filter2idl(f_and_andnot.to_inner(), 0).unwrap();
|
||||
|
@ -3058,7 +3136,7 @@ mod tests {
|
|||
}
|
||||
// test andnot in and (last) with no-index
|
||||
let f_and_andnot = filter_resolved!(f_and!([
|
||||
f_pres("no-index"),
|
||||
f_pres(Attribute::NoIndex),
|
||||
f_andnot(f_eq(Attribute::Name, PartialValue::new_utf8s("claire")))
|
||||
]));
|
||||
|
||||
|
@ -3121,24 +3199,33 @@ mod tests {
|
|||
run_test!(|be: &mut BackendWriteTransaction| {
|
||||
// Create some test entry with some indexed / unindexed values.
|
||||
let mut e1: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e1.add_ava("name", Value::new_iname("william"));
|
||||
e1.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e1.add_ava("ta", Value::from("dupe"));
|
||||
e1.add_ava("tb", Value::from("1"));
|
||||
e1.add_ava(Attribute::Name.as_ref(), Value::new_iname("william"));
|
||||
e1.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
e1.add_ava("testattr", Value::from("dupe"));
|
||||
e1.add_ava("testattrnumber", Value::from("1"));
|
||||
let e1 = e1.into_sealed_new();
|
||||
|
||||
let mut e2: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e2.add_ava("name", Value::new_iname("claire"));
|
||||
e2.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d2"));
|
||||
e2.add_ava("ta", Value::from("dupe"));
|
||||
e2.add_ava("tb", Value::from("1"));
|
||||
e2.add_ava(Attribute::Name.as_ref(), Value::new_iname("claire"));
|
||||
e2.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d2"),
|
||||
);
|
||||
e2.add_ava("testattr", Value::from("dupe"));
|
||||
e2.add_ava("testattrnumber", Value::from("1"));
|
||||
let e2 = e2.into_sealed_new();
|
||||
|
||||
let mut e3: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e3.add_ava("name", Value::new_iname("benny"));
|
||||
e3.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d3"));
|
||||
e3.add_ava("ta", Value::from("dupe"));
|
||||
e3.add_ava("tb", Value::from("2"));
|
||||
e3.add_ava(Attribute::Name.as_ref(), Value::new_iname("benny"));
|
||||
e3.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d3"),
|
||||
);
|
||||
e3.add_ava("testattr", Value::from("dupe"));
|
||||
e3.add_ava("testattrnumber", Value::from("2"));
|
||||
let e3 = e3.into_sealed_new();
|
||||
|
||||
let _rset = be.create(&CID_ZERO, vec![e1, e2, e3]).unwrap();
|
||||
|
@ -3148,12 +3235,12 @@ mod tests {
|
|||
assert!(!be.is_idx_slopeyness_generated().unwrap());
|
||||
|
||||
let ta_eq_slope = be
|
||||
.get_idx_slope(&IdxKey::new("ta", IndexType::Equality))
|
||||
.get_idx_slope(&IdxKey::new("testattr", IndexType::Equality))
|
||||
.unwrap();
|
||||
assert_eq!(ta_eq_slope, 45);
|
||||
|
||||
let tb_eq_slope = be
|
||||
.get_idx_slope(&IdxKey::new("tb", IndexType::Equality))
|
||||
.get_idx_slope(&IdxKey::new("testattrnumber", IndexType::Equality))
|
||||
.unwrap();
|
||||
assert_eq!(tb_eq_slope, 45);
|
||||
|
||||
|
@ -3182,12 +3269,12 @@ mod tests {
|
|||
assert!(be.is_idx_slopeyness_generated().unwrap());
|
||||
|
||||
let ta_eq_slope = be
|
||||
.get_idx_slope(&IdxKey::new("ta", IndexType::Equality))
|
||||
.get_idx_slope(&IdxKey::new("testattr", IndexType::Equality))
|
||||
.unwrap();
|
||||
assert_eq!(ta_eq_slope, 200);
|
||||
|
||||
let tb_eq_slope = be
|
||||
.get_idx_slope(&IdxKey::new("tb", IndexType::Equality))
|
||||
.get_idx_slope(&IdxKey::new("testattrnumber", IndexType::Equality))
|
||||
.unwrap();
|
||||
assert_eq!(tb_eq_slope, 133);
|
||||
|
||||
|
@ -3221,15 +3308,18 @@ mod tests {
|
|||
lim_deny_allids.unindexed_allow = false;
|
||||
|
||||
let mut e: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e.add_ava("userid", Value::from("william"));
|
||||
e.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e.add_ava("nonexist", Value::from("x"));
|
||||
e.add_ava(Attribute::UserId.as_ref(), Value::from("william"));
|
||||
e.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
e.add_ava(Attribute::NonExist.as_ref(), Value::from("x"));
|
||||
let e = e.into_sealed_new();
|
||||
let single_result = be.create(&CID_ZERO, vec![e.clone()]);
|
||||
|
||||
assert!(single_result.is_ok());
|
||||
let filt = e
|
||||
.filter_from_attrs(&[AttrString::from("nonexist")])
|
||||
.filter_from_attrs(&[Attribute::NonExist.into()])
|
||||
.expect("failed to generate filter")
|
||||
.into_valid_resolved();
|
||||
// check allow on allids
|
||||
|
@ -3256,15 +3346,18 @@ mod tests {
|
|||
lim_deny.search_max_results = 0;
|
||||
|
||||
let mut e: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e.add_ava("userid", Value::from("william"));
|
||||
e.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e.add_ava("nonexist", Value::from("x"));
|
||||
e.add_ava(Attribute::UserId.as_ref(), Value::from("william"));
|
||||
e.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
e.add_ava(Attribute::NonExist.as_ref(), Value::from("x"));
|
||||
let e = e.into_sealed_new();
|
||||
let single_result = be.create(&CID_ZERO, vec![e.clone()]);
|
||||
assert!(single_result.is_ok());
|
||||
|
||||
let filt = e
|
||||
.filter_from_attrs(&[AttrString::from("nonexist")])
|
||||
.filter_from_attrs(&[Attribute::NonExist.into()])
|
||||
.expect("failed to generate filter")
|
||||
.into_valid_resolved();
|
||||
|
||||
|
@ -3312,10 +3405,13 @@ mod tests {
|
|||
lim_deny.search_max_filter_test = 0;
|
||||
|
||||
let mut e: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e.add_ava("name", Value::new_iname("william"));
|
||||
e.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e.add_ava("nonexist", Value::from("x"));
|
||||
e.add_ava("nonexist", Value::from("y"));
|
||||
e.add_ava(Attribute::Name.as_ref(), Value::new_iname("william"));
|
||||
e.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
e.add_ava(Attribute::NonExist.as_ref(), Value::from("x"));
|
||||
e.add_ava(Attribute::NonExist.as_ref(), Value::from("y"));
|
||||
let e = e.into_sealed_new();
|
||||
let single_result = be.create(&CID_ZERO, vec![e]);
|
||||
assert!(single_result.is_ok());
|
||||
|
@ -3364,7 +3460,7 @@ mod tests {
|
|||
|
||||
// This is a demo idxmeta, purely for testing.
|
||||
let idxmeta = vec![IdxKey {
|
||||
attr: AttrString::from("uuid"),
|
||||
attr: Attribute::Uuid.into(),
|
||||
itype: IndexType::Equality,
|
||||
}];
|
||||
|
||||
|
@ -3381,8 +3477,11 @@ mod tests {
|
|||
|
||||
// Create into A
|
||||
let mut e: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e.add_ava("userid", Value::from("william"));
|
||||
e.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"));
|
||||
e.add_ava(Attribute::UserId.as_ref(), Value::from("william"));
|
||||
e.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1"),
|
||||
);
|
||||
let e = e.into_sealed_new();
|
||||
|
||||
let single_result = be_a_txn.create(&CID_ZERO, vec![e]);
|
||||
|
@ -3402,8 +3501,11 @@ mod tests {
|
|||
|
||||
// Create into B
|
||||
let mut e: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e.add_ava("userid", Value::from("claire"));
|
||||
e.add_ava("uuid", Value::from("0c680959-0944-47d6-9dea-53304d124266"));
|
||||
e.add_ava(Attribute::UserId.as_ref(), Value::from("claire"));
|
||||
e.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::from("0c680959-0944-47d6-9dea-53304d124266"),
|
||||
);
|
||||
let e = e.into_sealed_new();
|
||||
|
||||
let single_result = be_b_txn.create(&CID_ZERO, vec![e]);
|
||||
|
|
|
@ -44,12 +44,14 @@ pub enum Attribute {
|
|||
AcpModifyClass,
|
||||
AcpModifyPresentAttr,
|
||||
AcpModifyRemovedAttr,
|
||||
AcpReceiver,
|
||||
AcpReceiverGroup,
|
||||
AcpSearchAttr,
|
||||
AcpTargetScope,
|
||||
ApiTokenSession,
|
||||
Attr,
|
||||
AttributeName,
|
||||
AttributeType,
|
||||
AuthSessionExpiry,
|
||||
BadlistPassword,
|
||||
Claim,
|
||||
|
@ -62,6 +64,8 @@ pub enum Attribute {
|
|||
DeviceKeys,
|
||||
DirectMemberOf,
|
||||
DisplayName,
|
||||
Dn,
|
||||
Domain,
|
||||
DomainDisplayName,
|
||||
DomainLdapBasedn,
|
||||
DomainName,
|
||||
|
@ -74,7 +78,10 @@ pub enum Attribute {
|
|||
Email,
|
||||
EmailAlternative,
|
||||
EmailPrimary,
|
||||
EntryDn,
|
||||
EntryUuid,
|
||||
Es256PrivateKeyDer,
|
||||
Excludes,
|
||||
FernetPrivateKeyStr,
|
||||
GidNumber,
|
||||
GrantUiHint,
|
||||
|
@ -84,6 +91,10 @@ pub enum Attribute {
|
|||
IpaNtHash,
|
||||
JwsEs256PrivateKey,
|
||||
LastModifiedCid,
|
||||
/// An LDAP Compatible emailAddress
|
||||
LdapEmailAddress,
|
||||
/// An LDAP Compatible sshkeys virtual attribute
|
||||
LdapKeys,
|
||||
LegalName,
|
||||
LoginShell,
|
||||
Mail,
|
||||
|
@ -120,22 +131,29 @@ pub enum Attribute {
|
|||
RadiusSecret,
|
||||
Replicated,
|
||||
Rs256PrivateKeyDer,
|
||||
Scope,
|
||||
SourceUuid,
|
||||
Spn,
|
||||
/// An LDAP-compatible sshpublickey
|
||||
LdapSshPublicKey,
|
||||
/// The Kanidm-local ssh_publickey
|
||||
SshPublicKey,
|
||||
Supplements,
|
||||
SystemSupplements,
|
||||
SyncAllowed,
|
||||
SyncClass,
|
||||
SyncCookie,
|
||||
SyncCredentialPortal,
|
||||
SyncExternalId,
|
||||
SyncParentUuid,
|
||||
SyncTokenSession,
|
||||
SyncYieldAuthority,
|
||||
Syntax,
|
||||
SystemExcludes,
|
||||
SystemMay,
|
||||
SystemMust,
|
||||
Term,
|
||||
TotpImport,
|
||||
Uid,
|
||||
UidNumber,
|
||||
Unique,
|
||||
|
@ -151,7 +169,11 @@ pub enum Attribute {
|
|||
#[cfg(any(debug_assertions, test))]
|
||||
TestAttr,
|
||||
#[cfg(any(debug_assertions, test))]
|
||||
TestNumber,
|
||||
#[cfg(any(debug_assertions, test))]
|
||||
Extra,
|
||||
#[cfg(any(debug_assertions, test))]
|
||||
TestNotAllowed,
|
||||
}
|
||||
|
||||
impl AsRef<str> for Attribute {
|
||||
|
@ -160,18 +182,20 @@ impl AsRef<str> for Attribute {
|
|||
}
|
||||
}
|
||||
|
||||
// impl Attribute {
|
||||
// pub fn as_str(self) -> &'static str {
|
||||
// self.into()
|
||||
// }
|
||||
// }
|
||||
|
||||
impl From<&Attribute> for &'static str {
|
||||
fn from(value: &Attribute) -> Self {
|
||||
(*value).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for Attribute {
|
||||
type Error = OperationError;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
Attribute::try_from(value.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for Attribute {
|
||||
type Error = OperationError;
|
||||
fn try_from(val: String) -> Result<Self, OperationError> {
|
||||
|
@ -185,12 +209,14 @@ impl TryFrom<String> for Attribute {
|
|||
ATTR_ACP_MODIFY_CLASS => Attribute::AcpModifyClass,
|
||||
ATTR_ACP_MODIFY_PRESENTATTR => Attribute::AcpModifyPresentAttr,
|
||||
ATTR_ACP_MODIFY_REMOVEDATTR => Attribute::AcpModifyRemovedAttr,
|
||||
ATTR_ACP_RECEIVER => Attribute::AcpReceiver,
|
||||
ATTR_ACP_RECEIVER_GROUP => Attribute::AcpReceiverGroup,
|
||||
ATTR_ACP_SEARCH_ATTR => Attribute::AcpSearchAttr,
|
||||
ATTR_ACP_TARGET_SCOPE => Attribute::AcpTargetScope,
|
||||
ATTR_API_TOKEN_SESSION => Attribute::ApiTokenSession,
|
||||
ATTR_ATTR => Attribute::Attr,
|
||||
ATTR_ATTRIBUTENAME => Attribute::AttributeName,
|
||||
ATTR_ATTRIBUTETYPE => Attribute::AttributeType,
|
||||
ATTR_AUTH_SESSION_EXPIRY => Attribute::AuthSessionExpiry,
|
||||
ATTR_BADLIST_PASSWORD => Attribute::BadlistPassword,
|
||||
ATTR_CLAIM => Attribute::Claim,
|
||||
|
@ -203,6 +229,8 @@ impl TryFrom<String> for Attribute {
|
|||
ATTR_DEVICEKEYS => Attribute::DeviceKeys,
|
||||
ATTR_DIRECTMEMBEROF => Attribute::DirectMemberOf,
|
||||
ATTR_DISPLAYNAME => Attribute::DisplayName,
|
||||
ATTR_DN => Attribute::Dn,
|
||||
ATTR_DOMAIN => Attribute::Domain,
|
||||
ATTR_DOMAIN_DISPLAY_NAME => Attribute::DomainDisplayName,
|
||||
ATTR_DOMAIN_LDAP_BASEDN => Attribute::DomainLdapBasedn,
|
||||
ATTR_DOMAIN_NAME => Attribute::DomainName,
|
||||
|
@ -215,16 +243,22 @@ impl TryFrom<String> for Attribute {
|
|||
ATTR_EMAIL => Attribute::Email,
|
||||
ATTR_EMAIL_ALTERNATIVE => Attribute::EmailAlternative,
|
||||
ATTR_EMAIL_PRIMARY => Attribute::EmailPrimary,
|
||||
ATTR_ENTRYDN => Attribute::EntryDn,
|
||||
ATTR_ENTRYUUID => Attribute::EntryUuid,
|
||||
ATTR_ES256_PRIVATE_KEY_DER => Attribute::Es256PrivateKeyDer,
|
||||
ATTR_EXCLUDES => Attribute::Excludes,
|
||||
ATTR_FERNET_PRIVATE_KEY_STR => Attribute::FernetPrivateKeyStr,
|
||||
ATTR_GROUP => Attribute::Group,
|
||||
ATTR_GIDNUMBER => Attribute::GidNumber,
|
||||
ATTR_GRANT_UI_HINT => Attribute::GrantUiHint,
|
||||
ATTR_GROUP => Attribute::Group,
|
||||
ATTR_ID_VERIFICATION_ECKEY => Attribute::IdVerificationEcKey,
|
||||
ATTR_INDEX => Attribute::Index,
|
||||
ATTR_IPANTHASH => Attribute::IpaNtHash,
|
||||
ATTR_JWS_ES256_PRIVATE_KEY => Attribute::JwsEs256PrivateKey,
|
||||
ATTR_LAST_MODIFIED_CID => Attribute::LastModifiedCid,
|
||||
ATTR_LDAP_EMAIL_ADDRESS => Attribute::LdapEmailAddress,
|
||||
ATTR_LDAP_KEYS => Attribute::LdapKeys,
|
||||
ATTR_LDAP_SSH_PUBLICKEY => Attribute::SshPublicKey,
|
||||
ATTR_LEGALNAME => Attribute::LegalName,
|
||||
ATTR_LOGINSHELL => Attribute::LoginShell,
|
||||
ATTR_MAIL => Attribute::Mail,
|
||||
|
@ -263,20 +297,26 @@ impl TryFrom<String> for Attribute {
|
|||
ATTR_RADIUS_SECRET => Attribute::RadiusSecret,
|
||||
ATTR_REPLICATED => Attribute::Replicated,
|
||||
ATTR_RS256_PRIVATE_KEY_DER => Attribute::Rs256PrivateKeyDer,
|
||||
ATTR_SCOPE => Attribute::Scope,
|
||||
ATTR_SOURCE_UUID => Attribute::SourceUuid,
|
||||
ATTR_SPN => Attribute::Spn,
|
||||
ATTR_LDAP_SSH_PUBLICKEY => Attribute::SshPublicKey,
|
||||
ATTR_SSHPUBLICKEY => Attribute::LdapSshPublicKey,
|
||||
ATTR_SUPPLEMENTS => Attribute::Supplements,
|
||||
ATTR_SYNC_ALLOWED => Attribute::SyncAllowed,
|
||||
ATTR_SYNC_CLASS => Attribute::SyncClass,
|
||||
ATTR_SYNC_COOKIE => Attribute::SyncCookie,
|
||||
ATTR_SYNC_CREDENTIAL_PORTAL => Attribute::SyncCredentialPortal,
|
||||
ATTR_SYNC_EXTERNAL_ID => Attribute::SyncExternalId,
|
||||
ATTR_SYNC_PARENT_UUID => Attribute::SyncParentUuid,
|
||||
ATTR_SYNC_TOKEN_SESSION => Attribute::SyncTokenSession,
|
||||
ATTR_SYNC_YIELD_AUTHORITY => Attribute::SyncYieldAuthority,
|
||||
ATTR_SYNTAX => Attribute::Syntax,
|
||||
ATTR_SYSTEMEXCLUDES => Attribute::SystemExcludes,
|
||||
ATTR_SYSTEMMAY => Attribute::SystemMay,
|
||||
ATTR_SYSTEMMUST => Attribute::SystemMust,
|
||||
ATTR_SYSTEMSUPPLEMENTS => Attribute::SystemSupplements,
|
||||
ATTR_TERM => Attribute::Term,
|
||||
ATTR_TOTP_IMPORT => Attribute::TotpImport,
|
||||
ATTR_UID => Attribute::Uid,
|
||||
ATTR_UIDNUMBER => Attribute::UidNumber,
|
||||
ATTR_UNIQUE => Attribute::Unique,
|
||||
|
@ -293,6 +333,10 @@ impl TryFrom<String> for Attribute {
|
|||
TEST_ATTR_TEST_ATTR => Attribute::TestAttr,
|
||||
#[cfg(any(debug_assertions, test))]
|
||||
TEST_ATTR_EXTRA => Attribute::Extra,
|
||||
#[cfg(any(debug_assertions, test))]
|
||||
TEST_ATTR_NUMBER => Attribute::TestNumber,
|
||||
#[cfg(any(debug_assertions, test))]
|
||||
TEST_ATTR_NOTALLOWED => Attribute::TestNotAllowed,
|
||||
_ => return Err(OperationError::InvalidAttributeName(val)),
|
||||
};
|
||||
Ok(res)
|
||||
|
@ -303,76 +347,76 @@ impl From<Attribute> for &'static str {
|
|||
fn from(val: Attribute) -> Self {
|
||||
match val {
|
||||
Attribute::Account => ATTR_ACCOUNT,
|
||||
Attribute::SystemMay => ATTR_SYSTEMMAY,
|
||||
Attribute::DynGroup => ATTR_DYNGROUP,
|
||||
Attribute::May => ATTR_MAY,
|
||||
Attribute::DomainDisplayName => ATTR_DOMAIN_DISPLAY_NAME,
|
||||
Attribute::SyncCredentialPortal => ATTR_SYNC_CREDENTIAL_PORTAL,
|
||||
Attribute::SyncCookie => ATTR_SYNC_COOKIE,
|
||||
Attribute::SyncYieldAuthority => ATTR_SYNC_YIELD_AUTHORITY,
|
||||
Attribute::SyncTokenSession => ATTR_SYNC_TOKEN_SESSION,
|
||||
Attribute::Es256PrivateKeyDer => ATTR_ES256_PRIVATE_KEY_DER,
|
||||
Attribute::Rs256PrivateKeyDer => ATTR_RS256_PRIVATE_KEY_DER,
|
||||
Attribute::SystemMust => ATTR_SYSTEMMUST,
|
||||
Attribute::AccountExpire => ATTR_ACCOUNT_EXPIRE,
|
||||
Attribute::AccountValidFrom => ATTR_ACCOUNT_VALID_FROM,
|
||||
Attribute::LegalName => ATTR_LEGALNAME,
|
||||
Attribute::DeviceKeys => ATTR_DEVICEKEYS,
|
||||
Attribute::DynGroupFilter => ATTR_DYNGROUP_FILTER,
|
||||
Attribute::UnixPassword => ATTR_UNIX_PASSWORD,
|
||||
Attribute::RadiusSecret => ATTR_RADIUS_SECRET,
|
||||
Attribute::NameHistory => ATTR_NAME_HISTORY,
|
||||
Attribute::Must => ATTR_MUST,
|
||||
Attribute::AcpCreateAttr => ATTR_ACP_CREATE_ATTR,
|
||||
Attribute::AcpCreateClass => ATTR_ACP_CREATE_CLASS,
|
||||
Attribute::AcpEnable => ATTR_ACP_ENABLE,
|
||||
Attribute::AcpModifyClass => ATTR_ACP_MODIFY_CLASS,
|
||||
Attribute::AcpModifyPresentAttr => ATTR_ACP_MODIFY_PRESENTATTR,
|
||||
Attribute::AcpModifyRemovedAttr => ATTR_ACP_MODIFY_REMOVEDATTR,
|
||||
Attribute::AcpReceiver => ATTR_ACP_RECEIVER,
|
||||
Attribute::AcpReceiverGroup => ATTR_ACP_RECEIVER_GROUP,
|
||||
Attribute::AcpSearchAttr => ATTR_ACP_SEARCH_ATTR,
|
||||
Attribute::AcpTargetScope => ATTR_ACP_TARGET_SCOPE,
|
||||
Attribute::ApiTokenSession => ATTR_API_TOKEN_SESSION,
|
||||
Attribute::Attr => ATTR_ATTR,
|
||||
Attribute::Group => ATTR_GROUP,
|
||||
Attribute::DomainLdapBasedn => ATTR_DOMAIN_LDAP_BASEDN,
|
||||
Attribute::FernetPrivateKeyStr => ATTR_FERNET_PRIVATE_KEY_STR,
|
||||
Attribute::CookiePrivateKey => ATTR_COOKIE_PRIVATE_KEY,
|
||||
|
||||
Attribute::NsUniqueId => ATTR_NSUNIQUEID,
|
||||
Attribute::IdVerificationEcKey => ATTR_ID_VERIFICATION_ECKEY,
|
||||
|
||||
Attribute::DomainSsid => ATTR_DOMAIN_SSID,
|
||||
Attribute::AttributeName => ATTR_ATTRIBUTENAME,
|
||||
Attribute::AttributeType => ATTR_ATTRIBUTETYPE,
|
||||
Attribute::AuthSessionExpiry => ATTR_AUTH_SESSION_EXPIRY,
|
||||
Attribute::BadlistPassword => ATTR_BADLIST_PASSWORD,
|
||||
Attribute::Claim => ATTR_CLAIM,
|
||||
Attribute::Class => ATTR_CLASS,
|
||||
Attribute::ClassName => ATTR_CLASSNAME,
|
||||
Attribute::Cn => ATTR_CN,
|
||||
Attribute::CookiePrivateKey => ATTR_COOKIE_PRIVATE_KEY,
|
||||
Attribute::CredentialUpdateIntentToken => ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN,
|
||||
Attribute::Description => ATTR_DESCRIPTION,
|
||||
Attribute::DeviceKeys => ATTR_DEVICEKEYS,
|
||||
Attribute::DirectMemberOf => ATTR_DIRECTMEMBEROF,
|
||||
Attribute::DisplayName => ATTR_DISPLAYNAME,
|
||||
Attribute::Dn => ATTR_DN,
|
||||
Attribute::Domain => ATTR_DOMAIN,
|
||||
Attribute::DomainDisplayName => ATTR_DOMAIN_DISPLAY_NAME,
|
||||
Attribute::DomainLdapBasedn => ATTR_DOMAIN_LDAP_BASEDN,
|
||||
Attribute::DomainName => ATTR_DOMAIN_NAME,
|
||||
Attribute::DomainUuid => ATTR_DOMAIN_UUID,
|
||||
Attribute::DomainSsid => ATTR_DOMAIN_SSID,
|
||||
Attribute::DomainTokenKey => ATTR_DOMAIN_TOKEN_KEY,
|
||||
Attribute::DomainUuid => ATTR_DOMAIN_UUID,
|
||||
Attribute::DynGroup => ATTR_DYNGROUP,
|
||||
Attribute::DynGroupFilter => ATTR_DYNGROUP_FILTER,
|
||||
Attribute::DynMember => ATTR_DYNMEMBER,
|
||||
Attribute::Email => ATTR_EMAIL,
|
||||
Attribute::EmailAlternative => ATTR_EMAIL_ALTERNATIVE,
|
||||
Attribute::EmailPrimary => ATTR_EMAIL_PRIMARY,
|
||||
Attribute::EntryDn => ATTR_ENTRYDN,
|
||||
Attribute::EntryUuid => ATTR_ENTRYUUID,
|
||||
Attribute::Es256PrivateKeyDer => ATTR_ES256_PRIVATE_KEY_DER,
|
||||
Attribute::Excludes => ATTR_EXCLUDES,
|
||||
Attribute::FernetPrivateKeyStr => ATTR_FERNET_PRIVATE_KEY_STR,
|
||||
Attribute::GidNumber => ATTR_GIDNUMBER,
|
||||
Attribute::GrantUiHint => ATTR_GRANT_UI_HINT,
|
||||
Attribute::Group => ATTR_GROUP,
|
||||
Attribute::IdVerificationEcKey => ATTR_ID_VERIFICATION_ECKEY,
|
||||
Attribute::Index => ATTR_INDEX,
|
||||
Attribute::IpaNtHash => ATTR_IPANTHASH,
|
||||
Attribute::JwsEs256PrivateKey => ATTR_JWS_ES256_PRIVATE_KEY,
|
||||
Attribute::LastModifiedCid => ATTR_LAST_MODIFIED_CID,
|
||||
Attribute::LdapEmailAddress => ATTR_LDAP_EMAIL_ADDRESS,
|
||||
Attribute::LdapKeys => ATTR_LDAP_KEYS,
|
||||
Attribute::LdapSshPublicKey => ATTR_SSHPUBLICKEY,
|
||||
Attribute::LegalName => ATTR_LEGALNAME,
|
||||
Attribute::LoginShell => ATTR_LOGINSHELL,
|
||||
Attribute::Mail => ATTR_MAIL,
|
||||
Attribute::May => ATTR_MAY,
|
||||
Attribute::Member => ATTR_MEMBER,
|
||||
Attribute::MemberOf => ATTR_MEMBEROF,
|
||||
Attribute::MultiValue => ATTR_MULTIVALUE,
|
||||
Attribute::Must => ATTR_MUST,
|
||||
Attribute::Name => ATTR_NAME,
|
||||
Attribute::NameHistory => ATTR_NAME_HISTORY,
|
||||
Attribute::NoIndex => ATTR_NO_INDEX,
|
||||
Attribute::NsUniqueId => ATTR_NSUNIQUEID,
|
||||
Attribute::OAuth2AllowInsecureClientDisablePkce => {
|
||||
ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE
|
||||
}
|
||||
|
@ -391,23 +435,38 @@ impl From<Attribute> for &'static str {
|
|||
Attribute::ObjectClass => ATTR_OBJECTCLASS,
|
||||
Attribute::OtherNoIndex => ATTR_OTHER_NO_INDEX,
|
||||
Attribute::PassKeys => ATTR_PASSKEYS,
|
||||
|
||||
Attribute::PasswordImport => ATTR_PASSWORD_IMPORT,
|
||||
Attribute::Phantom => ATTR_PHANTOM,
|
||||
Attribute::PrimaryCredential => ATTR_PRIMARY_CREDENTIAL,
|
||||
Attribute::PrivateCookieKey => ATTR_PRIVATE_COOKIE_KEY,
|
||||
Attribute::PrivilegeExpiry => ATTR_PRIVILEGE_EXPIRY,
|
||||
Attribute::RadiusSecret => ATTR_RADIUS_SECRET,
|
||||
Attribute::Replicated => ATTR_REPLICATED,
|
||||
Attribute::Rs256PrivateKeyDer => ATTR_RS256_PRIVATE_KEY_DER,
|
||||
Attribute::Scope => ATTR_SCOPE,
|
||||
Attribute::SourceUuid => ATTR_SOURCE_UUID,
|
||||
Attribute::Spn => ATTR_SPN,
|
||||
Attribute::LdapSshPublicKey => ATTR_SSHPUBLICKEY,
|
||||
Attribute::SshPublicKey => ATTR_LDAP_SSH_PUBLICKEY,
|
||||
Attribute::Supplements => ATTR_SUPPLEMENTS,
|
||||
Attribute::SyncAllowed => ATTR_SYNC_ALLOWED,
|
||||
Attribute::SyncClass => ATTR_SYNC_CLASS,
|
||||
Attribute::SyncCookie => ATTR_SYNC_COOKIE,
|
||||
Attribute::SyncCredentialPortal => ATTR_SYNC_CREDENTIAL_PORTAL,
|
||||
Attribute::SyncExternalId => ATTR_SYNC_EXTERNAL_ID,
|
||||
Attribute::SyncParentUuid => ATTR_SYNC_PARENT_UUID,
|
||||
Attribute::SyncTokenSession => ATTR_SYNC_TOKEN_SESSION,
|
||||
Attribute::SyncYieldAuthority => ATTR_SYNC_YIELD_AUTHORITY,
|
||||
Attribute::Syntax => ATTR_SYNTAX,
|
||||
Attribute::SystemExcludes => ATTR_SYSTEMEXCLUDES,
|
||||
Attribute::SystemMay => ATTR_SYSTEMMAY,
|
||||
Attribute::SystemMust => ATTR_SYSTEMMUST,
|
||||
Attribute::SystemSupplements => ATTR_SYSTEMSUPPLEMENTS,
|
||||
Attribute::Term => ATTR_TERM,
|
||||
Attribute::TotpImport => ATTR_TOTP_IMPORT,
|
||||
Attribute::Uid => ATTR_UID,
|
||||
Attribute::UidNumber => ATTR_UIDNUMBER,
|
||||
Attribute::Unique => ATTR_UNIQUE,
|
||||
Attribute::UnixPassword => ATTR_UNIX_PASSWORD,
|
||||
Attribute::UserAuthTokenSession => ATTR_USER_AUTH_TOKEN_SESSION,
|
||||
Attribute::UserId => ATTR_USERID,
|
||||
Attribute::UserPassword => ATTR_USERPASSWORD,
|
||||
|
@ -420,8 +479,10 @@ impl From<Attribute> for &'static str {
|
|||
Attribute::TestAttr => TEST_ATTR_TEST_ATTR,
|
||||
#[cfg(any(debug_assertions, test))]
|
||||
Attribute::Extra => TEST_ATTR_EXTRA,
|
||||
Attribute::AuthSessionExpiry => ATTR_AUTH_SESSION_EXPIRY,
|
||||
Attribute::PrivilegeExpiry => ATTR_PRIVILEGE_EXPIRY,
|
||||
#[cfg(any(debug_assertions, test))]
|
||||
Attribute::TestNumber => TEST_ATTR_NUMBER,
|
||||
#[cfg(any(debug_assertions, test))]
|
||||
Attribute::TestNotAllowed => TEST_ATTR_NOTALLOWED,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -255,7 +255,9 @@ where
|
|||
{
|
||||
/// Get the uuid of this entry.
|
||||
pub(crate) fn get_uuid(&self) -> Option<Uuid> {
|
||||
self.attrs.get("uuid").and_then(|vs| vs.to_uuid_single())
|
||||
self.attrs
|
||||
.get(Attribute::Uuid.as_ref())
|
||||
.and_then(|vs| vs.to_uuid_single())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -352,6 +354,7 @@ impl Entry<EntryInit, EntryNew> {
|
|||
if vs.is_empty() {
|
||||
None
|
||||
} else {
|
||||
// TODO: this should be an "Attribute::from(k)"
|
||||
let attr = AttrString::from(k.to_lowercase());
|
||||
let vv: ValueSet = match attr.as_str() {
|
||||
kanidm_proto::constants::ATTR_ATTRIBUTENAME | kanidm_proto::constants::ATTR_CLASSNAME | kanidm_proto::constants::ATTR_DOMAIN => {
|
||||
|
@ -618,6 +621,10 @@ impl Entry<EntryInit, EntryNew> {
|
|||
// event for the attribute.
|
||||
/// Add an attribute-value-assertion to this Entry.
|
||||
pub fn add_ava(&mut self, attr: &str, value: Value) {
|
||||
// TODO: attr can be replaced with Attribute and this can go away
|
||||
#[allow(clippy::panic)]
|
||||
let attr =
|
||||
Attribute::try_from(attr).unwrap_or_else(|_| panic!("Invalid attribute {}", attr));
|
||||
self.add_ava_int(attr, value);
|
||||
}
|
||||
|
||||
|
@ -794,7 +801,7 @@ impl Entry<EntryIncremental, EntryNew> {
|
|||
// We need to make a random uuid in the conflict gen process.
|
||||
let new_uuid = Uuid::new_v4();
|
||||
cnf_ent.purge_ava("uuid");
|
||||
cnf_ent.add_ava("uuid", Value::Uuid(new_uuid));
|
||||
cnf_ent.add_ava(Attribute::Uuid.as_ref(), Value::Uuid(new_uuid));
|
||||
cnf_ent.add_ava(Attribute::Class.as_ref(), EntryClass::Recycled.into());
|
||||
cnf_ent.add_ava(Attribute::Class.as_ref(), EntryClass::Conflict.into());
|
||||
|
||||
|
@ -1075,9 +1082,9 @@ impl Entry<EntryIncremental, EntryCommitted> {
|
|||
|
||||
if let Err(e) = ne.validate(schema) {
|
||||
warn!(uuid = ?self.valid.uuid, err = ?e, "Entry failed schema check, moving to a conflict state");
|
||||
ne.add_ava_int(Attribute::Class.as_ref(), EntryClass::Recycled.into());
|
||||
ne.add_ava_int(Attribute::Class.as_ref(), EntryClass::Conflict.into());
|
||||
ne.add_ava_int(Attribute::SourceUuid.as_ref(), Value::Uuid(self.valid.uuid));
|
||||
ne.add_ava_int(Attribute::Class, EntryClass::Recycled.into());
|
||||
ne.add_ava_int(Attribute::Class, EntryClass::Conflict.into());
|
||||
ne.add_ava_int(Attribute::SourceUuid, Value::Uuid(self.valid.uuid));
|
||||
}
|
||||
ne
|
||||
}
|
||||
|
@ -1330,7 +1337,7 @@ impl Entry<EntrySealed, EntryCommitted> {
|
|||
/// Insert a claim to this entry. This claim can NOT be persisted to disk, this is only
|
||||
/// used during a single Event session.
|
||||
pub fn insert_claim(&mut self, value: &str) {
|
||||
self.add_ava_int("claim", Value::new_iutf8(value));
|
||||
self.add_ava_int(Attribute::Claim, Value::new_iutf8(value));
|
||||
}
|
||||
|
||||
pub fn compare(&self, rhs: &Entry<EntrySealed, EntryCommitted>) -> bool {
|
||||
|
@ -1370,7 +1377,11 @@ impl Entry<EntrySealed, EntryCommitted> {
|
|||
// * name
|
||||
// * gidnumber
|
||||
|
||||
let cands = ["spn", "name", "gidnumber"];
|
||||
let cands = [
|
||||
Attribute::Spn.as_ref(),
|
||||
Attribute::Name.as_ref(),
|
||||
Attribute::GidNumber.as_ref(),
|
||||
];
|
||||
cands
|
||||
.iter()
|
||||
.filter_map(|c| self.attrs.get(*c).map(|vs| vs.to_proto_string_clone_iter()))
|
||||
|
@ -1394,7 +1405,11 @@ impl Entry<EntrySealed, EntryCommitted> {
|
|||
self.attrs
|
||||
.get("spn")
|
||||
.and_then(|vs| vs.to_value_single())
|
||||
.or_else(|| self.attrs.get("name").and_then(|vs| vs.to_value_single()))
|
||||
.or_else(|| {
|
||||
self.attrs
|
||||
.get(Attribute::Name.as_ref())
|
||||
.and_then(|vs| vs.to_value_single())
|
||||
})
|
||||
.unwrap_or_else(|| Value::Uuid(self.get_uuid()))
|
||||
}
|
||||
|
||||
|
@ -1406,7 +1421,7 @@ impl Entry<EntrySealed, EntryCommitted> {
|
|||
.and_then(|vs| vs.to_proto_string_single().map(|v| format!("spn={v}")))
|
||||
.or_else(|| {
|
||||
self.attrs
|
||||
.get("name")
|
||||
.get(Attribute::Name.as_ref())
|
||||
.and_then(|vs| vs.to_proto_string_single().map(|v| format!("name={v}")))
|
||||
})
|
||||
.unwrap_or_else(|| format!("uuid={}", self.get_uuid().as_hyphenated()))
|
||||
|
@ -2345,8 +2360,8 @@ impl<VALID, STATE> Entry<VALID, STATE> {
|
|||
/// If the value already existed, or was unable to be added, false is returned. Alternately,
|
||||
/// you can think of this boolean as "if a write occurred to the structure", true indicating that
|
||||
/// a change occurred.
|
||||
fn add_ava_int(&mut self, attr: &str, value: Value) -> bool {
|
||||
if let Some(vs) = self.attrs.get_mut(attr) {
|
||||
fn add_ava_int(&mut self, attr: Attribute, value: Value) -> bool {
|
||||
if let Some(vs) = self.attrs.get_mut(attr.as_ref()) {
|
||||
let r = vs.insert_checked(value);
|
||||
debug_assert!(r.is_ok());
|
||||
// Default to the value not being present if wrong typed.
|
||||
|
@ -2355,7 +2370,7 @@ impl<VALID, STATE> Entry<VALID, STATE> {
|
|||
#[allow(clippy::expect_used)]
|
||||
let vs = valueset::from_value_iter(std::iter::once(value))
|
||||
.expect("Unable to fail - non-zero iter, and single value type!");
|
||||
self.attrs.insert(AttrString::from(attr), vs);
|
||||
self.attrs.insert(attr.into(), vs);
|
||||
// The attribute did not exist before.
|
||||
true
|
||||
}
|
||||
|
@ -2393,10 +2408,18 @@ impl<VALID, STATE> Entry<VALID, STATE> {
|
|||
|
||||
pub(crate) fn get_display_id(&self) -> String {
|
||||
self.attrs
|
||||
.get("spn")
|
||||
.get(Attribute::Spn.as_ref())
|
||||
.and_then(|vs| vs.to_value_single())
|
||||
.or_else(|| self.attrs.get("name").and_then(|vs| vs.to_value_single()))
|
||||
.or_else(|| self.attrs.get("uuid").and_then(|vs| vs.to_value_single()))
|
||||
.or_else(|| {
|
||||
self.attrs
|
||||
.get(Attribute::Name.as_ref())
|
||||
.and_then(|vs| vs.to_value_single())
|
||||
})
|
||||
.or_else(|| {
|
||||
self.attrs
|
||||
.get(Attribute::Uuid.as_ref())
|
||||
.and_then(|vs| vs.to_value_single())
|
||||
})
|
||||
.map(|value| value.to_proto_string_clone())
|
||||
.unwrap_or_else(|| "no entry id available".to_string())
|
||||
}
|
||||
|
@ -2922,14 +2945,25 @@ where
|
|||
// we need this to be *state* based where we assert presence.
|
||||
pub fn add_ava(&mut self, attr: &str, value: Value) {
|
||||
self.valid.ecstate.change_ava(&self.valid.cid, attr);
|
||||
// TODO: attr can be replaced with Attribute and this can go away
|
||||
#[allow(clippy::panic)]
|
||||
let attr =
|
||||
Attribute::try_from(attr).unwrap_or_else(|_| panic!("Invalid attribute {}", attr));
|
||||
self.add_ava_int(attr, value);
|
||||
}
|
||||
|
||||
pub fn add_ava_if_not_exist(&mut self, attr: &str, value: Value) {
|
||||
// This returns true if the value WAS changed! See add_ava_int.
|
||||
|
||||
// TODO: attr can be replaced with Attribute and this can go away
|
||||
#[allow(clippy::panic)]
|
||||
let attr =
|
||||
Attribute::try_from(attr).unwrap_or_else(|_| panic!("Invalid attribute {}", attr));
|
||||
if self.add_ava_int(attr, value) {
|
||||
// In this case, we ONLY update the changestate if the value was already present!
|
||||
self.valid.ecstate.change_ava(&self.valid.cid, attr);
|
||||
self.valid
|
||||
.ecstate
|
||||
.change_ava(&self.valid.cid, attr.as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3095,18 +3129,18 @@ impl From<&SchemaAttribute> for Entry<EntryInit, EntryNew> {
|
|||
// Build the Map of the attributes relevant
|
||||
// let mut attrs: Map<AttrString, Set<Value>> = Map::with_capacity(8);
|
||||
let mut attrs: Map<AttrString, ValueSet> = Map::new();
|
||||
attrs.insert(AttrString::from("attributename"), name_v);
|
||||
attrs.insert(AttrString::from(Attribute::Description.as_ref()), desc_v);
|
||||
attrs.insert(Attribute::AttributeName.into(), name_v);
|
||||
attrs.insert(Attribute::Description.into(), desc_v);
|
||||
attrs.insert(Attribute::Uuid.into(), uuid_v);
|
||||
attrs.insert(AttrString::from("multivalue"), multivalue_v);
|
||||
attrs.insert(AttrString::from("phantom"), phantom_v);
|
||||
attrs.insert(AttrString::from("sync_allowed"), sync_allowed_v);
|
||||
attrs.insert(AttrString::from("replicated"), replicated_v);
|
||||
attrs.insert(AttrString::from("unique"), unique_v);
|
||||
attrs.insert(Attribute::MultiValue.into(), multivalue_v);
|
||||
attrs.insert(Attribute::Phantom.into(), phantom_v);
|
||||
attrs.insert(Attribute::SyncAllowed.into(), sync_allowed_v);
|
||||
attrs.insert(Attribute::Replicated.into(), replicated_v);
|
||||
attrs.insert(Attribute::Unique.into(), unique_v);
|
||||
if let Some(vs) = index_v {
|
||||
attrs.insert(AttrString::from("index"), vs);
|
||||
attrs.insert(Attribute::Index.into(), vs);
|
||||
}
|
||||
attrs.insert(AttrString::from("syntax"), syntax_v);
|
||||
attrs.insert(Attribute::Syntax.into(), syntax_v);
|
||||
attrs.insert(
|
||||
Attribute::Class.into(),
|
||||
vs_iutf8!["object", "system", "attributetype"],
|
||||
|
@ -3131,24 +3165,28 @@ impl From<&SchemaClass> for Entry<EntryInit, EntryNew> {
|
|||
|
||||
// let mut attrs: Map<AttrString, Set<Value>> = Map::with_capacity(8);
|
||||
let mut attrs: Map<AttrString, ValueSet> = Map::new();
|
||||
attrs.insert(AttrString::from("classname"), name_v);
|
||||
attrs.insert(AttrString::from(Attribute::Description.as_ref()), desc_v);
|
||||
attrs.insert(AttrString::from("sync_allowed"), sync_allowed_v);
|
||||
attrs.insert(Attribute::ClassName.into(), name_v);
|
||||
attrs.insert(Attribute::Description.into(), desc_v);
|
||||
attrs.insert(Attribute::SyncAllowed.into(), sync_allowed_v);
|
||||
attrs.insert(Attribute::Uuid.into(), uuid_v);
|
||||
attrs.insert(
|
||||
Attribute::Class.into(),
|
||||
vs_iutf8!["object", "system", "classtype"],
|
||||
vs_iutf8![
|
||||
EntryClass::Object.into(),
|
||||
EntryClass::System.into(),
|
||||
EntryClass::ClassType.into()
|
||||
],
|
||||
);
|
||||
|
||||
let vs_systemmay = ValueSetIutf8::from_iter(s.systemmay.iter().map(|sm| sm.as_str()));
|
||||
if let Some(vs) = vs_systemmay {
|
||||
attrs.insert(AttrString::from("systemmay"), vs);
|
||||
attrs.insert(Attribute::SystemMay.into(), vs);
|
||||
}
|
||||
|
||||
let vs_systemmust = ValueSetIutf8::from_iter(s.systemmust.iter().map(|sm| sm.as_str()));
|
||||
|
||||
if let Some(vs) = vs_systemmust {
|
||||
attrs.insert(AttrString::from("systemmust"), vs);
|
||||
attrs.insert(Attribute::SystemMust.into(), vs);
|
||||
}
|
||||
|
||||
Entry {
|
||||
|
@ -3165,7 +3203,6 @@ mod tests {
|
|||
use std::collections::BTreeSet as Set;
|
||||
|
||||
use hashbrown::HashMap;
|
||||
use smartstring::alias::String as AttrString;
|
||||
|
||||
use crate::be::{IdxKey, IdxSlope};
|
||||
use crate::entry::{Entry, EntryInit, EntryInvalid, EntryNew};
|
||||
|
@ -3176,7 +3213,7 @@ mod tests {
|
|||
fn test_entry_basic() {
|
||||
let mut e: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
|
||||
e.add_ava("userid", Value::from("william"));
|
||||
e.add_ava(Attribute::UserId.as_ref(), Value::from("william"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -3256,19 +3293,19 @@ mod tests {
|
|||
let pv10 = PartialValue::new_uint32(10);
|
||||
let pv15 = PartialValue::new_uint32(15);
|
||||
|
||||
e1.add_ava("a", Value::new_uint32(10));
|
||||
e1.add_ava("testattr", Value::new_uint32(10));
|
||||
|
||||
assert!(!e1.attribute_lessthan("a", &pv2));
|
||||
assert!(!e1.attribute_lessthan("a", &pv8));
|
||||
assert!(!e1.attribute_lessthan("a", &pv10));
|
||||
assert!(e1.attribute_lessthan("a", &pv15));
|
||||
assert!(!e1.attribute_lessthan("testattr", &pv2));
|
||||
assert!(!e1.attribute_lessthan("testattr", &pv8));
|
||||
assert!(!e1.attribute_lessthan("testattr", &pv10));
|
||||
assert!(e1.attribute_lessthan("testattr", &pv15));
|
||||
|
||||
e1.add_ava("a", Value::new_uint32(8));
|
||||
e1.add_ava("testattr", Value::new_uint32(8));
|
||||
|
||||
assert!(!e1.attribute_lessthan("a", &pv2));
|
||||
assert!(!e1.attribute_lessthan("a", &pv8));
|
||||
assert!(e1.attribute_lessthan("a", &pv10));
|
||||
assert!(e1.attribute_lessthan("a", &pv15));
|
||||
assert!(!e1.attribute_lessthan("testattr", &pv2));
|
||||
assert!(!e1.attribute_lessthan("testattr", &pv8));
|
||||
assert!(e1.attribute_lessthan("testattr", &pv10));
|
||||
assert!(e1.attribute_lessthan("testattr", &pv15));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -3374,7 +3411,7 @@ mod tests {
|
|||
);
|
||||
idxmeta.insert(
|
||||
IdxKey {
|
||||
attr: AttrString::from("extra"),
|
||||
attr: Attribute::Extra.into(),
|
||||
itype: IndexType::Equality,
|
||||
},
|
||||
IdxSlope::MAX,
|
||||
|
@ -3438,7 +3475,7 @@ mod tests {
|
|||
assert!(
|
||||
add_a_r[0]
|
||||
== Ok((
|
||||
&AttrString::from("extra"),
|
||||
&Attribute::Extra.into(),
|
||||
IndexType::Equality,
|
||||
"test".to_string()
|
||||
))
|
||||
|
@ -3449,7 +3486,7 @@ mod tests {
|
|||
assert!(
|
||||
del_a_r[0]
|
||||
== Err((
|
||||
&AttrString::from("extra"),
|
||||
&Attribute::Extra.into(),
|
||||
IndexType::Equality,
|
||||
"test".to_string()
|
||||
))
|
||||
|
@ -3515,11 +3552,14 @@ mod tests {
|
|||
{
|
||||
let mut e: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e.add_ava(Attribute::Class.as_ref(), EntryClass::Person.to_value());
|
||||
e.add_ava("gidnumber", Value::new_uint32(1300));
|
||||
e.add_ava("name", Value::new_iname("testperson"));
|
||||
e.add_ava("spn", Value::new_spn_str("testperson", "example.com"));
|
||||
e.add_ava(Attribute::GidNumber.as_ref(), Value::new_uint32(1300));
|
||||
e.add_ava(Attribute::Name.as_ref(), Value::new_iname("testperson"));
|
||||
e.add_ava(
|
||||
"uuid",
|
||||
Attribute::Spn.as_ref(),
|
||||
Value::new_spn_str("testperson", "example.com"),
|
||||
);
|
||||
e.add_ava(
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::Uuid(uuid!("9fec0398-c46c-4df4-9df5-b0016f7d563f")),
|
||||
);
|
||||
let e = e.into_sealed_committed();
|
||||
|
@ -3561,13 +3601,19 @@ mod tests {
|
|||
{
|
||||
let mut e1: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e1.add_ava(Attribute::Class.as_ref(), EntryClass::Person.to_value());
|
||||
e1.add_ava("spn", Value::new_spn_str("testperson", "example.com"));
|
||||
e1.add_ava(
|
||||
Attribute::Spn.as_ref(),
|
||||
Value::new_spn_str("testperson", "example.com"),
|
||||
);
|
||||
let e1 = e1.into_sealed_committed();
|
||||
|
||||
let mut e2: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e2.add_ava(Attribute::Class.as_ref(), EntryClass::Person.to_value());
|
||||
e2.add_ava("name", Value::new_iname("testperson"));
|
||||
e2.add_ava("spn", Value::new_spn_str("testperson", "example.com"));
|
||||
e2.add_ava(Attribute::Name.as_ref(), Value::new_iname("testperson"));
|
||||
e2.add_ava(
|
||||
Attribute::Spn.as_ref(),
|
||||
Value::new_spn_str("testperson", "example.com"),
|
||||
);
|
||||
let e2 = e2.into_sealed_committed();
|
||||
|
||||
// One attr added
|
||||
|
@ -3587,12 +3633,18 @@ mod tests {
|
|||
{
|
||||
let mut e1: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e1.add_ava(Attribute::Class.as_ref(), EntryClass::Person.to_value());
|
||||
e1.add_ava("spn", Value::new_spn_str("testperson", "example.com"));
|
||||
e1.add_ava(
|
||||
Attribute::Spn.as_ref(),
|
||||
Value::new_spn_str("testperson", "example.com"),
|
||||
);
|
||||
let e1 = e1.into_sealed_committed();
|
||||
|
||||
let mut e2: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e2.add_ava(Attribute::Class.as_ref(), EntryClass::Person.to_value());
|
||||
e2.add_ava("spn", Value::new_spn_str("renameperson", "example.com"));
|
||||
e2.add_ava(
|
||||
Attribute::Spn.as_ref(),
|
||||
Value::new_spn_str("renameperson", "example.com"),
|
||||
);
|
||||
let e2 = e2.into_sealed_committed();
|
||||
|
||||
assert!(
|
||||
|
@ -3610,11 +3662,17 @@ mod tests {
|
|||
assert!(Entry::idx_uuid2spn_diff(None, None).is_none());
|
||||
|
||||
let mut e1: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e1.add_ava("spn", Value::new_spn_str("testperson", "example.com"));
|
||||
e1.add_ava(
|
||||
Attribute::Spn.as_ref(),
|
||||
Value::new_spn_str("testperson", "example.com"),
|
||||
);
|
||||
let e1 = e1.into_sealed_committed();
|
||||
|
||||
let mut e2: Entry<EntryInit, EntryNew> = Entry::new();
|
||||
e2.add_ava("spn", Value::new_spn_str("renameperson", "example.com"));
|
||||
e2.add_ava(
|
||||
Attribute::Spn.as_ref(),
|
||||
Value::new_spn_str("renameperson", "example.com"),
|
||||
);
|
||||
let e2 = e2.into_sealed_committed();
|
||||
|
||||
assert!(
|
||||
|
|
|
@ -38,8 +38,7 @@ const FILTER_DEPTH_MAX: usize = 16;
|
|||
// This is &Value so we can lazy const then clone, but perhaps we can reconsider
|
||||
// later if this should just take Value.
|
||||
pub fn f_eq<'a>(a: Attribute, v: PartialValue) -> FC<'a> {
|
||||
let a: &'static str = a.into();
|
||||
FC::Eq(a, v)
|
||||
FC::Eq(a.into(), v)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
@ -48,8 +47,8 @@ pub fn f_sub(a: &str, v: PartialValue) -> FC {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn f_pres(a: &str) -> FC {
|
||||
FC::Pres(a)
|
||||
pub fn f_pres<'a>(a: Attribute) -> FC<'a> {
|
||||
FC::Pres(a.into())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
@ -86,9 +85,9 @@ pub fn f_self<'a>() -> FC<'a> {
|
|||
pub fn f_id(id: &str) -> FC<'static> {
|
||||
let uf = Uuid::parse_str(id)
|
||||
.ok()
|
||||
.map(|u| FC::Eq("uuid", PartialValue::Uuid(u)));
|
||||
.map(|u| FC::Eq(Attribute::Uuid.as_ref(), PartialValue::Uuid(u)));
|
||||
let spnf = PartialValue::new_spn_s(id).map(|spn| FC::Eq("spn", spn));
|
||||
let nf = FC::Eq("name", PartialValue::new_iname(id));
|
||||
let nf = FC::Eq(Attribute::Name.as_ref(), PartialValue::new_iname(id));
|
||||
let f: Vec<_> = iter::once(uf)
|
||||
.chain(iter::once(spnf))
|
||||
.flatten()
|
||||
|
@ -99,8 +98,8 @@ pub fn f_id(id: &str) -> FC<'static> {
|
|||
|
||||
#[allow(dead_code)]
|
||||
pub fn f_spn_name(id: &str) -> FC<'static> {
|
||||
let spnf = PartialValue::new_spn_s(id).map(|spn| FC::Eq("spn", spn));
|
||||
let nf = FC::Eq("name", PartialValue::new_iname(id));
|
||||
let spnf = PartialValue::new_spn_s(id).map(|spn| FC::Eq(Attribute::Spn.as_ref(), spn));
|
||||
let nf = FC::Eq(Attribute::Name.as_ref(), PartialValue::new_iname(id));
|
||||
let f: Vec<_> = iter::once(spnf).flatten().chain(iter::once(nf)).collect();
|
||||
FC::Or(f)
|
||||
}
|
||||
|
@ -1152,7 +1151,7 @@ impl FilterResolved {
|
|||
// Since we have no index data, we manually configure a reasonable
|
||||
// slope and indicate the presence of some expected basic
|
||||
// indexes.
|
||||
let idx = matches!(a.as_str(), "name" | "uuid");
|
||||
let idx = matches!(a.as_str(), ATTR_NAME | ATTR_UUID);
|
||||
let idx = NonZeroU8::new(idx as u8);
|
||||
Some(FilterResolved::Eq(a, v, idx))
|
||||
}
|
||||
|
@ -1424,12 +1423,12 @@ mod tests {
|
|||
EntryClass::TestClass.to_partialvalue()
|
||||
)]),
|
||||
f_sub(Attribute::Class.as_ref(), PartialValue::new_class("te")),
|
||||
f_pres(Attribute::Class.as_ref()),
|
||||
f_pres(Attribute::Class),
|
||||
f_eq(Attribute::Class, EntryClass::TestClass.to_partialvalue())
|
||||
]),
|
||||
f_and(vec![
|
||||
f_eq(Attribute::Class, EntryClass::TestClass.to_partialvalue()),
|
||||
f_pres(Attribute::Class.as_ref()),
|
||||
f_pres(Attribute::Class),
|
||||
f_sub(Attribute::Class.as_ref(), PartialValue::new_class("te")),
|
||||
])
|
||||
);
|
||||
|
@ -1443,13 +1442,13 @@ mod tests {
|
|||
f_eq(Attribute::Uid, PartialValue::new_class("bar")),
|
||||
]),
|
||||
f_sub(Attribute::Class.as_ref(), PartialValue::new_class("te")),
|
||||
f_pres(Attribute::Class.as_ref()),
|
||||
f_pres(Attribute::Class),
|
||||
f_eq(Attribute::Class, EntryClass::TestClass.to_partialvalue())
|
||||
]),
|
||||
f_and(vec![
|
||||
f_eq(Attribute::Class, PartialValue::new_class("foo")),
|
||||
f_eq(Attribute::Class, EntryClass::TestClass.to_partialvalue()),
|
||||
f_pres(Attribute::Class.as_ref()),
|
||||
f_pres(Attribute::Class),
|
||||
f_eq(Attribute::Uid, PartialValue::new_class("bar")),
|
||||
f_sub(Attribute::Class.as_ref(), PartialValue::new_class("te")),
|
||||
])
|
||||
|
@ -1458,7 +1457,7 @@ mod tests {
|
|||
filter_optimise_assert!(
|
||||
f_or(vec![
|
||||
f_eq(Attribute::Class, EntryClass::TestClass.to_partialvalue()),
|
||||
f_pres(Attribute::Class.as_ref()),
|
||||
f_pres(Attribute::Class),
|
||||
f_sub(Attribute::Class.as_ref(), PartialValue::new_class("te")),
|
||||
f_or(vec![f_eq(
|
||||
Attribute::Class,
|
||||
|
@ -1467,7 +1466,7 @@ mod tests {
|
|||
]),
|
||||
f_or(vec![
|
||||
f_sub(Attribute::Class.as_ref(), PartialValue::new_class("te")),
|
||||
f_pres(Attribute::Class.as_ref()),
|
||||
f_pres(Attribute::Class),
|
||||
f_eq(Attribute::Class, EntryClass::TestClass.to_partialvalue())
|
||||
])
|
||||
);
|
||||
|
@ -1497,17 +1496,17 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_filter_eq() {
|
||||
let f_t1a = filter!(f_pres("userid"));
|
||||
let f_t1b = filter!(f_pres("userid"));
|
||||
let f_t1c = filter!(f_pres("zzzz"));
|
||||
let f_t1a = filter!(f_pres(Attribute::UserId));
|
||||
let f_t1b = filter!(f_pres(Attribute::UserId));
|
||||
let f_t1c = filter!(f_pres(Attribute::NonExist));
|
||||
|
||||
assert!(f_t1a == f_t1b);
|
||||
assert!(f_t1a != f_t1c);
|
||||
assert!(f_t1b != f_t1c);
|
||||
|
||||
let f_t2a = filter!(f_and!([f_pres("userid")]));
|
||||
let f_t2b = filter!(f_and!([f_pres("userid")]));
|
||||
let f_t2c = filter!(f_and!([f_pres("zzzz")]));
|
||||
let f_t2a = filter!(f_and!([f_pres(Attribute::UserId)]));
|
||||
let f_t2b = filter!(f_and!([f_pres(Attribute::UserId)]));
|
||||
let f_t2c = filter!(f_and!([f_pres(Attribute::NonExist)]));
|
||||
assert!(f_t2a == f_t2b);
|
||||
assert!(f_t2a != f_t2c);
|
||||
assert!(f_t2b != f_t2c);
|
||||
|
@ -1521,8 +1520,8 @@ mod tests {
|
|||
// Test that we uphold the rules of partialOrd
|
||||
// Basic equality
|
||||
// Test the two major paths here (str vs list)
|
||||
let f_t1a = filter_resolved!(f_pres("userid"));
|
||||
let f_t1b = filter_resolved!(f_pres("userid"));
|
||||
let f_t1a = filter_resolved!(f_pres(Attribute::UserId));
|
||||
let f_t1b = filter_resolved!(f_pres(Attribute::UserId));
|
||||
|
||||
assert_eq!(f_t1a.partial_cmp(&f_t1b), Some(Ordering::Equal));
|
||||
assert_eq!(f_t1b.partial_cmp(&f_t1a), Some(Ordering::Equal));
|
||||
|
@ -1551,16 +1550,16 @@ mod tests {
|
|||
fn test_filter_clone() {
|
||||
// Test that cloning filters yields the same result regardless of
|
||||
// complexity.
|
||||
let f_t1a = filter_resolved!(f_pres("userid"));
|
||||
let f_t1a = filter_resolved!(f_pres(Attribute::UserId));
|
||||
let f_t1b = f_t1a.clone();
|
||||
let f_t1c = filter_resolved!(f_pres("zzzz"));
|
||||
let f_t1c = filter_resolved!(f_pres(Attribute::NonExist));
|
||||
|
||||
assert!(f_t1a == f_t1b);
|
||||
assert!(f_t1a != f_t1c);
|
||||
|
||||
let f_t2a = filter_resolved!(f_and!([f_pres("userid")]));
|
||||
let f_t2a = filter_resolved!(f_and!([f_pres(Attribute::UserId)]));
|
||||
let f_t2b = f_t2a.clone();
|
||||
let f_t2c = filter_resolved!(f_and!([f_pres("zzzz")]));
|
||||
let f_t2c = filter_resolved!(f_and!([f_pres(Attribute::NonExist)]));
|
||||
|
||||
assert!(f_t2a == f_t2b);
|
||||
assert!(f_t2a != f_t2c);
|
||||
|
|
|
@ -628,7 +628,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
) -> Result<(), OperationError> {
|
||||
// Delete the attribute with uuid.
|
||||
let modlist = ModifyList::new_list(vec![Modify::Removed(
|
||||
AttrString::from("user_auth_token_session"),
|
||||
Attribute::UserAuthTokenSession.into(),
|
||||
PartialValue::Refer(dte.token_id),
|
||||
)]);
|
||||
|
||||
|
@ -870,7 +870,7 @@ mod tests {
|
|||
)),
|
||||
ModifyList::new_list(vec![
|
||||
Modify::Present(Attribute::Class.into(), EntryClass::PosixAccount.into()),
|
||||
Modify::Present(AttrString::from("gidnumber"), Value::new_uint32(2001)),
|
||||
Modify::Present(Attribute::GidNumber.into(), Value::new_uint32(2001)),
|
||||
]),
|
||||
);
|
||||
assert!(idms_prox_write.qs_write.modify(&me_posix).is_ok());
|
||||
|
|
|
@ -419,7 +419,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
.get_accesscontrols()
|
||||
.effective_permission_check(
|
||||
ident,
|
||||
Some(btreeset![AttrString::from("sync_credential_portal")]),
|
||||
Some(btreeset![Attribute::SyncCredentialPortal.into()]),
|
||||
&[entry],
|
||||
)?;
|
||||
|
||||
|
@ -607,7 +607,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
|
||||
if ct >= max_ttl {
|
||||
modlist.push_mod(Modify::Removed(
|
||||
AttrString::from("credential_update_intent_token"),
|
||||
Attribute::CredentialUpdateIntentToken.into(),
|
||||
PartialValue::IntentToken(existing_intent_id.clone()),
|
||||
));
|
||||
}
|
||||
|
@ -665,7 +665,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
let mut modlist = ModifyList::new();
|
||||
|
||||
modlist.push_mod(Modify::Removed(
|
||||
AttrString::from("credential_update_intent_token"),
|
||||
Attribute::CredentialUpdateIntentToken.into(),
|
||||
PartialValue::IntentToken(intent_id.clone()),
|
||||
));
|
||||
|
||||
|
@ -779,11 +779,11 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
let mut modlist = ModifyList::new();
|
||||
|
||||
modlist.push_mod(Modify::Removed(
|
||||
AttrString::from("credential_update_intent_token"),
|
||||
Attribute::CredentialUpdateIntentToken.into(),
|
||||
PartialValue::IntentToken(intent_id.clone()),
|
||||
));
|
||||
modlist.push_mod(Modify::Present(
|
||||
AttrString::from("credential_update_intent_token"),
|
||||
Attribute::CredentialUpdateIntentToken.into(),
|
||||
Value::IntentToken(
|
||||
intent_id.clone(),
|
||||
IntentTokenState::InProgress {
|
||||
|
@ -949,11 +949,11 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
};
|
||||
|
||||
modlist.push_mod(Modify::Removed(
|
||||
AttrString::from("credential_update_intent_token"),
|
||||
Attribute::CredentialUpdateIntentToken.into(),
|
||||
PartialValue::IntentToken(intent_token_id.clone()),
|
||||
));
|
||||
modlist.push_mod(Modify::Present(
|
||||
AttrString::from("credential_update_intent_token"),
|
||||
Attribute::CredentialUpdateIntentToken.into(),
|
||||
Value::IntentToken(
|
||||
intent_token_id.clone(),
|
||||
IntentTokenState::Consumed { max_ttl },
|
||||
|
@ -1050,11 +1050,11 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
};
|
||||
|
||||
modlist.push_mod(Modify::Removed(
|
||||
AttrString::from("credential_update_intent_token"),
|
||||
Attribute::CredentialUpdateIntentToken.into(),
|
||||
PartialValue::IntentToken(intent_token_id.clone()),
|
||||
));
|
||||
modlist.push_mod(Modify::Present(
|
||||
AttrString::from("credential_update_intent_token"),
|
||||
Attribute::CredentialUpdateIntentToken.into(),
|
||||
Value::IntentToken(
|
||||
intent_token_id.clone(),
|
||||
IntentTokenState::Valid { max_ttl, perms },
|
||||
|
|
|
@ -635,7 +635,7 @@ mod tests {
|
|||
filter!(f_eq(Attribute::Name, PartialValue::new_iname("admin"))),
|
||||
ModifyList::new_list(vec![
|
||||
Modify::Present(Attribute::Class.into(), EntryClass::PosixAccount.into()),
|
||||
Modify::Present(AttrString::from("gidnumber"), Value::new_uint32(2001)),
|
||||
Modify::Present(Attribute::GidNumber.into(), Value::new_uint32(2001)),
|
||||
]),
|
||||
);
|
||||
assert!(idms_prox_write.qs_write.modify(&me_posix).is_ok());
|
||||
|
@ -1057,7 +1057,7 @@ mod tests {
|
|||
PartialValue::new_iname("idm_people_read_priv")
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
Value::Refer(sa_uuid),
|
||||
)]),
|
||||
);
|
||||
|
|
|
@ -558,7 +558,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
// and when replication converges the session is actually removed.
|
||||
|
||||
let modlist = ModifyList::new_list(vec![Modify::Removed(
|
||||
AttrString::from("oauth2_session"),
|
||||
Attribute::OAuth2Session.into(),
|
||||
PartialValue::Refer(session_id),
|
||||
)]);
|
||||
|
||||
|
@ -729,11 +729,11 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
|
||||
let modlist = ModifyList::new_list(vec![
|
||||
Modify::Removed(
|
||||
AttrString::from("oauth2_consent_scope_map"),
|
||||
Attribute::OAuth2ConsentScopeMap.into(),
|
||||
PartialValue::Refer(o2rs.uuid),
|
||||
),
|
||||
Modify::Present(
|
||||
AttrString::from("oauth2_consent_scope_map"),
|
||||
Attribute::OAuth2ConsentScopeMap.into(),
|
||||
Value::OauthScopeMap(o2rs.uuid, consent_req.scopes.iter().cloned().collect()),
|
||||
),
|
||||
]);
|
||||
|
@ -931,7 +931,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
|
||||
// Revoke it
|
||||
let modlist = ModifyList::new_list(vec![Modify::Removed(
|
||||
AttrString::from("oauth2_session"),
|
||||
Attribute::OAuth2Session.into(),
|
||||
PartialValue::Refer(session_id),
|
||||
)]);
|
||||
|
||||
|
@ -2955,7 +2955,7 @@ mod tests {
|
|||
let me_inv_m = ModifyEvent::new_internal_invalid(
|
||||
filter!(f_eq(Attribute::Name, PartialValue::new_iname("admin"))),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("account_expire"),
|
||||
Attribute::AccountExpire.into(),
|
||||
v_expire,
|
||||
)]),
|
||||
);
|
||||
|
|
|
@ -161,7 +161,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
});
|
||||
|
||||
let modlist = ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("sync_token_session"),
|
||||
Attribute::SyncTokenSession.into(),
|
||||
session,
|
||||
)]);
|
||||
|
||||
|
@ -199,7 +199,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
_ct: Duration,
|
||||
) -> Result<(), OperationError> {
|
||||
let modlist =
|
||||
ModifyList::new_list(vec![Modify::Purged(AttrString::from("sync_token_session"))]);
|
||||
ModifyList::new_list(vec![Modify::Purged(Attribute::SyncTokenSession.into())]);
|
||||
|
||||
self.qs_write
|
||||
.impersonate_modify(
|
||||
|
@ -894,9 +894,9 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
|
||||
let secret = complex
|
||||
.attrs
|
||||
.get("secret")
|
||||
.get(SCIM_SECRET)
|
||||
.ok_or_else(|| {
|
||||
error!("Invalid scim complex attr - missing required key secret");
|
||||
error!("Invalid SCIM complex attr - missing required key secret");
|
||||
OperationError::InvalidAttribute(format!(
|
||||
"missing required key secret - {scim_attr_name}"
|
||||
))
|
||||
|
@ -920,7 +920,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
}
|
||||
})?;
|
||||
|
||||
let algo = complex.attrs.get("algo")
|
||||
let algo = complex.attrs.get(SCIM_ALGO)
|
||||
.ok_or_else(|| {
|
||||
error!("Invalid scim complex attr - missing required key algo");
|
||||
OperationError::InvalidAttribute(format!(
|
||||
|
@ -951,7 +951,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
}
|
||||
})?;
|
||||
|
||||
let step = complex.attrs.get("step").ok_or_else(|| {
|
||||
let step = complex.attrs.get(SCIM_STEP).ok_or_else(|| {
|
||||
error!("Invalid scim complex attr - missing required key step");
|
||||
OperationError::InvalidAttribute(format!(
|
||||
"missing required key step - {scim_attr_name}"
|
||||
|
@ -978,7 +978,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
|
||||
let digits = complex
|
||||
.attrs
|
||||
.get("digits")
|
||||
.get(SCIM_DIGITS)
|
||||
.ok_or_else(|| {
|
||||
error!("Invalid scim complex attr - missing required key digits");
|
||||
OperationError::InvalidAttribute(format!(
|
||||
|
@ -1627,7 +1627,7 @@ mod tests {
|
|||
Attribute::Name,
|
||||
PartialValue::new_iname("test_scim_sync")
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Purged(AttrString::from("sync_token_session"))]),
|
||||
ModifyList::new_list(vec![Modify::Purged(Attribute::SyncTokenSession.into())]),
|
||||
);
|
||||
assert!(idms_prox_write.qs_write.modify(&me_inv_m).is_ok());
|
||||
assert!(idms_prox_write.commit().is_ok());
|
||||
|
|
|
@ -2112,7 +2112,6 @@ mod tests {
|
|||
use std::time::Duration;
|
||||
|
||||
use kanidm_proto::v1::{AuthAllowed, AuthIssueSession, AuthMech, OperationError};
|
||||
use smartstring::alias::String as AttrString;
|
||||
use time::OffsetDateTime;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -2666,7 +2665,7 @@ mod tests {
|
|||
filter!(f_eq(Attribute::Name, PartialValue::new_iname("admin"))),
|
||||
ModifyList::new_list(vec![
|
||||
Modify::Present(Attribute::Class.into(), EntryClass::PosixAccount.into()),
|
||||
Modify::Present(AttrString::from("gidnumber"), Value::new_uint32(2001)),
|
||||
Modify::Present(Attribute::GidNumber.into(), Value::new_uint32(2001)),
|
||||
]),
|
||||
);
|
||||
assert!(idms_prox_write.qs_write.modify(&me_posix).is_ok());
|
||||
|
@ -2751,7 +2750,7 @@ mod tests {
|
|||
filter!(f_eq(Attribute::Name, PartialValue::new_iname("admin"))),
|
||||
ModifyList::new_list(vec![
|
||||
Modify::Present(Attribute::Class.into(), EntryClass::PosixAccount.into()),
|
||||
Modify::Present(AttrString::from("gidnumber"), Value::new_uint32(2001)),
|
||||
Modify::Present(Attribute::GidNumber.into(), Value::new_uint32(2001)),
|
||||
]),
|
||||
);
|
||||
assert!(idms_prox_write.qs_write.modify(&me_posix).is_ok());
|
||||
|
@ -2787,7 +2786,7 @@ mod tests {
|
|||
let mut idms_prox_write = idms.proxy_write(duration_from_epoch_now()).await;
|
||||
let me_purge_up = ModifyEvent::new_internal_invalid(
|
||||
filter!(f_eq(Attribute::Name, PartialValue::new_iname("admin"))),
|
||||
ModifyList::new_list(vec![Modify::Purged(AttrString::from("unix_password"))]),
|
||||
ModifyList::new_list(vec![Modify::Purged(Attribute::UnixPassword.into())]),
|
||||
);
|
||||
assert!(idms_prox_write.qs_write.modify(&me_purge_up).is_ok());
|
||||
assert!(idms_prox_write.commit().is_ok());
|
||||
|
@ -2820,7 +2819,7 @@ mod tests {
|
|||
ModifyEvent::new_internal_invalid(
|
||||
filter!(f_eq(Attribute::Name, PartialValue::new_iname("admin"))),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("password_import"),
|
||||
Attribute::PasswordImport.into(),
|
||||
Value::from("{SSHA512}JwrSUHkI7FTAfHRVR6KoFlSN0E3dmaQWARjZ+/UsShYlENOqDtFVU77HJLLrY2MuSp0jve52+pwtdVl2QUAHukQ0XUf5LDtM")
|
||||
)]),
|
||||
);
|
||||
|
@ -2901,8 +2900,8 @@ mod tests {
|
|||
filter!(f_eq(Attribute::Name, PartialValue::new_iname("admin"))),
|
||||
ModifyList::new_list(vec![
|
||||
Modify::Present(Attribute::Class.into(), EntryClass::PosixAccount.into()),
|
||||
Modify::Present(AttrString::from("gidnumber"), Value::new_uint32(2001)),
|
||||
Modify::Present(AttrString::from("unix_password"), v_cred),
|
||||
Modify::Present(Attribute::GidNumber.into(), Value::new_uint32(2001)),
|
||||
Modify::Present(Attribute::UnixPassword.into(), v_cred),
|
||||
]),
|
||||
);
|
||||
assert!(idms_prox_write.qs_write.modify(&me_posix).is_ok());
|
||||
|
@ -2955,8 +2954,8 @@ mod tests {
|
|||
let me_inv_m = ModifyEvent::new_internal_invalid(
|
||||
filter!(f_eq(Attribute::Name, PartialValue::new_iname("admin"))),
|
||||
ModifyList::new_list(vec![
|
||||
Modify::Present(AttrString::from("account_expire"), v_expire),
|
||||
Modify::Present(AttrString::from("account_valid_from"), v_valid_from),
|
||||
Modify::Present(Attribute::AccountExpire.into(), v_expire),
|
||||
Modify::Present(Attribute::AccountValidFrom.into(), v_valid_from),
|
||||
]),
|
||||
);
|
||||
// go!
|
||||
|
@ -3046,7 +3045,7 @@ mod tests {
|
|||
filter!(f_eq(Attribute::Name, PartialValue::new_iname("admin"))),
|
||||
ModifyList::new_list(vec![
|
||||
Modify::Present(Attribute::Class.into(), EntryClass::PosixAccount.into()),
|
||||
Modify::Present(AttrString::from("gidnumber"), Value::new_uint32(2001)),
|
||||
Modify::Present(Attribute::GidNumber.into(), Value::new_uint32(2001)),
|
||||
]),
|
||||
);
|
||||
assert!(idms_prox_write.qs_write.modify(&me_posix).is_ok());
|
||||
|
@ -3409,7 +3408,7 @@ mod tests {
|
|||
filter!(f_eq(Attribute::Name, PartialValue::new_iname("admin"))),
|
||||
ModifyList::new_list(vec![
|
||||
Modify::Present(Attribute::Class.into(), EntryClass::PosixAccount.into()),
|
||||
Modify::Present(AttrString::from("gidnumber"), Value::new_uint32(2001)),
|
||||
Modify::Present(Attribute::GidNumber.into(), Value::new_uint32(2001)),
|
||||
]),
|
||||
);
|
||||
assert!(idms_prox_write.qs_write.modify(&me_posix).is_ok());
|
||||
|
@ -3947,9 +3946,9 @@ mod tests {
|
|||
let me_reset_tokens = ModifyEvent::new_internal_invalid(
|
||||
filter!(f_eq(Attribute::Uuid, PartialValue::Uuid(UUID_DOMAIN_INFO))),
|
||||
ModifyList::new_list(vec![
|
||||
Modify::Purged(AttrString::from("fernet_private_key_str")),
|
||||
Modify::Purged(AttrString::from("es256_private_key_der")),
|
||||
Modify::Purged(AttrString::from("domain_token_key")),
|
||||
Modify::Purged(Attribute::FernetPrivateKeyStr.into()),
|
||||
Modify::Purged(Attribute::Es256PrivateKeyDer.into()),
|
||||
Modify::Purged(Attribute::DomainTokenKey.into()),
|
||||
]),
|
||||
);
|
||||
assert!(idms_prox_write.qs_write.modify(&me_reset_tokens).is_ok());
|
||||
|
|
|
@ -249,7 +249,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
|
||||
// modify the account to put the session onto it.
|
||||
let modlist = ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("api_token_session"),
|
||||
Attribute::ApiTokenSession.into(),
|
||||
session,
|
||||
)]);
|
||||
|
||||
|
@ -286,7 +286,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
|||
) -> Result<(), OperationError> {
|
||||
// Delete the attribute with uuid.
|
||||
let modlist = ModifyList::new_list(vec![Modify::Removed(
|
||||
AttrString::from("api_token_session"),
|
||||
Attribute::ApiTokenSession.into(),
|
||||
PartialValue::Refer(dte.token_id),
|
||||
)]);
|
||||
|
||||
|
|
|
@ -170,7 +170,7 @@ impl ModifyList<ModifyInvalid> {
|
|||
let schema_attributes = schema.get_attributes();
|
||||
/*
|
||||
let schema_name = schema_attributes
|
||||
.get("name")
|
||||
.get(Attribute::Name.as_ref()")
|
||||
.expect("Critical: Core schema corrupt or missing. To initiate a core transfer, please deposit substitute core in receptacle.");
|
||||
*/
|
||||
|
||||
|
|
|
@ -259,7 +259,7 @@ impl Plugin for AttrUnique {
|
|||
#[instrument(level = "debug", name = "attrunique::verify", skip_all)]
|
||||
fn verify(qs: &mut QueryServerReadTransaction) -> Vec<Result<(), ConsistencyError>> {
|
||||
// Only check live entries, not recycled.
|
||||
let filt_in = filter!(f_pres(Attribute::Class.as_ref()));
|
||||
let filt_in = filter!(f_pres(Attribute::Class));
|
||||
|
||||
let all_cand = match qs
|
||||
.internal_search(filt_in)
|
||||
|
|
|
@ -206,7 +206,7 @@ impl Plugin for Base {
|
|||
#[instrument(level = "debug", name = "base::verify", skip_all)]
|
||||
fn verify(qs: &mut QueryServerReadTransaction) -> Vec<Result<(), ConsistencyError>> {
|
||||
// Search for class = *
|
||||
let entries = match qs.internal_search(filter!(f_pres(Attribute::Class.as_ref()))) {
|
||||
let entries = match qs.internal_search(filter!(f_pres(Attribute::Class))) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
admin_error!("Internal Search Failure: {:?}", e);
|
||||
|
|
|
@ -193,7 +193,7 @@ mod tests {
|
|||
preload,
|
||||
filter!(f_eq(Attribute::Name, PartialValue::new_iutf8("testperson"))),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("password_import"),
|
||||
Attribute::PasswordImport.into(),
|
||||
Value::from(IMPORT_HASH)
|
||||
)]),
|
||||
None,
|
||||
|
@ -228,7 +228,7 @@ mod tests {
|
|||
preload,
|
||||
filter!(f_eq(Attribute::Name, PartialValue::new_iutf8("testperson"))),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("password_import"),
|
||||
Attribute::PasswordImport.into(),
|
||||
Value::from(IMPORT_HASH)
|
||||
)]),
|
||||
None,
|
||||
|
@ -266,7 +266,7 @@ mod tests {
|
|||
preload,
|
||||
filter!(f_eq(Attribute::Name, PartialValue::new_iutf8("testperson"))),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("password_import"),
|
||||
Attribute::PasswordImport.into(),
|
||||
Value::from(IMPORT_HASH)
|
||||
)]),
|
||||
None,
|
||||
|
@ -320,15 +320,15 @@ mod tests {
|
|||
filter!(f_eq(Attribute::Name, PartialValue::new_iutf8("testperson"))),
|
||||
ModifyList::new_list(vec![
|
||||
Modify::Present(
|
||||
AttrString::from("password_import"),
|
||||
Attribute::PasswordImport.into(),
|
||||
Value::Utf8(IMPORT_HASH.to_string())
|
||||
),
|
||||
Modify::Present(
|
||||
AttrString::from("totp_import"),
|
||||
Attribute::TotpImport.into(),
|
||||
Value::TotpSecret("a".to_string(), totp_a.clone())
|
||||
),
|
||||
Modify::Present(
|
||||
AttrString::from("totp_import"),
|
||||
Attribute::TotpImport.into(),
|
||||
Value::TotpSecret("b".to_string(), totp_b.clone())
|
||||
)
|
||||
]),
|
||||
|
@ -385,7 +385,7 @@ mod tests {
|
|||
preload,
|
||||
filter!(f_eq(Attribute::Name, PartialValue::new_iutf8("testperson"))),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("totp_import"),
|
||||
Attribute::TotpImport.into(),
|
||||
Value::TotpSecret("a".to_string(), totp_a)
|
||||
)]),
|
||||
None,
|
||||
|
|
|
@ -582,7 +582,7 @@ mod tests {
|
|||
ModifyList::new_list(vec![
|
||||
Modify::Purged("dyngroup_filter".into()),
|
||||
Modify::Present(
|
||||
AttrString::from("dyngroup_filter"),
|
||||
Attribute::DynGroupFilter.into(),
|
||||
Value::JsonFilt(ProtoFilter::Eq("name".to_string(), "testgroup".to_string()))
|
||||
)
|
||||
]),
|
||||
|
@ -637,7 +637,7 @@ mod tests {
|
|||
ModifyList::new_list(vec![
|
||||
Modify::Purged("dyngroup_filter".into()),
|
||||
Modify::Present(
|
||||
AttrString::from("dyngroup_filter"),
|
||||
Attribute::DynGroupFilter.into(),
|
||||
Value::JsonFilt(ProtoFilter::Eq(
|
||||
"name".to_string(),
|
||||
"no_such_entry_exists".to_string()
|
||||
|
@ -689,7 +689,7 @@ mod tests {
|
|||
PartialValue::new_iname("test_dyngroup")
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("dynmember"),
|
||||
Attribute::DynMember.into(),
|
||||
Value::Refer(UUID_ADMIN)
|
||||
)]),
|
||||
None,
|
||||
|
@ -741,7 +741,7 @@ mod tests {
|
|||
Attribute::Name,
|
||||
PartialValue::new_iname("test_dyngroup")
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Purged(AttrString::from("dynmember"),)]),
|
||||
ModifyList::new_list(vec![Modify::Purged(Attribute::DynMember.into(),)]),
|
||||
None,
|
||||
|_| {},
|
||||
|qs: &mut QueryServerWriteTransaction| {
|
||||
|
|
|
@ -214,8 +214,8 @@ mod tests {
|
|||
preload,
|
||||
filter!(f_eq(Attribute::Uuid, PartialValue::Uuid(uuid))),
|
||||
ModifyList::new_list(vec![
|
||||
Modify::Purged(AttrString::from("oauth2_rs_basic_secret"),),
|
||||
Modify::Purged(AttrString::from("oauth2_rs_token_key"),)
|
||||
Modify::Purged(Attribute::OAuth2RsBasicSecret.into(),),
|
||||
Modify::Purged(Attribute::OAuth2RsTokenKey.into(),)
|
||||
]),
|
||||
None,
|
||||
|_| {},
|
||||
|
|
|
@ -305,7 +305,7 @@ impl Plugin for MemberOf {
|
|||
fn verify(qs: &mut QueryServerReadTransaction) -> Vec<Result<(), ConsistencyError>> {
|
||||
let mut r = Vec::new();
|
||||
|
||||
let filt_in = filter!(f_pres(Attribute::Class.as_ref()));
|
||||
let filt_in = filter!(f_pres(Attribute::Class));
|
||||
|
||||
let all_cand = match qs
|
||||
.internal_search(filt_in)
|
||||
|
@ -797,7 +797,7 @@ mod tests {
|
|||
PartialValue::new_uuid_s(UUID_A).unwrap()
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
Value::new_refer_s(UUID_B).unwrap()
|
||||
)]),
|
||||
None,
|
||||
|
@ -836,7 +836,7 @@ mod tests {
|
|||
PartialValue::new_uuid_s(UUID_A).unwrap()
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
Value::new_refer_s(UUID_B).unwrap()
|
||||
)]),
|
||||
None,
|
||||
|
@ -893,7 +893,7 @@ mod tests {
|
|||
PartialValue::new_uuid_s(UUID_B).unwrap()
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
Value::new_refer_s(UUID_C).unwrap()
|
||||
)]),
|
||||
None,
|
||||
|
@ -953,7 +953,7 @@ mod tests {
|
|||
PartialValue::new_uuid_s(UUID_C).unwrap()
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
Value::new_refer_s(UUID_A).unwrap()
|
||||
)]),
|
||||
None,
|
||||
|
@ -1020,7 +1020,7 @@ mod tests {
|
|||
f_eq(Attribute::Uuid, PartialValue::new_uuid_s(UUID_D).unwrap()),
|
||||
])),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
Value::new_refer_s(UUID_A).unwrap()
|
||||
)]),
|
||||
None,
|
||||
|
@ -1092,7 +1092,7 @@ mod tests {
|
|||
PartialValue::new_uuid_s(UUID_A).unwrap()
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Removed(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
PartialValue::new_refer_s(UUID_B).unwrap()
|
||||
)]),
|
||||
None,
|
||||
|
@ -1134,7 +1134,7 @@ mod tests {
|
|||
PartialValue::new_uuid_s(UUID_A).unwrap()
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Removed(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
PartialValue::new_refer_s(UUID_B).unwrap()
|
||||
)]),
|
||||
None,
|
||||
|
@ -1195,7 +1195,7 @@ mod tests {
|
|||
PartialValue::new_uuid_s(UUID_B).unwrap()
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Removed(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
PartialValue::new_refer_s(UUID_C).unwrap()
|
||||
)]),
|
||||
None,
|
||||
|
@ -1266,7 +1266,7 @@ mod tests {
|
|||
PartialValue::new_uuid_s(UUID_C).unwrap()
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Removed(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
PartialValue::new_refer_s(UUID_A).unwrap()
|
||||
)]),
|
||||
None,
|
||||
|
@ -1356,11 +1356,11 @@ mod tests {
|
|||
)),
|
||||
ModifyList::new_list(vec![
|
||||
Modify::Removed(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
PartialValue::new_refer_s(UUID_A).unwrap()
|
||||
),
|
||||
Modify::Removed(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
PartialValue::new_refer_s(UUID_D).unwrap()
|
||||
),
|
||||
]),
|
||||
|
|
|
@ -339,7 +339,7 @@ mod tests {
|
|||
),
|
||||
(
|
||||
Attribute::AcpSearchAttr.as_ref(),
|
||||
Value::new_iutf8("attributename")
|
||||
Value::new_iutf8(Attribute::AttributeName.as_ref())
|
||||
),
|
||||
(
|
||||
Attribute::AcpModifyClass.as_ref(),
|
||||
|
|
|
@ -184,7 +184,7 @@ impl Plugin for ReferentialIntegrity {
|
|||
fn verify(qs: &mut QueryServerReadTransaction) -> Vec<Result<(), ConsistencyError>> {
|
||||
// Get all entries as cand
|
||||
// build a cand-uuid set
|
||||
let filt_in = filter_all!(f_pres(Attribute::Class.as_ref()));
|
||||
let filt_in = filter_all!(f_pres(Attribute::Class));
|
||||
|
||||
let all_cand = match qs
|
||||
.internal_search(filt_in)
|
||||
|
@ -433,7 +433,7 @@ mod tests {
|
|||
PartialValue::new_iname("testgroup_b")
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
Value::new_refer_s("d2b496bd-8493-47b7-8142-f568b5cf47ee").unwrap()
|
||||
)]),
|
||||
None,
|
||||
|
@ -467,7 +467,7 @@ mod tests {
|
|||
PartialValue::new_iname("testgroup_b")
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
Value::new_refer_s("d2b496bd-8493-47b7-8142-f568b5cf47ee").unwrap()
|
||||
)]),
|
||||
None,
|
||||
|
@ -514,13 +514,10 @@ mod tests {
|
|||
)),
|
||||
ModifyList::new_list(vec![
|
||||
Modify::Present(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
Value::Refer(uuid!("d2b496bd-8493-47b7-8142-f568b5cf47ee"))
|
||||
),
|
||||
Modify::Present(
|
||||
AttrString::from("member"),
|
||||
Value::Refer(UUID_DOES_NOT_EXIST)
|
||||
),
|
||||
Modify::Present(Attribute::Member.into(), Value::Refer(UUID_DOES_NOT_EXIST)),
|
||||
]),
|
||||
None,
|
||||
|_| {},
|
||||
|
@ -562,7 +559,7 @@ mod tests {
|
|||
Attribute::Name,
|
||||
PartialValue::new_iname("testgroup_b")
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Purged(AttrString::from("member"))]),
|
||||
ModifyList::new_list(vec![Modify::Purged(Attribute::Member.into())]),
|
||||
None,
|
||||
|_| {},
|
||||
|_| {}
|
||||
|
@ -593,7 +590,7 @@ mod tests {
|
|||
PartialValue::new_iname("testgroup_a")
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
Value::new_refer_s("d2b496bd-8493-47b7-8142-f568b5cf47ee").unwrap()
|
||||
)]),
|
||||
None,
|
||||
|
@ -638,7 +635,7 @@ mod tests {
|
|||
PartialValue::new_iname("testgroup_b")
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("member"),
|
||||
Attribute::Member.into(),
|
||||
Value::new_refer_s("d2b496bd-8493-47b7-8142-f568b5cf47ee").unwrap()
|
||||
)]),
|
||||
None,
|
||||
|
|
|
@ -174,7 +174,7 @@ impl<'a> QueryServerReadTransaction<'a> {
|
|||
|
||||
let entry_filter = filter_all!(f_or!([
|
||||
f_and!([
|
||||
f_pres(Attribute::Class.as_ref()),
|
||||
f_pres(Attribute::Class),
|
||||
f_andnot(f_or(vec![
|
||||
// These are from above!
|
||||
f_eq(Attribute::Class, EntryClass::AttributeType.into()),
|
||||
|
|
|
@ -154,7 +154,7 @@ async fn test_repl_refresh_basic(server_a: &QueryServer, server_b: &QueryServer)
|
|||
// Now assert everything else in the db matches.
|
||||
|
||||
let entries_a = server_a_txn
|
||||
.internal_search(filter_all!(f_pres(Attribute::Class.as_ref())))
|
||||
.internal_search(filter_all!(f_pres(Attribute::Class)))
|
||||
.map(|ents| {
|
||||
ents.into_iter()
|
||||
.map(|e| (e.get_uuid(), e))
|
||||
|
@ -163,7 +163,7 @@ async fn test_repl_refresh_basic(server_a: &QueryServer, server_b: &QueryServer)
|
|||
.expect("Failed to access all entries");
|
||||
|
||||
let entries_b = server_a_txn
|
||||
.internal_search(filter_all!(f_pres(Attribute::Class.as_ref())))
|
||||
.internal_search(filter_all!(f_pres(Attribute::Class)))
|
||||
.map(|ents| {
|
||||
ents.into_iter()
|
||||
.map(|e| (e.get_uuid(), e))
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1627,7 +1627,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_access_internal_search() {
|
||||
// Test that an internal search bypasses ACS
|
||||
let se = SearchEvent::new_internal_invalid(filter!(f_pres(Attribute::Class.as_ref())));
|
||||
let se = SearchEvent::new_internal_invalid(filter!(f_pres(Attribute::Class)));
|
||||
|
||||
let expect = vec![E_TEST_ACCOUNT_1.clone()];
|
||||
let entries = vec![E_TEST_ACCOUNT_1.clone()];
|
||||
|
@ -1639,8 +1639,8 @@ mod tests {
|
|||
"test_acp",
|
||||
Uuid::new_v4(),
|
||||
UUID_TEST_GROUP_1,
|
||||
filter_valid!(f_pres("nomatchy")), // apply to none - ie no allowed results
|
||||
"name", // allow to this attr, but we don't eval this.
|
||||
filter_valid!(f_pres(Attribute::NonExist)), // apply to none - ie no allowed results
|
||||
"name", // allow to this attr, but we don't eval this.
|
||||
)],
|
||||
entries,
|
||||
expect
|
||||
|
@ -1657,13 +1657,13 @@ mod tests {
|
|||
|
||||
let se_a = SearchEvent::new_impersonate_entry(
|
||||
E_TEST_ACCOUNT_1.clone(),
|
||||
filter_all!(f_pres("name")),
|
||||
filter_all!(f_pres(Attribute::Name)),
|
||||
);
|
||||
let ex_a = vec![Arc::new(ev1)];
|
||||
|
||||
let se_b = SearchEvent::new_impersonate_entry(
|
||||
E_TEST_ACCOUNT_2.clone(),
|
||||
filter_all!(f_pres("name")),
|
||||
filter_all!(f_pres(Attribute::Name)),
|
||||
);
|
||||
let ex_b = vec![];
|
||||
|
||||
|
@ -1701,12 +1701,12 @@ mod tests {
|
|||
|
||||
let se_ro = SearchEvent::new_impersonate_identity(
|
||||
Identity::from_impersonate_entry_readonly(E_TEST_ACCOUNT_1.clone()),
|
||||
filter_all!(f_pres("name")),
|
||||
filter_all!(f_pres(Attribute::Name)),
|
||||
);
|
||||
|
||||
let se_rw = SearchEvent::new_impersonate_identity(
|
||||
Identity::from_impersonate_entry_readwrite(E_TEST_ACCOUNT_1.clone()),
|
||||
filter_all!(f_pres("name")),
|
||||
filter_all!(f_pres(Attribute::Name)),
|
||||
);
|
||||
|
||||
let acp = AccessControlSearch::from_raw(
|
||||
|
@ -1744,7 +1744,7 @@ mod tests {
|
|||
|
||||
let se_anon_ro = SearchEvent::new_impersonate_identity(
|
||||
Identity::from_impersonate_entry_readonly(E_TEST_ACCOUNT_1.clone()),
|
||||
filter_all!(f_pres("name")),
|
||||
filter_all!(f_pres(Attribute::Name)),
|
||||
);
|
||||
|
||||
let acp = AccessControlSearch::from_raw(
|
||||
|
@ -1829,7 +1829,7 @@ mod tests {
|
|||
)),
|
||||
);
|
||||
// the requested attrs here.
|
||||
se_anon.attrs = Some(btreeset![AttrString::from("name")]);
|
||||
se_anon.attrs = Some(btreeset![Attribute::Name.into()]);
|
||||
|
||||
let acp = AccessControlSearch::from_raw(
|
||||
"test_acp",
|
||||
|
@ -2122,15 +2122,18 @@ mod tests {
|
|||
fn test_access_enforce_create() {
|
||||
let ev1 = entry_init!(
|
||||
(Attribute::Class.as_ref(), EntryClass::Account.to_value()),
|
||||
("name", Value::new_iname("testperson1")),
|
||||
(Attribute::Name.as_ref(), Value::new_iname("testperson1")),
|
||||
(Attribute::Uuid.as_ref(), Value::Uuid(UUID_TEST_ACCOUNT_1))
|
||||
);
|
||||
let r1_set = vec![ev1];
|
||||
|
||||
let ev2 = entry_init!(
|
||||
(Attribute::Class.as_ref(), EntryClass::Account.to_value()),
|
||||
("notallowed", Value::new_class("notallowed")),
|
||||
("name", Value::new_iname("testperson1")),
|
||||
(
|
||||
Attribute::TestNotAllowed.as_ref(),
|
||||
Value::new_class("notallowed")
|
||||
),
|
||||
(Attribute::Name.as_ref(), Value::new_iname("testperson1")),
|
||||
(Attribute::Uuid.as_ref(), Value::Uuid(UUID_TEST_ACCOUNT_1))
|
||||
);
|
||||
|
||||
|
@ -2138,8 +2141,8 @@ mod tests {
|
|||
|
||||
let ev3 = entry_init!(
|
||||
(Attribute::Class.as_ref(), EntryClass::Account.to_value()),
|
||||
("class", Value::new_class("notallowed")),
|
||||
("name", Value::new_iname("testperson1")),
|
||||
(Attribute::Class.as_ref(), Value::new_class("notallowed")),
|
||||
(Attribute::Name.as_ref(), Value::new_iname("testperson1")),
|
||||
(Attribute::Uuid.as_ref(), Value::Uuid(UUID_TEST_ACCOUNT_1))
|
||||
);
|
||||
let r3_set = vec![ev3];
|
||||
|
@ -2147,7 +2150,7 @@ mod tests {
|
|||
let ev4 = entry_init!(
|
||||
(Attribute::Class.as_ref(), EntryClass::Account.to_value()),
|
||||
(Attribute::Class.as_ref(), EntryClass::Group.to_value()),
|
||||
("name", Value::new_iname("testperson1")),
|
||||
(Attribute::Name.as_ref(), Value::new_iname("testperson1")),
|
||||
(Attribute::Uuid.as_ref(), Value::Uuid(UUID_TEST_ACCOUNT_1))
|
||||
);
|
||||
let r4_set = vec![ev4];
|
||||
|
@ -2411,7 +2414,7 @@ mod tests {
|
|||
vec![AccessEffectivePermission {
|
||||
delete: false,
|
||||
target: uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"),
|
||||
search: Access::Allow(btreeset![AttrString::from("name")]),
|
||||
search: Access::Allow(btreeset![Attribute::Name.into()]),
|
||||
modify_pres: Access::Allow(BTreeSet::new()),
|
||||
modify_rem: Access::Allow(BTreeSet::new()),
|
||||
modify_class: Access::Allow(BTreeSet::new()),
|
||||
|
@ -2454,9 +2457,9 @@ mod tests {
|
|||
delete: false,
|
||||
target: uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"),
|
||||
search: Access::Allow(BTreeSet::new()),
|
||||
modify_pres: Access::Allow(btreeset![AttrString::from("name")]),
|
||||
modify_rem: Access::Allow(btreeset![AttrString::from("name")]),
|
||||
modify_class: Access::Allow(btreeset![AttrString::from("object")]),
|
||||
modify_pres: Access::Allow(btreeset![Attribute::Name.into()]),
|
||||
modify_rem: Access::Allow(btreeset![Attribute::Name.into()]),
|
||||
modify_class: Access::Allow(btreeset![EntryClass::Object.into()]),
|
||||
}]
|
||||
)
|
||||
}
|
||||
|
@ -2814,14 +2817,14 @@ mod tests {
|
|||
|
||||
let se_a = SearchEvent::new_impersonate_entry(
|
||||
E_TEST_ACCOUNT_1.clone(),
|
||||
filter_all!(f_pres("oauth2_rs_name")),
|
||||
filter_all!(f_pres(Attribute::OAuth2RsName)),
|
||||
);
|
||||
let ex_a = vec![Arc::new(ev1)];
|
||||
let ex_a_reduced = vec![ev1_reduced];
|
||||
|
||||
let se_b = SearchEvent::new_impersonate_entry(
|
||||
E_TEST_ACCOUNT_2.clone(),
|
||||
filter_all!(f_pres("oauth2_rs_name")),
|
||||
filter_all!(f_pres(Attribute::OAuth2RsName)),
|
||||
);
|
||||
let ex_b = vec![];
|
||||
|
||||
|
@ -2896,7 +2899,7 @@ mod tests {
|
|||
|
||||
let se_a = SearchEvent::new_impersonate_entry(
|
||||
sync_test_account,
|
||||
filter_all!(f_pres("sync_credential_portal")),
|
||||
filter_all!(f_pres(Attribute::SyncCredentialPortal)),
|
||||
);
|
||||
let ex_a = vec![Arc::new(ev1)];
|
||||
let ex_a_reduced = vec![ev1_reduced];
|
||||
|
@ -2907,7 +2910,7 @@ mod tests {
|
|||
// Test a non-synced account aka the deny case
|
||||
let se_b = SearchEvent::new_impersonate_entry(
|
||||
E_TEST_ACCOUNT_2.clone(),
|
||||
filter_all!(f_pres("sync_credential_portal")),
|
||||
filter_all!(f_pres(Attribute::SyncCredentialPortal)),
|
||||
);
|
||||
let ex_b = vec![];
|
||||
|
||||
|
|
|
@ -206,7 +206,7 @@ mod tests {
|
|||
(Attribute::Class.as_ref(), EntryClass::Person.to_value()),
|
||||
(Attribute::Name.as_ref(), Value::new_iname("testperson1")),
|
||||
(
|
||||
"uuid",
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::Uuid(uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
|
||||
),
|
||||
(
|
||||
|
@ -224,7 +224,7 @@ mod tests {
|
|||
(Attribute::Class.as_ref(), EntryClass::Person.to_value()),
|
||||
(Attribute::Name.as_ref(), Value::new_iname("testperson2")),
|
||||
(
|
||||
"uuid",
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::Uuid(uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63932"))
|
||||
),
|
||||
(
|
||||
|
@ -242,7 +242,7 @@ mod tests {
|
|||
(Attribute::Class.as_ref(), EntryClass::Person.to_value()),
|
||||
(Attribute::Name.as_ref(), Value::new_iname("testperson3")),
|
||||
(
|
||||
"uuid",
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::Uuid(uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63933"))
|
||||
),
|
||||
(
|
||||
|
@ -261,7 +261,7 @@ mod tests {
|
|||
assert!(cr.is_ok());
|
||||
|
||||
// Delete filter is syntax invalid
|
||||
let de_inv = DeleteEvent::new_internal_invalid(filter!(f_pres("nhtoaunaoehtnu")));
|
||||
let de_inv = DeleteEvent::new_internal_invalid(filter!(f_pres(Attribute::NonExist)));
|
||||
assert!(server_txn.delete(&de_inv).is_err());
|
||||
|
||||
// Delete deletes nothing
|
||||
|
|
|
@ -289,8 +289,8 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
pub fn migrate_9_to_10(&mut self) -> Result<(), OperationError> {
|
||||
admin_warn!("starting 9 to 10 migration.");
|
||||
let filter = filter!(f_or!([
|
||||
f_pres("primary_credential"),
|
||||
f_pres("unix_password"),
|
||||
f_pres(Attribute::PrimaryCredential),
|
||||
f_pres(Attribute::UnixPassword),
|
||||
]));
|
||||
// This "does nothing" since everything has object anyway, but it forces the entry to be
|
||||
// loaded and rewritten.
|
||||
|
@ -309,7 +309,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
#[instrument(level = "debug", skip_all)]
|
||||
pub fn migrate_10_to_11(&mut self) -> Result<(), OperationError> {
|
||||
admin_warn!("starting 9 to 10 migration.");
|
||||
let filter = filter!(f_pres("primary_credential"));
|
||||
let filter = filter!(f_pres(Attribute::PrimaryCredential));
|
||||
|
||||
let pre_candidates = self.internal_search(filter).map_err(|e| {
|
||||
admin_error!(err = ?e, "migrate_10_to_11 internal search failure");
|
||||
|
@ -358,8 +358,8 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
admin_warn!("starting 11 to 12 migration.");
|
||||
// sync_token_session
|
||||
let filter = filter!(f_or!([
|
||||
f_pres("api_token_session"),
|
||||
f_pres("sync_token_session"),
|
||||
f_pres(Attribute::ApiTokenSession),
|
||||
f_pres(Attribute::SyncTokenSession),
|
||||
]));
|
||||
|
||||
let mut mod_candidates = self.internal_search_writeable(&filter).map_err(|e| {
|
||||
|
@ -838,10 +838,10 @@ mod tests {
|
|||
filter!(f_eq(Attribute::Uuid, PartialValue::Uuid(UUID_DOMAIN_INFO))),
|
||||
ModifyList::new_list(vec![
|
||||
Modify::Purged(Attribute::Name.into()),
|
||||
Modify::Purged(AttrString::from("domain_name")),
|
||||
Modify::Purged(Attribute::DomainName.into()),
|
||||
Modify::Present(Attribute::Name.into(), Value::new_iutf8("domain_local")),
|
||||
Modify::Present(
|
||||
AttrString::from("domain_name"),
|
||||
Attribute::DomainName.into(),
|
||||
Value::new_iutf8("example.com"),
|
||||
),
|
||||
]),
|
||||
|
|
|
@ -991,7 +991,7 @@ impl<'a> QueryServerReadTransaction<'a> {
|
|||
// the entry changelogs are consistent to their entries.
|
||||
let schema = self.get_schema();
|
||||
|
||||
let filt_all = filter!(f_pres(Attribute::Class.as_ref()));
|
||||
let filt_all = filter!(f_pres(Attribute::Class));
|
||||
let all_entries = match self.internal_search(filt_all) {
|
||||
Ok(a) => a,
|
||||
Err(_e) => return vec![Err(ConsistencyError::QueryServerSearchFailure)],
|
||||
|
@ -1930,7 +1930,10 @@ mod tests {
|
|||
"uuid",
|
||||
Value::Uuid(uuid!("cfcae205-31c3-484b-8ced-667d1709c5e3"))
|
||||
),
|
||||
("attributename", Value::new_iutf8("testattr")),
|
||||
(
|
||||
Attribute::AttributeName.as_ref(),
|
||||
Value::new_iutf8("testattr")
|
||||
),
|
||||
("description", Value::new_utf8s("Test Attribute")),
|
||||
("multivalue", Value::new_bool(false)),
|
||||
("unique", Value::new_bool(false)),
|
||||
|
|
|
@ -512,7 +512,7 @@ mod tests {
|
|||
(Attribute::Class.as_ref(), EntryClass::Person.to_value()),
|
||||
(Attribute::Name.as_ref(), Value::new_iname("testperson1")),
|
||||
(
|
||||
"uuid",
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::Uuid(uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"))
|
||||
),
|
||||
(
|
||||
|
@ -530,7 +530,7 @@ mod tests {
|
|||
(Attribute::Class.as_ref(), EntryClass::Person.to_value()),
|
||||
(Attribute::Name.as_ref(), Value::new_iname("testperson2")),
|
||||
(
|
||||
"uuid",
|
||||
Attribute::Uuid.as_ref(),
|
||||
Value::Uuid(uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63932"))
|
||||
),
|
||||
(
|
||||
|
@ -550,7 +550,7 @@ mod tests {
|
|||
|
||||
// Empty Modlist (filter is valid)
|
||||
let me_emp = ModifyEvent::new_internal_invalid(
|
||||
filter!(f_pres(Attribute::Class.as_ref())),
|
||||
filter!(f_pres(Attribute::Class)),
|
||||
ModifyList::new_list(vec![]),
|
||||
);
|
||||
assert!(server_txn.modify(&me_emp) == Err(OperationError::EmptyRequest));
|
||||
|
@ -580,7 +580,7 @@ mod tests {
|
|||
// PartialValue::new_iname("Flarbalgarble")
|
||||
// )),
|
||||
// &ModifyList::new_list(vec![Modify::Present(
|
||||
// AttrString::from("description"),
|
||||
// Attribute::Description.into(),
|
||||
// Value::from("anusaosu"),
|
||||
// )]),
|
||||
// );
|
||||
|
@ -593,16 +593,16 @@ mod tests {
|
|||
|
||||
// Mod is invalid to schema
|
||||
let me_inv_m = ModifyEvent::new_internal_invalid(
|
||||
filter!(f_pres(Attribute::Class.as_ref())),
|
||||
filter!(f_pres(Attribute::Class)),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
AttrString::from("htnaonu"),
|
||||
Attribute::NonExist.into(),
|
||||
Value::from("anusaosu"),
|
||||
)]),
|
||||
);
|
||||
assert!(
|
||||
server_txn.modify(&me_inv_m)
|
||||
== Err(OperationError::SchemaViolation(
|
||||
SchemaError::InvalidAttribute("htnaonu".to_string())
|
||||
SchemaError::InvalidAttribute(Attribute::NonExist.to_string())
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -737,7 +737,7 @@ mod tests {
|
|||
ModifyList::new_list(vec![
|
||||
Modify::Present(Attribute::Class.into(), EntryClass::SystemInfo.to_value()),
|
||||
// Modify::Present("domain".to_string(), Value::new_iutf8("domain.name")),
|
||||
Modify::Present(AttrString::from("version"), Value::new_uint32(1)),
|
||||
Modify::Present(Attribute::Version.into(), Value::new_uint32(1)),
|
||||
]),
|
||||
);
|
||||
assert!(server_txn.modify(&me_sin).is_ok());
|
||||
|
|
|
@ -150,11 +150,11 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
dm_mods
|
||||
.entry(g_uuid)
|
||||
.and_modify(|mlist| {
|
||||
let m = Modify::Present(AttrString::from("member"), Value::Refer(u));
|
||||
let m = Modify::Present(Attribute::Member.into(), Value::Refer(u));
|
||||
mlist.push_mod(m);
|
||||
})
|
||||
.or_insert({
|
||||
let m = Modify::Present(AttrString::from("member"), Value::Refer(u));
|
||||
let m = Modify::Present(Attribute::Member.into(), Value::Refer(u));
|
||||
ModifyList::new_list(vec![m])
|
||||
});
|
||||
}
|
||||
|
|
|
@ -561,7 +561,7 @@ impl PartialValue {
|
|||
|
||||
pub fn new_spn_s(s: &str) -> Option<Self> {
|
||||
SPN_RE.captures(s).and_then(|caps| {
|
||||
let name = match caps.name("name") {
|
||||
let name = match caps.name(Attribute::Name.as_ref()) {
|
||||
Some(v) => v.as_str().to_string(),
|
||||
None => return None,
|
||||
};
|
||||
|
@ -1222,7 +1222,7 @@ impl Value {
|
|||
|
||||
pub fn new_spn_parse(s: &str) -> Option<Self> {
|
||||
SPN_RE.captures(s).and_then(|caps| {
|
||||
let name = match caps.name("name") {
|
||||
let name = match caps.name(Attribute::Name.as_ref()) {
|
||||
Some(v) => v.as_str().to_string(),
|
||||
None => return None,
|
||||
};
|
||||
|
|
|
@ -6,6 +6,7 @@ use kanidm_proto::constants::{
|
|||
APPLICATION_JSON, ATTR_ACP_RECEIVER_GROUP, ATTR_ACP_TARGET_SCOPE, ATTR_DESCRIPTION,
|
||||
ATTR_LDAP_SSH_PUBLICKEY, ATTR_NAME,
|
||||
};
|
||||
use kanidmd_lib::prelude::Attribute;
|
||||
use kanidmd_testkit::*;
|
||||
use reqwest::header::CONTENT_TYPE;
|
||||
|
||||
|
@ -270,74 +271,89 @@ async fn test_default_entries_rbac_admins_schema_entries(rsclient: KanidmClient)
|
|||
let classtype_entries = rsclient.idm_schema_classtype_list().await.unwrap();
|
||||
let classnames: HashSet<String> = classtype_entries
|
||||
.iter()
|
||||
.map(|entry| entry.attrs.get("classname").unwrap().first().unwrap())
|
||||
.map(|entry| {
|
||||
entry
|
||||
.attrs
|
||||
.get(Attribute::ClassName.as_ref())
|
||||
.unwrap()
|
||||
.first()
|
||||
.unwrap()
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
println!("{:?}", classnames);
|
||||
|
||||
assert!(default_classnames.is_subset(&classnames));
|
||||
|
||||
// TODO: this could probably just iterate on the enum?
|
||||
let default_attributenames: HashSet<String> = [
|
||||
"acp_create_attr",
|
||||
"acp_create_class",
|
||||
"acp_enable",
|
||||
"acp_modify_class",
|
||||
"acp_modify_presentattr",
|
||||
"acp_modify_removedattr",
|
||||
"acp_receiver_group",
|
||||
"acp_search_attr",
|
||||
"acp_targetscope",
|
||||
"attributename",
|
||||
"claim",
|
||||
"class",
|
||||
"classname",
|
||||
ATTR_DESCRIPTION,
|
||||
"directmemberof",
|
||||
"domain",
|
||||
"index",
|
||||
"last_modified_cid",
|
||||
"may",
|
||||
"member",
|
||||
"memberof",
|
||||
"multivalue",
|
||||
"must",
|
||||
ATTR_NAME,
|
||||
"password_import",
|
||||
"phantom",
|
||||
"spn",
|
||||
"syntax",
|
||||
"systemmay",
|
||||
"systemmust",
|
||||
"unique",
|
||||
"uuid",
|
||||
"version",
|
||||
"displayname",
|
||||
"legalname",
|
||||
"mail",
|
||||
ATTR_LDAP_SSH_PUBLICKEY,
|
||||
"primary_credential",
|
||||
"radius_secret",
|
||||
"domain_name",
|
||||
"domain_display_name",
|
||||
"domain_uuid",
|
||||
"domain_ssid",
|
||||
"gidnumber",
|
||||
"badlist_password",
|
||||
"authsession_expiry",
|
||||
"privilege_expiry",
|
||||
"loginshell",
|
||||
"unix_password",
|
||||
"nsuniqueid",
|
||||
Attribute::AcpCreateAttr,
|
||||
Attribute::AcpCreateClass,
|
||||
Attribute::AcpEnable,
|
||||
Attribute::AcpModifyClass,
|
||||
Attribute::AcpModifyPresentAttr,
|
||||
Attribute::AcpModifyRemovedAttr,
|
||||
Attribute::AcpReceiverGroup,
|
||||
Attribute::AcpSearchAttr,
|
||||
Attribute::AcpTargetScope,
|
||||
Attribute::AttributeName,
|
||||
Attribute::Claim,
|
||||
Attribute::Class,
|
||||
Attribute::ClassName,
|
||||
Attribute::Description,
|
||||
Attribute::DirectMemberOf,
|
||||
Attribute::Domain,
|
||||
Attribute::Index,
|
||||
Attribute::LastModifiedCid,
|
||||
Attribute::May,
|
||||
Attribute::Member,
|
||||
Attribute::MemberOf,
|
||||
Attribute::MultiValue,
|
||||
Attribute::Must,
|
||||
Attribute::Name,
|
||||
Attribute::PasswordImport,
|
||||
Attribute::Phantom,
|
||||
Attribute::Spn,
|
||||
Attribute::Syntax,
|
||||
Attribute::SystemMay,
|
||||
Attribute::SystemMust,
|
||||
Attribute::Unique,
|
||||
Attribute::Uuid,
|
||||
Attribute::Version,
|
||||
Attribute::DisplayName,
|
||||
Attribute::LegalName,
|
||||
Attribute::Mail,
|
||||
Attribute::LdapSshPublicKey,
|
||||
Attribute::PrimaryCredential,
|
||||
Attribute::RadiusSecret,
|
||||
Attribute::DomainName,
|
||||
Attribute::DomainDisplayName,
|
||||
Attribute::DomainUuid,
|
||||
Attribute::DomainSsid,
|
||||
Attribute::GidNumber,
|
||||
Attribute::BadlistPassword,
|
||||
Attribute::AuthSessionExpiry,
|
||||
Attribute::PrivilegeExpiry,
|
||||
Attribute::LoginShell,
|
||||
Attribute::UnixPassword,
|
||||
Attribute::NsUniqueId,
|
||||
]
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.map(|a| a.as_ref().to_string())
|
||||
.collect();
|
||||
|
||||
let attributename_entries = rsclient.idm_schema_attributetype_list().await.unwrap();
|
||||
println!("{:?}", attributename_entries);
|
||||
let attributenames = attributename_entries
|
||||
.iter()
|
||||
.map(|entry| entry.attrs.get("attributename").unwrap().first().unwrap())
|
||||
.map(|entry| {
|
||||
entry
|
||||
.attrs
|
||||
.get(Attribute::AttributeName.as_ref())
|
||||
.unwrap()
|
||||
.first()
|
||||
.unwrap()
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
|
|
|
@ -47,11 +47,14 @@ async fn dont_trust_xff_dont_send_header(rsclient: KanidmClient) {
|
|||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
let ip_res: Vec<IpAddr> = res
|
||||
.json()
|
||||
.await
|
||||
.expect("Failed to parse response as Vec<IpAddr>");
|
||||
|
||||
let body = res.bytes().await.unwrap();
|
||||
let ip_res: Vec<IpAddr> = serde_json::from_slice(&body).unwrap_or_else(|op| {
|
||||
panic!(
|
||||
"Failed to parse response as Vec<IpAddr>: {:?} body: {:?}",
|
||||
op, body,
|
||||
)
|
||||
});
|
||||
eprintln!("Body: {:?}", body);
|
||||
assert_eq!(ip_res[0], DEFAULT_IP_ADDRESS);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue