mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
Adding a builtin class for all built-in things (#2603)
* adding builtin class to builtin objects * Resolve issues with builtin PR --------- Co-authored-by: William Brown <william@blackhats.net.au>
This commit is contained in:
parent
8175253bae
commit
4c1fa0d644
|
@ -22,6 +22,7 @@ Configure OTLP trace exports by setting a `otel_grpc_url` in the server configur
|
||||||
enable [OpenTelemetry traces](https://opentelemetry.io) to be sent for observability use cases.
|
enable [OpenTelemetry traces](https://opentelemetry.io) to be sent for observability use cases.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
otel_grpc_url = "http://my-otel-host:4317"
|
otel_grpc_url = "http://my-otel-host:4317"
|
||||||
```
|
```
|
||||||
|
|
|
@ -228,4 +228,8 @@ pub const KOPID: &str = "X-KANIDM-OPID";
|
||||||
/// HTTP Header containing the Kanidm server version
|
/// HTTP Header containing the Kanidm server version
|
||||||
pub const KVERSION: &str = "X-KANIDM-VERSION";
|
pub const KVERSION: &str = "X-KANIDM-VERSION";
|
||||||
|
|
||||||
|
/// X-Forwarded-For header
|
||||||
pub const X_FORWARDED_FOR: &str = "x-forwarded-for";
|
pub const X_FORWARDED_FOR: &str = "x-forwarded-for";
|
||||||
|
|
||||||
|
/// Builtin object
|
||||||
|
pub const ENTRYCLASS_BUILTIN: &str = "builtin";
|
||||||
|
|
|
@ -205,7 +205,7 @@ pub(crate) fn qs_pair_test(args: &TokenStream, item: TokenStream) -> TokenStream
|
||||||
};
|
};
|
||||||
|
|
||||||
// Setup the config filling the remaining fields with the default values
|
// Setup the config filling the remaining fields with the default values
|
||||||
let (default_config_struct, _flags) = match parse_attributes(&args, &input) {
|
let (default_config_struct, _flags) = match parse_attributes(args, &input) {
|
||||||
Ok(dc) => dc,
|
Ok(dc) => dc,
|
||||||
Err(e) => return token_stream_with_error(args.clone(), e),
|
Err(e) => return token_stream_with_error(args.clone(), e),
|
||||||
};
|
};
|
||||||
|
@ -286,7 +286,7 @@ pub(crate) fn idm_test(args: &TokenStream, item: TokenStream) -> TokenStream {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Setup the config filling the remaining fields with the default values
|
// Setup the config filling the remaining fields with the default values
|
||||||
let (default_config_struct, flags) = match parse_attributes(&args, &input) {
|
let (default_config_struct, flags) = match parse_attributes(args, &input) {
|
||||||
Ok(dc) => dc,
|
Ok(dc) => dc,
|
||||||
Err(e) => return token_stream_with_error(args.clone(), e),
|
Err(e) => return token_stream_with_error(args.clone(), e),
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@ use criterion::{
|
||||||
use kanidmd_lib::entry::{Entry, EntryInit, EntryNew};
|
use kanidmd_lib::entry::{Entry, EntryInit, EntryNew};
|
||||||
use kanidmd_lib::entry_init;
|
use kanidmd_lib::entry_init;
|
||||||
use kanidmd_lib::prelude::{Attribute, EntryClass};
|
use kanidmd_lib::prelude::{Attribute, EntryClass};
|
||||||
|
use kanidmd_lib::testkit::{setup_idm_test, TestConfiguration};
|
||||||
use kanidmd_lib::value::Value;
|
use kanidmd_lib::value::Value;
|
||||||
|
|
||||||
pub fn duration_from_epoch_now() -> Duration {
|
pub fn duration_from_epoch_now() -> Duration {
|
||||||
|
@ -38,7 +39,7 @@ pub fn scaling_user_create_single(c: &mut Criterion) {
|
||||||
.expect("Failed building the Runtime")
|
.expect("Failed building the Runtime")
|
||||||
.block_on(async {
|
.block_on(async {
|
||||||
let (idms, _idms_delayed, _idms_audit) =
|
let (idms, _idms_delayed, _idms_audit) =
|
||||||
kanidmd_lib::testkit::setup_idm_test().await;
|
setup_idm_test(TestConfiguration::default()).await;
|
||||||
|
|
||||||
let ct = duration_from_epoch_now();
|
let ct = duration_from_epoch_now();
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
@ -105,7 +106,7 @@ pub fn scaling_user_create_batched(c: &mut Criterion) {
|
||||||
.expect("Failed building the Runtime")
|
.expect("Failed building the Runtime")
|
||||||
.block_on(async {
|
.block_on(async {
|
||||||
let (idms, _idms_delayed, _idms_audit) =
|
let (idms, _idms_delayed, _idms_audit) =
|
||||||
kanidmd_lib::testkit::setup_idm_test().await;
|
setup_idm_test(TestConfiguration::default()).await;
|
||||||
|
|
||||||
let ct = duration_from_epoch_now();
|
let ct = duration_from_epoch_now();
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
|
@ -77,6 +77,7 @@ pub struct BuiltinAcp {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BuiltinAcp> for EntryInitNew {
|
impl From<BuiltinAcp> for EntryInitNew {
|
||||||
|
#[allow(clippy::panic)]
|
||||||
fn from(value: BuiltinAcp) -> Self {
|
fn from(value: BuiltinAcp) -> Self {
|
||||||
let mut entry = EntryInitNew::default();
|
let mut entry = EntryInitNew::default();
|
||||||
|
|
||||||
|
@ -94,6 +95,11 @@ impl From<BuiltinAcp> for EntryInitNew {
|
||||||
});
|
});
|
||||||
|
|
||||||
entry.set_ava(Attribute::Name, [Value::new_iname(value.name)]);
|
entry.set_ava(Attribute::Name, [Value::new_iname(value.name)]);
|
||||||
|
|
||||||
|
if value.uuid >= DYNAMIC_RANGE_MINIMUM_UUID {
|
||||||
|
panic!("Builtin ACP has invalid UUID! {:?}", value);
|
||||||
|
}
|
||||||
|
|
||||||
entry.set_ava(Attribute::Uuid, [Value::Uuid(value.uuid)]);
|
entry.set_ava(Attribute::Uuid, [Value::Uuid(value.uuid)]);
|
||||||
entry.set_ava(
|
entry.set_ava(
|
||||||
Attribute::Description,
|
Attribute::Description,
|
||||||
|
|
|
@ -600,6 +600,7 @@ pub enum EntryClass {
|
||||||
Account,
|
Account,
|
||||||
AccountPolicy,
|
AccountPolicy,
|
||||||
AttributeType,
|
AttributeType,
|
||||||
|
Builtin,
|
||||||
Class,
|
Class,
|
||||||
ClassType,
|
ClassType,
|
||||||
Conflict,
|
Conflict,
|
||||||
|
@ -646,6 +647,7 @@ impl From<EntryClass> for &'static str {
|
||||||
EntryClass::Account => "account",
|
EntryClass::Account => "account",
|
||||||
EntryClass::AccountPolicy => "account_policy",
|
EntryClass::AccountPolicy => "account_policy",
|
||||||
EntryClass::AttributeType => "attributetype",
|
EntryClass::AttributeType => "attributetype",
|
||||||
|
EntryClass::Builtin => ENTRYCLASS_BUILTIN,
|
||||||
EntryClass::Class => ATTR_CLASS,
|
EntryClass::Class => ATTR_CLASS,
|
||||||
EntryClass::ClassType => "classtype",
|
EntryClass::ClassType => "classtype",
|
||||||
EntryClass::Conflict => "conflict",
|
EntryClass::Conflict => "conflict",
|
||||||
|
@ -801,6 +803,10 @@ impl Default for BuiltinAccount {
|
||||||
|
|
||||||
impl From<BuiltinAccount> for Account {
|
impl From<BuiltinAccount> for Account {
|
||||||
fn from(value: BuiltinAccount) -> Self {
|
fn from(value: BuiltinAccount) -> Self {
|
||||||
|
#[allow(clippy::panic)]
|
||||||
|
if value.uuid >= DYNAMIC_RANGE_MINIMUM_UUID {
|
||||||
|
panic!("Builtin ACP has invalid UUID! {:?}", value);
|
||||||
|
}
|
||||||
Account {
|
Account {
|
||||||
name: value.name.to_string(),
|
name: value.name.to_string(),
|
||||||
uuid: value.uuid,
|
uuid: value.uuid,
|
||||||
|
@ -817,6 +823,10 @@ impl From<BuiltinAccount> for EntryInitNew {
|
||||||
fn from(value: BuiltinAccount) -> Self {
|
fn from(value: BuiltinAccount) -> Self {
|
||||||
let mut entry = EntryInitNew::new();
|
let mut entry = EntryInitNew::new();
|
||||||
entry.add_ava(Attribute::Name, Value::new_iname(value.name));
|
entry.add_ava(Attribute::Name, Value::new_iname(value.name));
|
||||||
|
#[allow(clippy::panic)]
|
||||||
|
if value.uuid >= DYNAMIC_RANGE_MINIMUM_UUID {
|
||||||
|
panic!("Builtin ACP has invalid UUID! {:?}", value);
|
||||||
|
}
|
||||||
entry.add_ava(Attribute::Uuid, Value::Uuid(value.uuid));
|
entry.add_ava(Attribute::Uuid, Value::Uuid(value.uuid));
|
||||||
entry.add_ava(Attribute::Description, Value::new_utf8s(value.description));
|
entry.add_ava(Attribute::Description, Value::new_utf8s(value.description));
|
||||||
entry.add_ava(Attribute::DisplayName, Value::new_utf8s(value.displayname));
|
entry.add_ava(Attribute::DisplayName, Value::new_utf8s(value.displayname));
|
||||||
|
@ -912,6 +922,11 @@ lazy_static! {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ⚠️ DOMAIN LEVEL 1 ENTRIES ⚠️
|
||||||
|
// Future entries need to be added via migrations.
|
||||||
|
//
|
||||||
|
// DO NOT MODIFY THIS DEFINITION
|
||||||
|
|
||||||
/// Build a list of internal admin entries
|
/// Build a list of internal admin entries
|
||||||
pub fn idm_builtin_admin_entries() -> Result<Vec<EntryInitNew>, OperationError> {
|
pub fn idm_builtin_admin_entries() -> Result<Vec<EntryInitNew>, OperationError> {
|
||||||
let mut res: Vec<EntryInitNew> = vec![
|
let mut res: Vec<EntryInitNew> = vec![
|
||||||
|
|
|
@ -22,6 +22,11 @@ impl TryFrom<BuiltinGroup> for EntryInitNew {
|
||||||
fn try_from(val: BuiltinGroup) -> Result<Self, OperationError> {
|
fn try_from(val: BuiltinGroup) -> Result<Self, OperationError> {
|
||||||
let mut entry = EntryInitNew::new();
|
let mut entry = EntryInitNew::new();
|
||||||
|
|
||||||
|
if val.uuid >= DYNAMIC_RANGE_MINIMUM_UUID {
|
||||||
|
error!("Builtin ACP has invalid UUID! {:?}", val);
|
||||||
|
return Err(OperationError::InvalidUuid);
|
||||||
|
}
|
||||||
|
|
||||||
entry.add_ava(Attribute::Name, Value::new_iname(val.name));
|
entry.add_ava(Attribute::Name, Value::new_iname(val.name));
|
||||||
entry.add_ava(Attribute::Description, Value::new_utf8s(val.description));
|
entry.add_ava(Attribute::Description, Value::new_utf8s(val.description));
|
||||||
// classes for groups
|
// classes for groups
|
||||||
|
|
|
@ -280,6 +280,7 @@ pub const UUID_SCHEMA_ATTR_LIMIT_SEARCH_MAX_RESULTS: Uuid =
|
||||||
uuid!("00000000-0000-0000-0000-ffff00000161");
|
uuid!("00000000-0000-0000-0000-ffff00000161");
|
||||||
pub const UUID_SCHEMA_ATTR_LIMIT_SEARCH_MAX_FILTER_TEST: Uuid =
|
pub const UUID_SCHEMA_ATTR_LIMIT_SEARCH_MAX_FILTER_TEST: Uuid =
|
||||||
uuid!("00000000-0000-0000-0000-ffff00000162");
|
uuid!("00000000-0000-0000-0000-ffff00000162");
|
||||||
|
pub const UUID_SCHEMA_CLASS_BUILTIN: Uuid = uuid!("00000000-0000-0000-0000-ffff00000163");
|
||||||
|
|
||||||
// System and domain infos
|
// System and domain infos
|
||||||
// I'd like to strongly criticise william of the past for making poor choices about these allocations.
|
// I'd like to strongly criticise william of the past for making poor choices about these allocations.
|
||||||
|
@ -396,3 +397,5 @@ pub const UUID_IDM_ACP_ACCOUNT_UNIX_EXTEND_V1: Uuid = uuid!("00000000-0000-0000-
|
||||||
// End of system ranges
|
// End of system ranges
|
||||||
pub const UUID_DOES_NOT_EXIST: Uuid = uuid!("00000000-0000-0000-0000-fffffffffffe");
|
pub const UUID_DOES_NOT_EXIST: Uuid = uuid!("00000000-0000-0000-0000-fffffffffffe");
|
||||||
pub const UUID_ANONYMOUS: Uuid = uuid!("00000000-0000-0000-0000-ffffffffffff");
|
pub const UUID_ANONYMOUS: Uuid = uuid!("00000000-0000-0000-0000-ffffffffffff");
|
||||||
|
|
||||||
|
pub const DYNAMIC_RANGE_MINIMUM_UUID: Uuid = uuid!("00000000-0000-0000-0001-000000000000");
|
||||||
|
|
|
@ -67,15 +67,34 @@ impl Plugin for Base {
|
||||||
// Now, every cand has a UUID - create a cand uuid set from it.
|
// Now, every cand has a UUID - create a cand uuid set from it.
|
||||||
let mut cand_uuid: BTreeSet<Uuid> = BTreeSet::new();
|
let mut cand_uuid: BTreeSet<Uuid> = BTreeSet::new();
|
||||||
|
|
||||||
|
let mut system_range_invalid = false;
|
||||||
|
|
||||||
// As we insert into the set, if a duplicate is found, return an error
|
// As we insert into the set, if a duplicate is found, return an error
|
||||||
// that a duplicate exists.
|
// that a duplicate exists.
|
||||||
//
|
//
|
||||||
// Remember, we have to use the ava here, not the get_uuid types because
|
// Remember, we have to use the ava here, not the get_uuid types because
|
||||||
// we may not have filled in the uuid field yet.
|
// we may not have filled in the uuid field yet.
|
||||||
for entry in cand.iter() {
|
for entry in cand.iter_mut() {
|
||||||
let uuid_ref: Uuid = entry
|
let uuid_ref: Uuid = entry
|
||||||
.get_ava_single_uuid(Attribute::Uuid)
|
.get_ava_single_uuid(Attribute::Uuid)
|
||||||
.ok_or_else(|| OperationError::InvalidAttribute(Attribute::Uuid.to_string()))?;
|
.ok_or_else(|| OperationError::InvalidAttribute(Attribute::Uuid.to_string()))?;
|
||||||
|
|
||||||
|
// Check that the system-protected range is not in the cand_uuid, unless we are
|
||||||
|
// an internal operation.
|
||||||
|
if uuid_ref < DYNAMIC_RANGE_MINIMUM_UUID {
|
||||||
|
if ce.ident.is_internal() {
|
||||||
|
// it's a builtin entry, lets add the class.
|
||||||
|
entry.add_ava(Attribute::Class, EntryClass::Builtin.to_value());
|
||||||
|
} else {
|
||||||
|
// Don't do that!
|
||||||
|
error!(
|
||||||
|
"uuid from protected system UUID range found in create set! {:?}",
|
||||||
|
uuid_ref
|
||||||
|
);
|
||||||
|
system_range_invalid = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if !cand_uuid.insert(uuid_ref) {
|
if !cand_uuid.insert(uuid_ref) {
|
||||||
trace!("uuid duplicate found in create set! {:?}", uuid_ref);
|
trace!("uuid duplicate found in create set! {:?}", uuid_ref);
|
||||||
return Err(OperationError::Plugin(PluginError::Base(
|
return Err(OperationError::Plugin(PluginError::Base(
|
||||||
|
@ -84,33 +103,18 @@ impl Plugin for Base {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the system-protected range is not in the cand_uuid, unless we are
|
if system_range_invalid {
|
||||||
// an internal operation.
|
return Err(OperationError::Plugin(PluginError::Base(
|
||||||
if !ce.ident.is_internal() {
|
"Uuid must not be in protected range".to_string(),
|
||||||
// TODO: We can't lazy const this as you can't borrow the type down to what
|
)));
|
||||||
// range and contains on btreeset need, but can we possibly make these
|
|
||||||
// part of the struct at init. rather than needing to parse a lot?
|
|
||||||
// The internal set is bounded by: UUID_ADMIN -> UUID_ANONYMOUS
|
|
||||||
// Sadly we need to allocate these to strings to make references, sigh.
|
|
||||||
let overlap: usize = cand_uuid.range(UUID_ADMIN..UUID_ANONYMOUS).count();
|
|
||||||
if overlap != 0 {
|
|
||||||
admin_error!(
|
|
||||||
"uuid from protected system UUID range found in create set! {:?}",
|
|
||||||
overlap
|
|
||||||
);
|
|
||||||
return Err(OperationError::Plugin(PluginError::Base(
|
|
||||||
"Uuid must not be in protected range".to_string(),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if cand_uuid.contains(&UUID_DOES_NOT_EXIST) {
|
if cand_uuid.contains(&UUID_DOES_NOT_EXIST) {
|
||||||
admin_error!(
|
error!(
|
||||||
"uuid \"does not exist\" found in create set! {:?}",
|
"uuid \"does not exist\" found in create set! THIS IS A BUG. PLEASE REPORT IT IMMEDIATELY."
|
||||||
UUID_DOES_NOT_EXIST
|
|
||||||
);
|
);
|
||||||
return Err(OperationError::Plugin(PluginError::Base(
|
return Err(OperationError::Plugin(PluginError::Base(
|
||||||
"UUID_DOES_NOT_EXIST may not exist!".to_string(),
|
"Attempt to create UUID_DOES_NOT_EXIST".to_string(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1962,6 +1962,15 @@ impl<'a> SchemaWriteTransaction<'a> {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
self.classes.insert(
|
||||||
|
EntryClass::Builtin.into(),
|
||||||
|
SchemaClass {
|
||||||
|
name: EntryClass::Builtin.into(),
|
||||||
|
uuid: UUID_SCHEMA_CLASS_BUILTIN,
|
||||||
|
description: String::from("A marker class denoting builtin entries"),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
self.classes.insert(
|
self.classes.insert(
|
||||||
EntryClass::MemberOf.into(),
|
EntryClass::MemberOf.into(),
|
||||||
SchemaClass {
|
SchemaClass {
|
||||||
|
|
|
@ -888,6 +888,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
// Update anonymous with the correct entry manager,
|
// Update anonymous with the correct entry manager,
|
||||||
BUILTIN_ACCOUNT_ANONYMOUS_DL6.clone().into(),
|
BUILTIN_ACCOUNT_ANONYMOUS_DL6.clone().into(),
|
||||||
];
|
];
|
||||||
|
self.reload()?;
|
||||||
|
|
||||||
idm_access_controls
|
idm_access_controls
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -897,6 +898,15 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
err
|
err
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
// all the built-in objects get a builtin class
|
||||||
|
let filter = f_lt(
|
||||||
|
Attribute::Uuid,
|
||||||
|
PartialValue::Uuid(DYNAMIC_RANGE_MINIMUM_UUID),
|
||||||
|
);
|
||||||
|
let modlist = modlist!([m_pres(Attribute::Class, &EntryClass::Builtin.into())]);
|
||||||
|
|
||||||
|
self.internal_modify(&filter!(filter), &modlist)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -927,6 +937,10 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
pub fn initialise_schema_idm(&mut self) -> Result<(), OperationError> {
|
pub fn initialise_schema_idm(&mut self) -> Result<(), OperationError> {
|
||||||
admin_debug!("initialise_schema_idm -> start ...");
|
admin_debug!("initialise_schema_idm -> start ...");
|
||||||
|
|
||||||
|
// ⚠️ DOMAIN LEVEL 1 SCHEMA ATTRIBUTES ⚠️
|
||||||
|
// Future schema attributes need to be added via migrations.
|
||||||
|
//
|
||||||
|
// DO NOT MODIFY THIS DEFINITION
|
||||||
let idm_schema_attrs = [
|
let idm_schema_attrs = [
|
||||||
SCHEMA_ATTR_SYNC_CREDENTIAL_PORTAL.clone().into(),
|
SCHEMA_ATTR_SYNC_CREDENTIAL_PORTAL.clone().into(),
|
||||||
SCHEMA_ATTR_SYNC_YIELD_AUTHORITY.clone().into(),
|
SCHEMA_ATTR_SYNC_YIELD_AUTHORITY.clone().into(),
|
||||||
|
@ -941,7 +955,10 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
}
|
}
|
||||||
debug_assert!(r.is_ok());
|
debug_assert!(r.is_ok());
|
||||||
|
|
||||||
// List of IDM schemas to init.
|
// ⚠️ DOMAIN LEVEL 1 SCHEMA ATTRIBUTES ⚠️
|
||||||
|
// Future schema classes need to be added via migrations.
|
||||||
|
//
|
||||||
|
// DO NOT MODIFY THIS DEFINITION
|
||||||
let idm_schema: Vec<EntryInitNew> = vec![
|
let idm_schema: Vec<EntryInitNew> = vec![
|
||||||
SCHEMA_ATTR_MAIL.clone().into(),
|
SCHEMA_ATTR_MAIL.clone().into(),
|
||||||
SCHEMA_ATTR_ACCOUNT_EXPIRE.clone().into(),
|
SCHEMA_ATTR_ACCOUNT_EXPIRE.clone().into(),
|
||||||
|
@ -1013,7 +1030,11 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
|
|
||||||
debug_assert!(r.is_ok());
|
debug_assert!(r.is_ok());
|
||||||
|
|
||||||
let idm_schema_classes: Vec<EntryInitNew> = vec![
|
// ⚠️ DOMAIN LEVEL 1 SCHEMA CLASSES ⚠️
|
||||||
|
// Future schema classes need to be added via migrations.
|
||||||
|
//
|
||||||
|
// DO NOT MODIFY THIS DEFINITION
|
||||||
|
let idm_schema_classes_dl1: Vec<EntryInitNew> = vec![
|
||||||
SCHEMA_CLASS_ACCOUNT.clone().into(),
|
SCHEMA_CLASS_ACCOUNT.clone().into(),
|
||||||
SCHEMA_CLASS_ACCOUNT_POLICY.clone().into(),
|
SCHEMA_CLASS_ACCOUNT_POLICY.clone().into(),
|
||||||
SCHEMA_CLASS_DOMAIN_INFO.clone().into(),
|
SCHEMA_CLASS_DOMAIN_INFO.clone().into(),
|
||||||
|
@ -1031,7 +1052,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
SCHEMA_CLASS_OAUTH2_RS_PUBLIC.clone().into(),
|
SCHEMA_CLASS_OAUTH2_RS_PUBLIC.clone().into(),
|
||||||
];
|
];
|
||||||
|
|
||||||
let r: Result<(), _> = idm_schema_classes
|
let r: Result<(), _> = idm_schema_classes_dl1
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.try_for_each(|entry| self.internal_migrate_or_create(entry));
|
.try_for_each(|entry| self.internal_migrate_or_create(entry));
|
||||||
|
|
||||||
|
@ -1096,6 +1117,10 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
debug_assert!(res.is_ok());
|
debug_assert!(res.is_ok());
|
||||||
res?;
|
res?;
|
||||||
|
|
||||||
|
// ⚠️ DOMAIN LEVEL 1 ENTRIES ⚠️
|
||||||
|
// Future entries need to be added via migrations.
|
||||||
|
//
|
||||||
|
// DO NOT MODIFY THIS DEFINITION
|
||||||
let idm_entries: Vec<BuiltinAcp> = vec![
|
let idm_entries: Vec<BuiltinAcp> = vec![
|
||||||
// Built in access controls.
|
// Built in access controls.
|
||||||
IDM_ACP_RECYCLE_BIN_SEARCH_V1.clone(),
|
IDM_ACP_RECYCLE_BIN_SEARCH_V1.clone(),
|
||||||
|
|
|
@ -999,7 +999,7 @@ pub enum OauthClaimMapJoin {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OauthClaimMapJoin {
|
impl OauthClaimMapJoin {
|
||||||
pub(crate) fn to_char(&self) -> char {
|
pub(crate) fn to_char(self) -> char {
|
||||||
match self {
|
match self {
|
||||||
OauthClaimMapJoin::CommaSeparatedValue => ',',
|
OauthClaimMapJoin::CommaSeparatedValue => ',',
|
||||||
OauthClaimMapJoin::SpaceSeparatedValue => ' ',
|
OauthClaimMapJoin::SpaceSeparatedValue => ' ',
|
||||||
|
|
|
@ -89,8 +89,11 @@ impl ValueSetT for ValueSetUuid {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lessthan(&self, _pv: &PartialValue) -> bool {
|
fn lessthan(&self, pv: &PartialValue) -> bool {
|
||||||
false
|
match pv {
|
||||||
|
PartialValue::Uuid(u) => self.set.iter().any(|v| v < u),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
|
@ -257,8 +260,11 @@ impl ValueSetT for ValueSetRefer {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lessthan(&self, _pv: &PartialValue) -> bool {
|
fn lessthan(&self, pv: &PartialValue) -> bool {
|
||||||
false
|
match pv {
|
||||||
|
PartialValue::Refer(u) => self.set.iter().any(|v| v < u),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
// use tempfile::tempdir;
|
// use tempfile::tempdir;
|
||||||
|
|
||||||
use kanidm_client::KanidmClient;
|
use kanidm_client::KanidmClient;
|
||||||
|
use kanidmd_lib::constants::EntryClass;
|
||||||
use kanidmd_testkit::login_put_admin_idm_admins;
|
use kanidmd_testkit::login_put_admin_idm_admins;
|
||||||
// use testkit_macros::cli_kanidm;
|
// use testkit_macros::cli_kanidm;
|
||||||
|
|
||||||
|
@ -96,7 +97,7 @@ async fn test_webdriver_user_login(rsclient: kanidm_client::KanidmClient) {
|
||||||
|
|
||||||
println!("Waiting for page to load");
|
println!("Waiting for page to load");
|
||||||
let mut wait_attempts = 0;
|
let mut wait_attempts = 0;
|
||||||
while wait_attempts < 10 {
|
loop {
|
||||||
tokio::time::sleep(tokio::time::Duration::from_micros(200)).await;
|
tokio::time::sleep(tokio::time::Duration::from_micros(200)).await;
|
||||||
c.wait();
|
c.wait();
|
||||||
|
|
||||||
|
@ -225,6 +226,24 @@ async fn test_idm_domain_set_ldap_basedn(rsclient: KanidmClient) {
|
||||||
.is_err());
|
.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[kanidmd_testkit::test]
|
||||||
|
/// Checks that a built-in group idm_all_persons has the "builtin" class as expected.
|
||||||
|
async fn test_all_persons_has_builtin_class(rsclient: KanidmClient) {
|
||||||
|
login_put_admin_idm_admins(&rsclient).await;
|
||||||
|
let res = rsclient
|
||||||
|
.idm_group_get("idm_all_persons")
|
||||||
|
.await
|
||||||
|
.expect("Failed to get idm_all_persons");
|
||||||
|
eprintln!("res: {:?}", res);
|
||||||
|
|
||||||
|
assert!(res
|
||||||
|
.unwrap()
|
||||||
|
.attrs
|
||||||
|
.get("class")
|
||||||
|
.unwrap()
|
||||||
|
.contains(&EntryClass::Builtin.as_ref().into()));
|
||||||
|
}
|
||||||
|
|
||||||
// /// run a test command as the admin user
|
// /// run a test command as the admin user
|
||||||
// fn test_cmd_admin(token_cache_path: &str, rsclient: &KanidmClient, cmd: &str) -> Output {
|
// fn test_cmd_admin(token_cache_path: &str, rsclient: &KanidmClient, cmd: &str) -> Output {
|
||||||
// let split_cmd: Vec<&str> = cmd.split_ascii_whitespace().collect();
|
// let split_cmd: Vec<&str> = cmd.split_ascii_whitespace().collect();
|
||||||
|
|
Loading…
Reference in a new issue