diff --git a/proto/src/internal/error.rs b/proto/src/internal/error.rs index 0c3076876..09f6cb144 100644 --- a/proto/src/internal/error.rs +++ b/proto/src/internal/error.rs @@ -222,6 +222,7 @@ pub enum OperationError { MG0006SKConstraintsNotMet, MG0007Oauth2StrictConstraintsNotMet, MG0008SkipUpgradeAttempted, + MG0009InvalidTargetLevelForBootstrap, // KP0001KeyProviderNotLoaded, KP0002KeyProviderInvalidClass, @@ -462,6 +463,7 @@ impl OperationError { Self::MG0006SKConstraintsNotMet => Some("Migration Constraints Not Met - Security Keys should not be present.".into()), Self::MG0007Oauth2StrictConstraintsNotMet => Some("Migration Constraints Not Met - All OAuth2 clients must have strict-redirect-uri mode enabled.".into()), Self::MG0008SkipUpgradeAttempted => Some("Skip Upgrade Attempted.".into()), + Self::MG0009InvalidTargetLevelForBootstrap => Some("The request target domain level was not valid for bootstrapping a new server instance".into()), Self::PL0001GidOverlapsSystemRange => None, Self::SC0001IncomingSshPublicKey => None, Self::SC0002ReferenceSyntaxInvalid => Some("A SCIM Reference Set contained invalid syntax and can not be processed.".into()), diff --git a/server/lib/src/constants/entries.rs b/server/lib/src/constants/entries.rs index 753885c9c..36f48aac4 100644 --- a/server/lib/src/constants/entries.rs +++ b/server/lib/src/constants/entries.rs @@ -1,20 +1,12 @@ //! Constant Entries for the IDM use std::fmt::Display; -use crate::constants::groups::idm_builtin_admin_groups; -use crate::constants::uuids::*; -use crate::entry::{Entry, EntryInit, EntryInitNew, EntryNew}; -use crate::idm::account::Account; use crate::value::PartialValue; use crate::value::Value; use crate::valueset::{ValueSet, ValueSetIutf8}; pub use kanidm_proto::attribute::Attribute; use kanidm_proto::constants::*; -use kanidm_proto::internal::OperationError; use kanidm_proto::scim_v1::JsonValue; -use kanidm_proto::v1::AccountType; - -use uuid::Uuid; //TODO: This would do well in the proto lib // together with all the other definitions. @@ -202,158 +194,9 @@ impl EntryClass { } } -lazy_static! { - /// Builtin System Admin account. - pub static ref BUILTIN_ACCOUNT_IDM_ADMIN: BuiltinAccount = BuiltinAccount { - account_type: AccountType::ServiceAccount, - entry_managed_by: None, - name: "idm_admin", - uuid: UUID_IDM_ADMIN, - description: "Builtin IDM Admin account.", - displayname: "IDM Administrator", - }; - - pub static ref E_SYSTEM_INFO_V1: EntryInitNew = entry_init!( - (Attribute::Class, EntryClass::Object.to_value()), - (Attribute::Class, EntryClass::SystemInfo.to_value()), - (Attribute::Class, EntryClass::System.to_value()), - (Attribute::Uuid, Value::Uuid(UUID_SYSTEM_INFO)), - ( - Attribute::Description, - Value::new_utf8s("System (local) info and metadata object.") - ), - (Attribute::Version, Value::Uint32(20)) - ); - - pub static ref E_DOMAIN_INFO_DL6: EntryInitNew = entry_init!( - (Attribute::Class, EntryClass::Object.to_value()), - (Attribute::Class, EntryClass::DomainInfo.to_value()), - (Attribute::Class, EntryClass::System.to_value()), - (Attribute::Class, EntryClass::KeyObject.to_value()), - (Attribute::Class, EntryClass::KeyObjectJwtEs256.to_value()), - (Attribute::Class, EntryClass::KeyObjectJweA128GCM.to_value()), - (Attribute::Name, Value::new_iname("domain_local")), - (Attribute::Uuid, Value::Uuid(UUID_DOMAIN_INFO)), - ( - Attribute::Description, - Value::new_utf8s("This local domain's info and metadata object.") - ) - ); -} - -#[derive(Debug, Clone)] -/// Built in accounts such as anonymous, idm_admin and admin -pub struct BuiltinAccount { - pub account_type: kanidm_proto::v1::AccountType, - pub entry_managed_by: Option, - pub name: &'static str, - pub uuid: Uuid, - pub description: &'static str, - pub displayname: &'static str, -} - -impl Default for BuiltinAccount { - fn default() -> Self { - BuiltinAccount { - account_type: AccountType::ServiceAccount, - entry_managed_by: None, - name: "", - uuid: Uuid::new_v4(), - description: "", - displayname: "", - } - } -} - -impl From for Account { - fn from(value: BuiltinAccount) -> Self { - #[allow(clippy::panic)] - if value.uuid >= DYNAMIC_RANGE_MINIMUM_UUID { - panic!("Builtin ACP has invalid UUID! {:?}", value); - } - Account { - name: value.name.to_string(), - uuid: value.uuid, - displayname: value.displayname.to_string(), - spn: format!("{}@example.com", value.name), - mail_primary: None, - mail: Vec::with_capacity(0), - ..Default::default() - } - } -} - -impl From for EntryInitNew { - fn from(value: BuiltinAccount) -> Self { - let mut entry = EntryInitNew::new(); - 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::Description, Value::new_utf8s(value.description)); - entry.add_ava(Attribute::DisplayName, Value::new_utf8s(value.displayname)); - - if let Some(entry_manager) = value.entry_managed_by { - entry.add_ava(Attribute::EntryManagedBy, Value::Refer(entry_manager)); - } - - entry.set_ava( - Attribute::Class, - vec![ - EntryClass::Account.to_value(), - EntryClass::MemberOf.to_value(), - EntryClass::Object.to_value(), - ], - ); - match value.account_type { - AccountType::Person => entry.add_ava(Attribute::Class, EntryClass::Person.to_value()), - AccountType::ServiceAccount => { - entry.add_ava(Attribute::Class, EntryClass::ServiceAccount.to_value()) - } - } - entry - } -} - -lazy_static! { - /// Builtin System Admin account. - pub static ref BUILTIN_ACCOUNT_ADMIN: BuiltinAccount = BuiltinAccount { - account_type: AccountType::ServiceAccount, - entry_managed_by: None, - name: "admin", - uuid: UUID_ADMIN, - description: "Builtin System Admin account.", - displayname: "System Administrator", - }; -} - -lazy_static! { - pub static ref BUILTIN_ACCOUNT_ANONYMOUS_DL6: BuiltinAccount = BuiltinAccount { - account_type: AccountType::ServiceAccount, - entry_managed_by: Some(UUID_IDM_ADMINS), - name: "anonymous", - uuid: UUID_ANONYMOUS, - description: "Anonymous access account.", - displayname: "Anonymous", - }; -} - -pub fn builtin_accounts() -> Vec<&'static BuiltinAccount> { - vec![ - &BUILTIN_ACCOUNT_ADMIN, - &BUILTIN_ACCOUNT_IDM_ADMIN, - &BUILTIN_ACCOUNT_ANONYMOUS_DL6, - ] -} - // ============ TEST DATA ============ #[cfg(test)] -pub const UUID_TESTPERSON_1: Uuid = ::uuid::uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"); - -#[cfg(test)] -pub const UUID_TESTPERSON_2: Uuid = ::uuid::uuid!("538faac7-4d29-473b-a59d-23023ac19955"); +use crate::entry::{Entry, EntryInit, EntryInitNew, EntryNew}; #[cfg(test)] lazy_static! { @@ -363,7 +206,10 @@ lazy_static! { (Attribute::Class, EntryClass::Person.to_value()), (Attribute::Name, Value::new_iname("testperson1")), (Attribute::DisplayName, Value::new_utf8s("Test Person 1")), - (Attribute::Uuid, Value::Uuid(UUID_TESTPERSON_1)) + ( + Attribute::Uuid, + Value::Uuid(super::uuids::UUID_TESTPERSON_1) + ) ); pub static ref E_TESTPERSON_2: EntryInitNew = entry_init!( (Attribute::Class, EntryClass::Object.to_value()), @@ -371,28 +217,9 @@ lazy_static! { (Attribute::Class, EntryClass::Person.to_value()), (Attribute::Name, Value::new_iname("testperson2")), (Attribute::DisplayName, Value::new_utf8s("Test Person 2")), - (Attribute::Uuid, Value::Uuid(UUID_TESTPERSON_2)) + ( + Attribute::Uuid, + Value::Uuid(super::uuids::UUID_TESTPERSON_2) + ) ); } - -// ⚠️ DOMAIN LEVEL 1 ENTRIES ⚠️ -// Future entries need to be added via migrations. -// -// DO NOT MODIFY THIS DEFINITION - -/// Build a list of internal admin entries -pub fn idm_builtin_admin_entries() -> Result, OperationError> { - let mut res: Vec = vec![ - BUILTIN_ACCOUNT_ADMIN.clone().into(), - BUILTIN_ACCOUNT_IDM_ADMIN.clone().into(), - ]; - for group in idm_builtin_admin_groups() { - let g: EntryInitNew = group.clone().try_into()?; - res.push(g); - } - - // We need to push anonymous *after* groups due to entry-managed-by - res.push(BUILTIN_ACCOUNT_ANONYMOUS_DL6.clone().into()); - - Ok(res) -} diff --git a/server/lib/src/constants/mod.rs b/server/lib/src/constants/mod.rs index f9ebb387b..35be1d8b4 100644 --- a/server/lib/src/constants/mod.rs +++ b/server/lib/src/constants/mod.rs @@ -1,20 +1,10 @@ // Re-export as needed -pub mod acp; pub mod entries; -pub mod groups; -mod key_providers; -pub mod schema; -pub mod system_config; pub mod uuids; pub mod values; -pub use self::acp::*; pub use self::entries::*; -pub use self::groups::*; -pub use self::key_providers::*; -pub use self::schema::*; -pub use self::system_config::*; pub use self::uuids::*; pub use self::values::*; diff --git a/server/lib/src/constants/uuids.rs b/server/lib/src/constants/uuids.rs index 1389f465c..a5da5dcb3 100644 --- a/server/lib/src/constants/uuids.rs +++ b/server/lib/src/constants/uuids.rs @@ -6,6 +6,7 @@ use uuid::{uuid, Uuid}; pub const STR_UUID_ADMIN: &str = "00000000-0000-0000-0000-000000000000"; pub const UUID_ADMIN: Uuid = uuid!("00000000-0000-0000-0000-000000000000"); pub const UUID_IDM_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000001"); +pub const NAME_IDM_ADMINS: &str = "idm_admins"; pub const UUID_IDM_PEOPLE_PII_READ: Uuid = uuid!("00000000-0000-0000-0000-000000000002"); pub const UUID_IDM_PEOPLE_WRITE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000003"); pub const UUID_IDM_GROUP_WRITE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000004"); @@ -26,6 +27,8 @@ pub const UUID_IDM_ADMIN: Uuid = uuid!("00000000-0000-0000-0000-000000000018"); pub const STR_UUID_SYSTEM_ADMINS: &str = "00000000-0000-0000-0000-000000000019"; pub const UUID_SYSTEM_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000019"); +pub const NAME_SYSTEM_ADMINS: &str = "system_admins"; + pub const UUID_DOMAIN_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000020"); pub const UUID_IDM_ACCOUNT_UNIX_EXTEND_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000021"); pub const UUID_IDM_GROUP_UNIX_EXTEND_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000022"); @@ -50,6 +53,7 @@ pub const UUID_IDM_HP_SERVICE_ACCOUNT_INTO_PERSON_MIGRATE_PRIV: Uuid = pub const UUID_IDM_ALL_PERSONS: Uuid = uuid!("00000000-0000-0000-0000-000000000035"); pub const STR_UUID_IDM_ALL_ACCOUNTS: &str = "00000000-0000-0000-0000-000000000036"; pub const UUID_IDM_ALL_ACCOUNTS: Uuid = uuid!("00000000-0000-0000-0000-000000000036"); +pub const NAME_IDM_ALL_ACCOUNTS: &str = "idm_all_accounts"; pub const UUID_IDM_HP_SYNC_ACCOUNT_MANAGE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000037"); @@ -452,3 +456,9 @@ pub const UUID_DOES_NOT_EXIST: Uuid = uuid!("00000000-0000-0000-0000-fffffffffff pub const UUID_ANONYMOUS: Uuid = uuid!("00000000-0000-0000-0000-ffffffffffff"); pub const DYNAMIC_RANGE_MINIMUM_UUID: Uuid = uuid!("00000000-0000-0000-0001-000000000000"); + +// ======= test data ====== +#[cfg(test)] +pub const UUID_TESTPERSON_1: Uuid = uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"); +#[cfg(test)] +pub const UUID_TESTPERSON_2: Uuid = uuid!("538faac7-4d29-473b-a59d-23023ac19955"); diff --git a/server/lib/src/event.rs b/server/lib/src/event.rs index 6b98f97f6..e9019693e 100644 --- a/server/lib/src/event.rs +++ b/server/lib/src/event.rs @@ -636,23 +636,6 @@ impl ModifyEvent { } } - /// ⚠️ - Bypass the schema state machine and force the filter to be considered valid. - /// This is a TEST ONLY method and will never be exposed in production. - #[cfg(test)] - pub fn new_impersonate_entry_ser( - e: BuiltinAccount, - filter: Filter, - modlist: ModifyList, - ) -> Self { - let ei: EntryInitNew = e.into(); - ModifyEvent { - ident: Identity::from_impersonate_entry_readwrite(Arc::new(ei.into_sealed_committed())), - filter: filter.clone().into_valid(), - filter_orig: filter.into_valid(), - modlist: modlist.into_valid(), - } - } - /// ⚠️ - Bypass the schema state machine and force the filter to be considered valid. /// This is a TEST ONLY method and will never be exposed in production. #[cfg(test)] diff --git a/server/lib/src/idm/account.rs b/server/lib/src/idm/account.rs index abe011de4..17b481f78 100644 --- a/server/lib/src/idm/account.rs +++ b/server/lib/src/idm/account.rs @@ -1041,18 +1041,10 @@ impl IdmServerProxyReadTransaction<'_> { #[cfg(test)] mod tests { - use crate::idm::account::Account; use crate::idm::accountpolicy::ResolvedAccountPolicy; use crate::prelude::*; use kanidm_proto::internal::UiHint; - #[test] - fn test_idm_account_from_anonymous() { - let account: Account = BUILTIN_ACCOUNT_ANONYMOUS_DL6.clone().into(); - debug!("{:?}", account); - // I think that's it? we may want to check anonymous mech ... - } - #[idm_test] async fn test_idm_account_ui_hints(idms: &IdmServer, _idms_delayed: &mut IdmServerDelayed) { let ct = duration_from_epoch_now(); diff --git a/server/lib/src/idm/authsession.rs b/server/lib/src/idm/authsession.rs index 0d544019e..02cdb96c8 100644 --- a/server/lib/src/idm/authsession.rs +++ b/server/lib/src/idm/authsession.rs @@ -1716,6 +1716,7 @@ mod tests { }; use crate::idm::delayed::DelayedAction; use crate::idm::AuthState; + use crate::migration_data::{BUILTIN_ACCOUNT_ANONYMOUS, BUILTIN_ACCOUNT_TEST_PERSON}; use crate::prelude::*; use crate::server::keys::KeyObjectInternal; use crate::utils::readable_password_from_random; @@ -1742,7 +1743,7 @@ mod tests { let webauthn = create_webauthn(); - let anon_account: Account = BUILTIN_ACCOUNT_ANONYMOUS_DL6.clone().into(); + let anon_account: Account = BUILTIN_ACCOUNT_ANONYMOUS.clone().into(); let asd = AuthSessionData { account: anon_account, @@ -1819,7 +1820,7 @@ mod tests { fn start_session_simple_password_mech(privileged: bool) -> UserAuthToken { let webauthn = create_webauthn(); // create the ent - let mut account: Account = BUILTIN_ACCOUNT_ADMIN.clone().into(); + let mut account: Account = BUILTIN_ACCOUNT_TEST_PERSON.clone().into(); // manually load in a cred let p = CryptoPolicy::minimum(); let cred = Credential::new_password_only(&p, "test_password").unwrap(); @@ -1920,7 +1921,7 @@ mod tests { sketching::test_init(); let webauthn = create_webauthn(); // create the ent - let mut account: Account = BUILTIN_ACCOUNT_ADMIN.clone().into(); + let mut account: Account = BUILTIN_ACCOUNT_TEST_PERSON.clone().into(); // manually load in a cred let p = CryptoPolicy::minimum(); let cred = Credential::new_password_only(&p, "list@no3IBTyqHu$bad").unwrap(); @@ -2087,7 +2088,7 @@ mod tests { sketching::test_init(); let webauthn = create_webauthn(); // create the ent - let mut account: Account = BUILTIN_ACCOUNT_ADMIN.clone().into(); + let mut account: Account = BUILTIN_ACCOUNT_TEST_PERSON.clone().into(); // Setup a fake time stamp for consistency. let ts = Duration::from_secs(12345); @@ -2264,7 +2265,7 @@ mod tests { sketching::test_init(); let webauthn = create_webauthn(); // create the ent - let mut account: Account = BUILTIN_ACCOUNT_ADMIN.clone().into(); + let mut account: Account = BUILTIN_ACCOUNT_TEST_PERSON.clone().into(); // Setup a fake time stamp for consistency. let ts = Duration::from_secs(12345); @@ -2440,7 +2441,7 @@ mod tests { let (audit_tx, mut audit_rx) = unbounded(); let ts = duration_from_epoch_now(); // create the ent - let mut account: Account = BUILTIN_ACCOUNT_ADMIN.clone().into(); + let mut account: Account = BUILTIN_ACCOUNT_TEST_PERSON.clone().into(); let (webauthn, mut wa, wan_cred) = setup_webauthn_passkey(account.name.as_str()); @@ -2594,7 +2595,7 @@ mod tests { let (audit_tx, mut audit_rx) = unbounded(); let ts = duration_from_epoch_now(); // create the ent - let mut account: Account = BUILTIN_ACCOUNT_ADMIN.clone().into(); + let mut account: Account = BUILTIN_ACCOUNT_TEST_PERSON.clone().into(); let (webauthn, mut wa, wan_cred) = setup_webauthn_securitykey(account.name.as_str()); let pw_good = "test_password"; @@ -2787,7 +2788,7 @@ mod tests { let (audit_tx, mut audit_rx) = unbounded(); let ts = duration_from_epoch_now(); // create the ent - let mut account: Account = BUILTIN_ACCOUNT_ADMIN.clone().into(); + let mut account: Account = BUILTIN_ACCOUNT_TEST_PERSON.clone().into(); let (webauthn, mut wa, wan_cred) = setup_webauthn_securitykey(account.name.as_str()); @@ -3053,7 +3054,7 @@ mod tests { sketching::test_init(); let webauthn = create_webauthn(); // create the ent - let mut account: Account = BUILTIN_ACCOUNT_ADMIN.clone().into(); + let mut account: Account = BUILTIN_ACCOUNT_TEST_PERSON.clone().into(); // Setup a fake time stamp for consistency. let ts = Duration::from_secs(12345); @@ -3262,7 +3263,7 @@ mod tests { sketching::test_init(); let webauthn = create_webauthn(); // create the ent - let mut account: Account = BUILTIN_ACCOUNT_ADMIN.clone().into(); + let mut account: Account = BUILTIN_ACCOUNT_TEST_PERSON.clone().into(); // Setup a fake time stamp for consistency. let ts = Duration::from_secs(12345); diff --git a/server/lib/src/idm/ldap.rs b/server/lib/src/idm/ldap.rs index de521bd78..4b7a4e37e 100644 --- a/server/lib/src/idm/ldap.rs +++ b/server/lib/src/idm/ldap.rs @@ -1989,7 +1989,7 @@ mod tests { let me = ModifyEvent::new_internal_invalid( filter!(f_eq( Attribute::Name, - PartialValue::new_iname(BUILTIN_GROUP_PEOPLE_PII_READ.name) + PartialValue::new_iname("idm_people_pii_read") )), ModifyList::new_list(vec![Modify::Present( Attribute::Member, diff --git a/server/lib/src/lib.rs b/server/lib/src/lib.rs index 562042536..870b19b0b 100644 --- a/server/lib/src/lib.rs +++ b/server/lib/src/lib.rs @@ -50,6 +50,12 @@ pub mod credential; pub mod entry; pub mod event; pub mod filter; + +// If this module is ever made public outside of this crate, firstyear will be extremely sad. +// This is *purely migration data*. Don't even think about using it in test cases for anything +// else. +pub(crate) mod migration_data; + pub mod modify; pub mod time; pub(crate) mod utils; diff --git a/server/lib/src/constants/acp.rs b/server/lib/src/migration_data/dl10/access.rs similarity index 100% rename from server/lib/src/constants/acp.rs rename to server/lib/src/migration_data/dl10/access.rs diff --git a/server/lib/src/migration_data/dl10/accounts.rs b/server/lib/src/migration_data/dl10/accounts.rs new file mode 100644 index 000000000..f7b6a065a --- /dev/null +++ b/server/lib/src/migration_data/dl10/accounts.rs @@ -0,0 +1,35 @@ +//! Constant Entries for the IDM +use crate::constants::uuids::*; +use crate::migration_data::types::BuiltinAccount; +use kanidm_proto::v1::AccountType; + +lazy_static! { + /// Builtin System Admin account. + pub static ref BUILTIN_ACCOUNT_IDM_ADMIN: BuiltinAccount = BuiltinAccount { + account_type: AccountType::ServiceAccount, + entry_managed_by: None, + name: "idm_admin", + uuid: UUID_IDM_ADMIN, + description: "Builtin IDM Admin account.", + displayname: "IDM Administrator", + }; + + /// Builtin System Admin account. + pub static ref BUILTIN_ACCOUNT_ADMIN: BuiltinAccount = BuiltinAccount { + account_type: AccountType::ServiceAccount, + entry_managed_by: None, + name: "admin", + uuid: UUID_ADMIN, + description: "Builtin System Admin account.", + displayname: "System Administrator", + }; + + pub static ref BUILTIN_ACCOUNT_ANONYMOUS_DL6: BuiltinAccount = BuiltinAccount { + account_type: AccountType::ServiceAccount, + entry_managed_by: Some(UUID_IDM_ADMINS), + name: "anonymous", + uuid: UUID_ANONYMOUS, + description: "Anonymous access account.", + displayname: "Anonymous", + }; +} diff --git a/server/lib/src/migration_data/dl10/groups.rs b/server/lib/src/migration_data/dl10/groups.rs new file mode 100644 index 000000000..568bf8987 --- /dev/null +++ b/server/lib/src/migration_data/dl10/groups.rs @@ -0,0 +1,408 @@ +use crate::entry::EntryInitNew; +use crate::prelude::*; +use crate::value::CredentialType; + +use kanidm_proto::internal::{Filter, OperationError, UiHint}; + +#[derive(Clone, Debug, Default)] +/// Built-in group definitions +pub struct BuiltinGroup { + pub name: &'static str, + pub description: &'static str, + pub uuid: uuid::Uuid, + pub members: Vec, + pub entry_managed_by: Option, + pub dyngroup: bool, + pub dyngroup_filter: Option, + pub extra_attributes: Vec<(Attribute, Value)>, +} + +impl TryFrom for EntryInitNew { + type Error = OperationError; + + fn try_from(val: BuiltinGroup) -> Result { + 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::Description, Value::new_utf8s(val.description)); + // classes for groups + entry.set_ava( + Attribute::Class, + vec![EntryClass::Group.into(), EntryClass::Object.into()], + ); + if val.dyngroup { + if !val.members.is_empty() { + return Err(OperationError::InvalidSchemaState(format!( + "Builtin dyngroup {} has members specified, this is not allowed", + val.name + ))); + } + entry.add_ava(Attribute::Class, EntryClass::DynGroup.to_value()); + match val.dyngroup_filter { + Some(filter) => entry.add_ava(Attribute::DynGroupFilter, Value::JsonFilt(filter)), + None => { + error!( + "No filter specified for dyngroup '{}' this is going to break things!", + val.name + ); + return Err(OperationError::FilterGeneration); + } + }; + } + + if let Some(entry_manager) = val.entry_managed_by { + entry.add_ava(Attribute::EntryManagedBy, Value::Refer(entry_manager)); + } + + entry.add_ava(Attribute::Uuid, Value::Uuid(val.uuid)); + entry.set_ava( + Attribute::Member, + val.members + .into_iter() + .map(Value::Refer) + .collect::>(), + ); + // add any extra attributes + val.extra_attributes + .into_iter() + .for_each(|(attr, val)| entry.add_ava(attr, val)); + // all done! + Ok(entry) + } +} + +lazy_static! { + // There are our built in "roles". They encapsulate some higher level collections + // of roles. The intent is to allow a pretty generic and correct by default set + // of these use cases. + pub static ref BUILTIN_GROUP_SYSTEM_ADMINS_V1: BuiltinGroup = BuiltinGroup { + name: NAME_SYSTEM_ADMINS, + description: "Builtin System Administrators Group.", + uuid: UUID_SYSTEM_ADMINS, + entry_managed_by: Some(UUID_SYSTEM_ADMINS), + members: vec![UUID_ADMIN], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_IDM_ADMINS_V1: BuiltinGroup = BuiltinGroup { + name: NAME_IDM_ADMINS, + description: "Builtin IDM Administrators Group.", + uuid: UUID_IDM_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMIN], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_SERVICE_DESK: BuiltinGroup = BuiltinGroup { + name: "idm_service_desk", + description: "Builtin Service Desk Group.", + uuid: UUID_IDM_SERVICE_DESK, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![], + ..Default::default() + }; +} + +lazy_static! { + // These are the "finer" roles. They encapsulate different concepts in the system. + // The next section is the "system style" roles. These adjust the operation of + // kanidm and relate to it's internals and how it functions. + pub static ref BUILTIN_GROUP_RECYCLE_BIN_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_recycle_bin_admins", + description: "Builtin Recycle Bin Administrators Group.", + uuid: UUID_IDM_RECYCLE_BIN_ADMINS, + entry_managed_by: Some(UUID_SYSTEM_ADMINS), + members: vec![UUID_SYSTEM_ADMINS], + ..Default::default() + }; + + /// Builtin IDM Group for granting local domain administration rights and trust administration rights + pub static ref BUILTIN_GROUP_DOMAIN_ADMINS: BuiltinGroup = BuiltinGroup { + name: "domain_admins", + description: "Builtin IDM Group for granting local domain administration rights and trust administration rights.", + uuid: UUID_DOMAIN_ADMINS, + entry_managed_by: Some(UUID_SYSTEM_ADMINS), + members: vec![UUID_SYSTEM_ADMINS], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_SCHEMA_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_schema_admins", + description: "Builtin Schema Administration Group.", + uuid: UUID_IDM_SCHEMA_ADMINS, + entry_managed_by: Some(UUID_SYSTEM_ADMINS), + members: vec![UUID_SYSTEM_ADMINS], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_ACCESS_CONTROL_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_access_control_admins", + description: "Builtin Access Control Administration Group.", + entry_managed_by: Some(UUID_SYSTEM_ADMINS), + uuid: UUID_IDM_ACCESS_CONTROL_ADMINS, + members: vec![UUID_SYSTEM_ADMINS], + ..Default::default() + }; + + // These are the IDM roles. They concern application integration, user permissions + // and credential security management. + + /// Builtin IDM Group for managing persons and their account details + pub static ref BUILTIN_GROUP_PEOPLE_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_people_admins", + description: "Builtin People Administration Group.", + uuid: UUID_IDM_PEOPLE_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_PEOPLE_ON_BOARDING: BuiltinGroup = BuiltinGroup { + name: "idm_people_on_boarding", + description: "Builtin People On Boarding Group.", + uuid: UUID_IDM_PEOPLE_ON_BOARDING, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![], + ..Default::default() + }; + + /// Builtin IDM Group for granting elevated people (personal data) read permissions. + pub static ref BUILTIN_GROUP_PEOPLE_PII_READ: BuiltinGroup = BuiltinGroup { + name: "idm_people_pii_read", + description: "Builtin IDM Group for granting elevated people (personal data) read permissions.", + uuid: UUID_IDM_PEOPLE_PII_READ, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![], + ..Default::default() + }; + + /// Builtin IDM Group for granting people the ability to write to their own name attributes. + pub static ref BUILTIN_GROUP_PEOPLE_SELF_NAME_WRITE_DL7: BuiltinGroup = BuiltinGroup { + name: "idm_people_self_name_write", + description: "Builtin IDM Group denoting users that can write to their own name attributes.", + uuid: UUID_IDM_PEOPLE_SELF_NAME_WRITE, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![ + UUID_IDM_ALL_PERSONS + ], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_SERVICE_ACCOUNT_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_service_account_admins", + description: "Builtin Service Account Administration Group.", + uuid: UUID_IDM_SERVICE_ACCOUNT_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + /// Builtin IDM Group for managing oauth2 resource server integrations to this authentication domain. + pub static ref BUILTIN_GROUP_OAUTH2_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_oauth2_admins", + description: "Builtin Oauth2 Integration Administration Group.", + uuid: UUID_IDM_OAUTH2_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_RADIUS_SERVICE_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_radius_service_admins", + description: "Builtin Radius Administration Group.", + uuid: UUID_IDM_RADIUS_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + /// Builtin IDM Group for RADIUS server access delegation. + pub static ref BUILTIN_IDM_RADIUS_SERVERS_V1: BuiltinGroup = BuiltinGroup { + name: "idm_radius_servers", + description: "Builtin IDM Group for RADIUS server access delegation.", + uuid: UUID_IDM_RADIUS_SERVERS, + entry_managed_by: Some(UUID_IDM_RADIUS_ADMINS), + members: vec![ + ], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_MAIL_SERVICE_ADMINS_DL8: BuiltinGroup = BuiltinGroup { + name: "idm_mail_service_admins", + description: "Builtin Mail Server Administration Group.", + uuid: UUID_IDM_MAIL_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + /// Builtin IDM Group for MAIL server Access delegation. + pub static ref BUILTIN_IDM_MAIL_SERVERS_DL8: BuiltinGroup = BuiltinGroup { + name: "idm_mail_servers", + description: "Builtin IDM Group for MAIL server access delegation.", + uuid: UUID_IDM_MAIL_SERVERS, + entry_managed_by: Some(UUID_IDM_MAIL_ADMINS), + members: vec![ + ], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_ACCOUNT_POLICY_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_account_policy_admins", + description: "Builtin Account Policy Administration Group.", + uuid: UUID_IDM_ACCOUNT_POLICY_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + /// Builtin IDM Group for managing posix/unix attributes on groups and users. + pub static ref BUILTIN_GROUP_UNIX_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_unix_admins", + description: "Builtin Unix Administration Group.", + uuid: UUID_IDM_UNIX_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + /// Builtin IDM Group for managing client authentication certificates. + pub static ref BUILTIN_GROUP_CLIENT_CERTIFICATE_ADMINS_DL7: BuiltinGroup = BuiltinGroup { + name: "idm_client_certificate_admins", + description: "Builtin Client Certificate Administration Group.", + uuid: UUID_IDM_CLIENT_CERTIFICATE_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + /// Builtin IDM Group for granting elevated group write and lifecycle permissions. + pub static ref IDM_GROUP_ADMINS_V1: BuiltinGroup = BuiltinGroup { + name: "idm_group_admins", + description: "Builtin IDM Group for granting elevated group write and lifecycle permissions.", + uuid: UUID_IDM_GROUP_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + /// Self-write of mail + pub static ref IDM_PEOPLE_SELF_MAIL_WRITE_DL7: BuiltinGroup = BuiltinGroup { + name: "idm_people_self_mail_write", + description: "Builtin IDM Group for people accounts to update their own mail.", + uuid: UUID_IDM_PEOPLE_SELF_MAIL_WRITE, + members: Vec::with_capacity(0), + ..Default::default() + }; +} + +// at some point vs code just gives up on syntax highlighting inside lazy_static... +lazy_static! { + pub static ref IDM_ALL_PERSONS: BuiltinGroup = BuiltinGroup { + name: "idm_all_persons", + description: "Builtin IDM dynamic group containing all persons.", + uuid: UUID_IDM_ALL_PERSONS, + members: Vec::with_capacity(0), + dyngroup: true, + dyngroup_filter: Some( + Filter::And(vec![ + Filter::Eq(Attribute::Class.to_string(), EntryClass::Person.to_string()), + Filter::Eq(Attribute::Class.to_string(), EntryClass::Account.to_string()), + ]) + ), + extra_attributes: vec![ + // Enable account policy by default + (Attribute::Class, EntryClass::AccountPolicy.to_value()), + // Enforce this is a system protected object + (Attribute::Class, EntryClass::System.to_value()), + // MFA By Default + (Attribute::CredentialTypeMinimum, CredentialType::Mfa.into()), + ], + ..Default::default() + }; + + pub static ref IDM_ALL_ACCOUNTS: BuiltinGroup = BuiltinGroup { + name: NAME_IDM_ALL_ACCOUNTS, + description: "Builtin IDM dynamic group containing all entries that can authenticate.", + uuid: UUID_IDM_ALL_ACCOUNTS, + members: Vec::with_capacity(0), + dyngroup: true, + dyngroup_filter: Some( + Filter::Eq(Attribute::Class.to_string(), EntryClass::Account.to_string()), + ), + extra_attributes: vec![ + // Enable account policy by default + (Attribute::Class, EntryClass::AccountPolicy.to_value()), + // Enforce this is a system protected object + (Attribute::Class, EntryClass::System.to_value()), + ], + ..Default::default() + }; + + + pub static ref IDM_UI_ENABLE_EXPERIMENTAL_FEATURES: BuiltinGroup = BuiltinGroup { + name: "idm_ui_enable_experimental_features", + description: "Members of this group will have access to experimental web UI features.", + uuid: UUID_IDM_UI_ENABLE_EXPERIMENTAL_FEATURES, + entry_managed_by: Some(UUID_IDM_ADMINS), + extra_attributes: vec![ + (Attribute::GrantUiHint, Value::UiHint(UiHint::ExperimentalFeatures)) + ], + ..Default::default() + }; + + /// Members of this group will have access to read the mail attribute of all persons and service accounts. + pub static ref IDM_ACCOUNT_MAIL_READ: BuiltinGroup = BuiltinGroup { + name: "idm_account_mail_read", + description: "Members of this group will have access to read the mail attribute of all persons and service accounts.", + entry_managed_by: Some(UUID_IDM_ACCESS_CONTROL_ADMINS), + uuid: UUID_IDM_ACCOUNT_MAIL_READ, + ..Default::default() + }; + + /// This must be the last group to init to include the UUID of the other high priv groups. + pub static ref IDM_HIGH_PRIVILEGE_DL8: BuiltinGroup = BuiltinGroup { + name: "idm_high_privilege", + uuid: UUID_IDM_HIGH_PRIVILEGE, + entry_managed_by: Some(UUID_IDM_ACCESS_CONTROL_ADMINS), + description: "Builtin IDM provided groups with high levels of access that should be audited and limited in modification.", + members: vec![ + UUID_SYSTEM_ADMINS, + UUID_IDM_ADMINS, + UUID_DOMAIN_ADMINS, + UUID_IDM_SERVICE_DESK, + UUID_IDM_RECYCLE_BIN_ADMINS, + UUID_IDM_SCHEMA_ADMINS, + UUID_IDM_ACCESS_CONTROL_ADMINS, + UUID_IDM_OAUTH2_ADMINS, + UUID_IDM_RADIUS_ADMINS, + UUID_IDM_ACCOUNT_POLICY_ADMINS, + UUID_IDM_RADIUS_SERVERS, + UUID_IDM_GROUP_ADMINS, + UUID_IDM_UNIX_ADMINS, + UUID_IDM_PEOPLE_PII_READ, + UUID_IDM_PEOPLE_ADMINS, + UUID_IDM_PEOPLE_ON_BOARDING, + UUID_IDM_SERVICE_ACCOUNT_ADMINS, + UUID_IDM_CLIENT_CERTIFICATE_ADMINS, + UUID_IDM_APPLICATION_ADMINS, + UUID_IDM_MAIL_ADMINS, + UUID_IDM_HIGH_PRIVILEGE, + ], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_APPLICATION_ADMINS_DL8: BuiltinGroup = BuiltinGroup { + name: "idm_application_admins", + uuid: UUID_IDM_APPLICATION_ADMINS, + description: "Builtin Application Administration Group.", + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; +} diff --git a/server/lib/src/constants/key_providers.rs b/server/lib/src/migration_data/dl10/key_providers.rs similarity index 100% rename from server/lib/src/constants/key_providers.rs rename to server/lib/src/migration_data/dl10/key_providers.rs diff --git a/server/lib/src/migration_data/dl10/mod.rs b/server/lib/src/migration_data/dl10/mod.rs new file mode 100644 index 000000000..b4b961824 --- /dev/null +++ b/server/lib/src/migration_data/dl10/mod.rs @@ -0,0 +1,268 @@ +mod access; +pub(super) mod accounts; +mod groups; +mod key_providers; +mod schema; +mod system_config; + +use self::access::*; +use self::accounts::*; +use self::groups::*; +use self::key_providers::*; +use self::schema::*; +use self::system_config::*; + +use crate::prelude::EntryInitNew; +use kanidm_proto::internal::OperationError; + +pub fn phase_1_schema_attrs() -> Vec { + vec![ + SCHEMA_ATTR_SYNC_CREDENTIAL_PORTAL.clone().into(), + SCHEMA_ATTR_SYNC_YIELD_AUTHORITY.clone().into(), + SCHEMA_ATTR_ACCOUNT_EXPIRE.clone().into(), + SCHEMA_ATTR_ACCOUNT_VALID_FROM.clone().into(), + SCHEMA_ATTR_API_TOKEN_SESSION.clone().into(), + SCHEMA_ATTR_AUTH_SESSION_EXPIRY.clone().into(), + SCHEMA_ATTR_AUTH_PRIVILEGE_EXPIRY.clone().into(), + SCHEMA_ATTR_AUTH_PASSWORD_MINIMUM_LENGTH.clone().into(), + SCHEMA_ATTR_BADLIST_PASSWORD.clone().into(), + SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN.clone().into(), + SCHEMA_ATTR_ATTESTED_PASSKEYS.clone().into(), + SCHEMA_ATTR_DOMAIN_DISPLAY_NAME.clone().into(), + SCHEMA_ATTR_DOMAIN_LDAP_BASEDN.clone().into(), + SCHEMA_ATTR_DOMAIN_NAME.clone().into(), + SCHEMA_ATTR_LDAP_ALLOW_UNIX_PW_BIND.clone().into(), + SCHEMA_ATTR_DOMAIN_SSID.clone().into(), + SCHEMA_ATTR_DOMAIN_TOKEN_KEY.clone().into(), + SCHEMA_ATTR_DOMAIN_UUID.clone().into(), + SCHEMA_ATTR_DYNGROUP_FILTER.clone().into(), + SCHEMA_ATTR_EC_KEY_PRIVATE.clone().into(), + SCHEMA_ATTR_ES256_PRIVATE_KEY_DER.clone().into(), + SCHEMA_ATTR_FERNET_PRIVATE_KEY_STR.clone().into(), + SCHEMA_ATTR_GIDNUMBER.clone().into(), + SCHEMA_ATTR_GRANT_UI_HINT.clone().into(), + SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY.clone().into(), + SCHEMA_ATTR_LOGINSHELL.clone().into(), + SCHEMA_ATTR_NAME_HISTORY.clone().into(), + SCHEMA_ATTR_NSUNIQUEID.clone().into(), + SCHEMA_ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE + .clone() + .into(), + SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP.clone().into(), + SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE.clone().into(), + SCHEMA_ATTR_OAUTH2_PREFER_SHORT_USERNAME.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_BASIC_SECRET.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_IMPLICIT_SCOPES.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_NAME.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_ORIGIN_LANDING.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_TOKEN_KEY.clone().into(), + SCHEMA_ATTR_OAUTH2_SESSION.clone().into(), + SCHEMA_ATTR_PASSKEYS.clone().into(), + SCHEMA_ATTR_PRIMARY_CREDENTIAL.clone().into(), + SCHEMA_ATTR_PRIVATE_COOKIE_KEY.clone().into(), + SCHEMA_ATTR_RADIUS_SECRET.clone().into(), + SCHEMA_ATTR_RS256_PRIVATE_KEY_DER.clone().into(), + SCHEMA_ATTR_SSH_PUBLICKEY.clone().into(), + SCHEMA_ATTR_SYNC_COOKIE.clone().into(), + SCHEMA_ATTR_SYNC_TOKEN_SESSION.clone().into(), + SCHEMA_ATTR_UNIX_PASSWORD.clone().into(), + SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION.clone().into(), + SCHEMA_ATTR_DENIED_NAME.clone().into(), + SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM.clone().into(), + SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST.clone().into(), + // DL4 + SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP_DL4.clone().into(), + SCHEMA_ATTR_OAUTH2_ALLOW_LOCALHOST_REDIRECT_DL4 + .clone() + .into(), + // DL5 + // DL6 + SCHEMA_ATTR_LIMIT_SEARCH_MAX_RESULTS_DL6.clone().into(), + SCHEMA_ATTR_LIMIT_SEARCH_MAX_FILTER_TEST_DL6.clone().into(), + SCHEMA_ATTR_KEY_INTERNAL_DATA_DL6.clone().into(), + SCHEMA_ATTR_KEY_PROVIDER_DL6.clone().into(), + SCHEMA_ATTR_KEY_ACTION_ROTATE_DL6.clone().into(), + SCHEMA_ATTR_KEY_ACTION_REVOKE_DL6.clone().into(), + SCHEMA_ATTR_KEY_ACTION_IMPORT_JWS_ES256_DL6.clone().into(), + // DL7 + SCHEMA_ATTR_PATCH_LEVEL_DL7.clone().into(), + SCHEMA_ATTR_DOMAIN_DEVELOPMENT_TAINT_DL7.clone().into(), + SCHEMA_ATTR_REFERS_DL7.clone().into(), + SCHEMA_ATTR_CERTIFICATE_DL7.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_ORIGIN_DL7.clone().into(), + SCHEMA_ATTR_OAUTH2_STRICT_REDIRECT_URI_DL7.clone().into(), + SCHEMA_ATTR_MAIL_DL7.clone().into(), + SCHEMA_ATTR_LEGALNAME_DL7.clone().into(), + SCHEMA_ATTR_DISPLAYNAME_DL7.clone().into(), + // DL8 + SCHEMA_ATTR_LINKED_GROUP_DL8.clone().into(), + SCHEMA_ATTR_APPLICATION_PASSWORD_DL8.clone().into(), + SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK_DL8.clone().into(), + // DL9 + SCHEMA_ATTR_OAUTH2_DEVICE_FLOW_ENABLE_DL9.clone().into(), + SCHEMA_ATTR_DOMAIN_ALLOW_EASTER_EGGS_DL9.clone().into(), + // DL10 + SCHEMA_ATTR_DENIED_NAME_DL10.clone().into(), + SCHEMA_ATTR_LDAP_MAXIMUM_QUERYABLE_ATTRIBUTES.clone().into(), + ] +} + +pub fn phase_2_schema_classes() -> Vec { + vec![ + SCHEMA_CLASS_DYNGROUP.clone().into(), + SCHEMA_CLASS_ORGPERSON.clone().into(), + SCHEMA_CLASS_POSIXACCOUNT.clone().into(), + SCHEMA_CLASS_POSIXGROUP.clone().into(), + SCHEMA_CLASS_SYSTEM_CONFIG.clone().into(), + // DL4 + SCHEMA_CLASS_OAUTH2_RS_PUBLIC_DL4.clone().into(), + // DL5 + SCHEMA_CLASS_ACCOUNT_DL5.clone().into(), + SCHEMA_CLASS_OAUTH2_RS_BASIC_DL5.clone().into(), + // DL6 + SCHEMA_CLASS_GROUP_DL6.clone().into(), + SCHEMA_CLASS_KEY_PROVIDER_DL6.clone().into(), + SCHEMA_CLASS_KEY_PROVIDER_INTERNAL_DL6.clone().into(), + SCHEMA_CLASS_KEY_OBJECT_DL6.clone().into(), + SCHEMA_CLASS_KEY_OBJECT_JWT_ES256_DL6.clone().into(), + SCHEMA_CLASS_KEY_OBJECT_JWE_A128GCM_DL6.clone().into(), + SCHEMA_CLASS_KEY_OBJECT_INTERNAL_DL6.clone().into(), + // DL7 + SCHEMA_CLASS_SERVICE_ACCOUNT_DL7.clone().into(), + SCHEMA_CLASS_SYNC_ACCOUNT_DL7.clone().into(), + SCHEMA_CLASS_CLIENT_CERTIFICATE_DL7.clone().into(), + // DL8 + SCHEMA_CLASS_ACCOUNT_POLICY_DL8.clone().into(), + SCHEMA_CLASS_APPLICATION_DL8.clone().into(), + SCHEMA_CLASS_PERSON_DL8.clone().into(), + // DL9 + SCHEMA_CLASS_OAUTH2_RS_DL9.clone().into(), + // DL10 + SCHEMA_CLASS_DOMAIN_INFO_DL10.clone().into(), + ] +} + +pub fn phase_3_key_provider() -> Vec { + vec![E_KEY_PROVIDER_INTERNAL_DL6.clone()] +} + +pub fn phase_4_system_entries() -> Vec { + vec![ + E_SYSTEM_INFO_V1.clone(), + E_DOMAIN_INFO_DL6.clone(), + E_SYSTEM_CONFIG_V1.clone(), + ] +} + +pub fn phase_5_builtin_admin_entries() -> Result, OperationError> { + Ok(vec![ + BUILTIN_ACCOUNT_ADMIN.clone().into(), + BUILTIN_ACCOUNT_IDM_ADMIN.clone().into(), + BUILTIN_GROUP_SYSTEM_ADMINS_V1.clone().try_into()?, + BUILTIN_GROUP_IDM_ADMINS_V1.clone().try_into()?, + // We need to push anonymous *after* groups due to entry-managed-by + BUILTIN_ACCOUNT_ANONYMOUS_DL6.clone().into(), + ]) +} + +pub fn phase_6_builtin_non_admin_entries() -> Result, OperationError> { + Ok(vec![ + BUILTIN_GROUP_DOMAIN_ADMINS.clone().try_into()?, + BUILTIN_GROUP_SCHEMA_ADMINS.clone().try_into()?, + BUILTIN_GROUP_ACCESS_CONTROL_ADMINS.clone().try_into()?, + BUILTIN_GROUP_UNIX_ADMINS.clone().try_into()?, + BUILTIN_GROUP_RECYCLE_BIN_ADMINS.clone().try_into()?, + BUILTIN_GROUP_SERVICE_DESK.clone().try_into()?, + BUILTIN_GROUP_OAUTH2_ADMINS.clone().try_into()?, + BUILTIN_GROUP_RADIUS_SERVICE_ADMINS.clone().try_into()?, + BUILTIN_GROUP_ACCOUNT_POLICY_ADMINS.clone().try_into()?, + BUILTIN_GROUP_PEOPLE_ADMINS.clone().try_into()?, + BUILTIN_GROUP_PEOPLE_PII_READ.clone().try_into()?, + BUILTIN_GROUP_PEOPLE_ON_BOARDING.clone().try_into()?, + BUILTIN_GROUP_SERVICE_ACCOUNT_ADMINS.clone().try_into()?, + BUILTIN_GROUP_MAIL_SERVICE_ADMINS_DL8.clone().try_into()?, + IDM_GROUP_ADMINS_V1.clone().try_into()?, + IDM_ALL_PERSONS.clone().try_into()?, + IDM_ALL_ACCOUNTS.clone().try_into()?, + BUILTIN_IDM_RADIUS_SERVERS_V1.clone().try_into()?, + BUILTIN_IDM_MAIL_SERVERS_DL8.clone().try_into()?, + BUILTIN_GROUP_PEOPLE_SELF_NAME_WRITE_DL7 + .clone() + .try_into()?, + IDM_PEOPLE_SELF_MAIL_WRITE_DL7.clone().try_into()?, + BUILTIN_GROUP_CLIENT_CERTIFICATE_ADMINS_DL7 + .clone() + .try_into()?, + BUILTIN_GROUP_APPLICATION_ADMINS_DL8.clone().try_into()?, + // Write deps on read.clone().try_into()?, so write must be added first. + // All members must exist before we write HP + IDM_HIGH_PRIVILEGE_DL8.clone().try_into()?, + // other things + IDM_UI_ENABLE_EXPERIMENTAL_FEATURES.clone().try_into()?, + IDM_ACCOUNT_MAIL_READ.clone().try_into()?, + ]) +} + +pub fn phase_7_builtin_access_control_profiles() -> Vec { + vec![ + // Built in access controls. + IDM_ACP_RECYCLE_BIN_SEARCH_V1.clone().into(), + IDM_ACP_RECYCLE_BIN_REVIVE_V1.clone().into(), + IDM_ACP_SCHEMA_WRITE_ATTRS_V1.clone().into(), + IDM_ACP_SCHEMA_WRITE_CLASSES_V1.clone().into(), + IDM_ACP_ACP_MANAGE_V1.clone().into(), + IDM_ACP_GROUP_ENTRY_MANAGED_BY_MODIFY_V1.clone().into(), + IDM_ACP_GROUP_ENTRY_MANAGER_V1.clone().into(), + IDM_ACP_SYNC_ACCOUNT_MANAGE_V1.clone().into(), + IDM_ACP_RADIUS_SERVERS_V1.clone().into(), + IDM_ACP_RADIUS_SECRET_MANAGE_V1.clone().into(), + IDM_ACP_PEOPLE_SELF_WRITE_MAIL_V1.clone().into(), + IDM_ACP_ACCOUNT_SELF_WRITE_V1.clone().into(), + IDM_ACP_ALL_ACCOUNTS_POSIX_READ_V1.clone().into(), + IDM_ACP_SYSTEM_CONFIG_ACCOUNT_POLICY_MANAGE_V1 + .clone() + .into(), + IDM_ACP_GROUP_UNIX_MANAGE_V1.clone().into(), + IDM_ACP_HP_GROUP_UNIX_MANAGE_V1.clone().into(), + IDM_ACP_GROUP_READ_V1.clone().into(), + IDM_ACP_ACCOUNT_UNIX_EXTEND_V1.clone().into(), + IDM_ACP_PEOPLE_PII_READ_V1.clone().into(), + IDM_ACP_PEOPLE_PII_MANAGE_V1.clone().into(), + IDM_ACP_PEOPLE_READ_V1.clone().into(), + IDM_ACP_PEOPLE_MANAGE_V1.clone().into(), + IDM_ACP_PEOPLE_DELETE_V1.clone().into(), + IDM_ACP_PEOPLE_CREDENTIAL_RESET_V1.clone().into(), + IDM_ACP_HP_PEOPLE_CREDENTIAL_RESET_V1.clone().into(), + IDM_ACP_SERVICE_ACCOUNT_CREATE_V1.clone().into(), + IDM_ACP_SERVICE_ACCOUNT_DELETE_V1.clone().into(), + IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGER_V1.clone().into(), + IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1 + .clone() + .into(), + IDM_ACP_HP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1 + .clone() + .into(), + IDM_ACP_SERVICE_ACCOUNT_MANAGE_V1.clone().into(), + // DL4 + // DL5 + // DL6 + IDM_ACP_PEOPLE_CREATE_DL6.clone().into(), + IDM_ACP_ACCOUNT_MAIL_READ_DL6.clone().into(), + // DL7 + IDM_ACP_SELF_NAME_WRITE_DL7.clone().into(), + IDM_ACP_HP_CLIENT_CERTIFICATE_MANAGER_DL7.clone().into(), + // DL8 + IDM_ACP_SELF_READ_DL8.clone().into(), + IDM_ACP_SELF_WRITE_DL8.clone().into(), + IDM_ACP_APPLICATION_MANAGE_DL8.clone().into(), + IDM_ACP_APPLICATION_ENTRY_MANAGER_DL8.clone().into(), + IDM_ACP_MAIL_SERVERS_DL8.clone().into(), + IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE_DL8.clone().into(), + // DL9 + IDM_ACP_OAUTH2_MANAGE_DL9.clone().into(), + IDM_ACP_GROUP_MANAGE_DL9.clone().into(), + IDM_ACP_DOMAIN_ADMIN_DL9.clone().into(), + ] +} diff --git a/server/lib/src/constants/schema.rs b/server/lib/src/migration_data/dl10/schema.rs similarity index 99% rename from server/lib/src/constants/schema.rs rename to server/lib/src/migration_data/dl10/schema.rs index 93abb84eb..0cfc290cb 100644 --- a/server/lib/src/constants/schema.rs +++ b/server/lib/src/migration_data/dl10/schema.rs @@ -1,7 +1,4 @@ -//! Core Constants -//! -//! Schema uuids start at `00000000-0000-0000-0000-ffff00000000` -//! +//! Schema Entries use crate::constants::entries::{Attribute, EntryClass}; use crate::constants::uuids::*; use crate::schema::{SchemaAttribute, SchemaClass}; diff --git a/server/lib/src/constants/system_config.rs b/server/lib/src/migration_data/dl10/system_config.rs similarity index 97% rename from server/lib/src/constants/system_config.rs rename to server/lib/src/migration_data/dl10/system_config.rs index 253d772e0..107bd8bbe 100644 --- a/server/lib/src/constants/system_config.rs +++ b/server/lib/src/migration_data/dl10/system_config.rs @@ -8,6 +8,31 @@ use crate::value::Value; // This is separated because the password badlist section may become very long lazy_static! { + pub static ref E_SYSTEM_INFO_V1: EntryInitNew = entry_init!( + (Attribute::Class, EntryClass::Object.to_value()), + (Attribute::Class, EntryClass::SystemInfo.to_value()), + (Attribute::Class, EntryClass::System.to_value()), + (Attribute::Uuid, Value::Uuid(UUID_SYSTEM_INFO)), + ( + Attribute::Description, + Value::new_utf8s("System (local) info and metadata object.") + ), + (Attribute::Version, Value::Uint32(20)) + ); + pub static ref E_DOMAIN_INFO_DL6: EntryInitNew = entry_init!( + (Attribute::Class, EntryClass::Object.to_value()), + (Attribute::Class, EntryClass::DomainInfo.to_value()), + (Attribute::Class, EntryClass::System.to_value()), + (Attribute::Class, EntryClass::KeyObject.to_value()), + (Attribute::Class, EntryClass::KeyObjectJwtEs256.to_value()), + (Attribute::Class, EntryClass::KeyObjectJweA128GCM.to_value()), + (Attribute::Name, Value::new_iname("domain_local")), + (Attribute::Uuid, Value::Uuid(UUID_DOMAIN_INFO)), + ( + Attribute::Description, + Value::new_utf8s("This local domain's info and metadata object.") + ) + ); pub static ref E_SYSTEM_CONFIG_V1: EntryInitNew = entry_init!( (Attribute::Class, EntryClass::Object.to_value()), (Attribute::Class, EntryClass::SystemConfig.to_value()), diff --git a/server/lib/src/migration_data/dl8/access.rs b/server/lib/src/migration_data/dl8/access.rs new file mode 100644 index 000000000..7c0487745 --- /dev/null +++ b/server/lib/src/migration_data/dl8/access.rs @@ -0,0 +1,2637 @@ +#![allow(clippy::expect_used)] +//! Constant Entries for the IDM + +use crate::constants::uuids::*; +use crate::entry::EntryInitNew; +use crate::prelude::*; +use crate::value::Value; +use kanidm_proto::internal::Filter as ProtoFilter; + +lazy_static! { + /// either recycled or tombstone + pub static ref FILTER_RECYCLED_OR_TOMBSTONE: ProtoFilter = ProtoFilter::Or(vec![ + match_class_filter!(EntryClass::Recycled), + match_class_filter!(EntryClass::Tombstone), + ]); + + /// not either recycled or tombstone + pub static ref FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED: ProtoFilter = + ProtoFilter::AndNot(Box::new(FILTER_RECYCLED_OR_TOMBSTONE.clone())); + + /// members of 000000001000 / idm_high_privilege + pub static ref FILTER_HP: ProtoFilter = ProtoFilter::Eq( + Attribute::MemberOf.to_string(), + UUID_IDM_HIGH_PRIVILEGE.to_string(), + ); + + /// OR ( HP, Recycled, Tombstone) + pub static ref FILTER_HP_OR_RECYCLED_OR_TOMBSTONE: ProtoFilter = ProtoFilter::Or(vec![ + FILTER_HP.clone(), + match_class_filter!(EntryClass::Recycled), + match_class_filter!(EntryClass::Tombstone), + ]); + + pub static ref FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE: ProtoFilter = + ProtoFilter::AndNot(Box::new(FILTER_HP_OR_RECYCLED_OR_TOMBSTONE.clone())); + + pub static ref DEFAULT_TARGET_SCOPE: ProtoFilter = ProtoFilter::And(Vec::with_capacity(0)); + +} + +#[derive(Clone, Debug, Default)] +/// Who will receive the privileges of this ACP. +pub enum BuiltinAcpReceiver { + #[default] + None, + /// This functions as an "OR" condition, that membership of *at least one* of these UUIDs + /// is sufficient for you to receive the access control. + Group(Vec), + EntryManager, +} + +#[derive(Clone, Debug, Default)] +/// Objects that are affected by the rules of this ACP. +pub enum BuiltinAcpTarget { + #[default] + None, + // Self, + Filter(ProtoFilter), + // MemberOf ( Uuid ), +} + +#[derive(Clone, Debug, Default)] +/// Built-in Access Control Profile definitions +pub struct BuiltinAcp { + classes: Vec, + pub name: &'static str, + uuid: Uuid, + description: &'static str, + receiver: BuiltinAcpReceiver, + target: BuiltinAcpTarget, + search_attrs: Vec, + modify_present_attrs: Vec, + modify_removed_attrs: Vec, + modify_classes: Vec, + create_classes: Vec, + create_attrs: Vec, +} + +impl From for EntryInitNew { + #[allow(clippy::panic)] + fn from(value: BuiltinAcp) -> Self { + let mut entry = EntryInitNew::default(); + + #[allow(clippy::panic)] + if value.name.is_empty() { + panic!("Builtin ACP has no name! {:?}", value); + } + #[allow(clippy::panic)] + if value.classes.is_empty() { + panic!("Builtin ACP has no classes! {:?}", value); + } + + value.classes.iter().for_each(|class| { + entry.add_ava(Attribute::Class, class.to_value()); + }); + + 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::Description, + [Value::new_utf8s(value.description)], + ); + + match &value.receiver { + #[allow(clippy::panic)] + BuiltinAcpReceiver::None => { + panic!("Builtin ACP has no receiver! {:?}", &value); + } + BuiltinAcpReceiver::Group(list) => { + entry.add_ava( + Attribute::Class, + EntryClass::AccessControlReceiverGroup.to_value(), + ); + for group in list { + entry.set_ava(Attribute::AcpReceiverGroup, [Value::Refer(*group)]); + } + } + BuiltinAcpReceiver::EntryManager => { + entry.add_ava( + Attribute::Class, + EntryClass::AccessControlReceiverEntryManager.to_value(), + ); + } + }; + + match &value.target { + #[allow(clippy::panic)] + BuiltinAcpTarget::None => { + panic!("Builtin ACP has no target! {:?}", &value); + } + BuiltinAcpTarget::Filter(proto_filter) => { + entry.add_ava( + Attribute::Class, + EntryClass::AccessControlTargetScope.to_value(), + ); + entry.set_ava( + Attribute::AcpTargetScope, + [Value::JsonFilt(proto_filter.clone())], + ); + } + } + + entry.set_ava( + Attribute::AcpSearchAttr, + value + .search_attrs + .into_iter() + .map(Value::from) + .collect::>(), + ); + value.modify_present_attrs.into_iter().for_each(|attr| { + entry.add_ava(Attribute::AcpModifyPresentAttr, Value::from(attr)); + }); + value.modify_removed_attrs.into_iter().for_each(|attr| { + entry.add_ava(Attribute::AcpModifyRemovedAttr, Value::from(attr)); + }); + value.modify_classes.into_iter().for_each(|class| { + entry.add_ava(Attribute::AcpModifyClass, Value::from(class)); + }); + value.create_classes.into_iter().for_each(|class| { + entry.add_ava(Attribute::AcpCreateClass, Value::from(class)); + }); + value.create_attrs.into_iter().for_each(|attr| { + entry.add_ava(Attribute::AcpCreateAttr, Value::from(attr)); + }); + entry + } +} + +lazy_static! { + pub static ref IDM_ACP_RECYCLE_BIN_SEARCH_V1: BuiltinAcp = BuiltinAcp { + uuid: UUID_IDM_ACP_RECYCLE_BIN_SEARCH_V1, + name: "idm_acp_recycle_bin_search", + description: "Builtin IDM recycle bin search permission.", + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_RECYCLE_BIN_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::Eq( + Attribute::Class.to_string(), + ATTR_RECYCLED.to_string() + )), + + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::LastModifiedCid, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_RECYCLE_BIN_REVIVE_V1: BuiltinAcp = BuiltinAcp { + uuid: UUID_IDM_ACP_RECYCLE_BIN_REVIVE_V1, + name: "idm_acp_recycle_bin_revive", + description: "Builtin IDM recycle bin revive permission.", + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_RECYCLE_BIN_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::Eq( + Attribute::Class.to_string(), + ATTR_RECYCLED.to_string() + )), + modify_removed_attrs: vec![Attribute::Class], + modify_classes: vec![EntryClass::Recycled], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SCHEMA_WRITE_ATTRS_V1: BuiltinAcp = BuiltinAcp{ + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_schema_write_attrs", + uuid: UUID_IDM_ACP_SCHEMA_WRITE_ATTRS_V1, + description: "Builtin IDM Control for management of schema attributes.", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_SCHEMA_ADMINS] ), + // has a class, and isn't recycled/tombstoned + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + ProtoFilter::Eq(EntryClass::Class.to_string(),EntryClass::AttributeType.to_string()), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::Index, + Attribute::Unique, + Attribute::MultiValue, + Attribute::AttributeName, + Attribute::Syntax, + Attribute::Uuid, + ], + modify_removed_attrs: vec![ + Attribute::Description, + Attribute::Index, + Attribute::Unique, + Attribute::MultiValue, + Attribute::Syntax, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::Index, + Attribute::Unique, + Attribute::MultiValue, + Attribute::Syntax, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::Index, + Attribute::Unique, + Attribute::MultiValue, + Attribute::AttributeName, + Attribute::Syntax, + Attribute::Uuid, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::AttributeType, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SCHEMA_WRITE_CLASSES_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_schema_write_classes", + uuid: UUID_IDM_ACP_SCHEMA_WRITE_CLASSES_V1, + description: "Builtin IDM Control for management of schema classes.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_SCHEMA_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + EntryClass::Class.to_string(), + EntryClass::ClassType.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::ClassName, + Attribute::Description, + Attribute::SystemMay, + Attribute::May, + Attribute::SystemMust, + Attribute::Must, + Attribute::Uuid, + ], + modify_removed_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::May, + Attribute::Must, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::May, + Attribute::Must, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::ClassName, + Attribute::Description, + Attribute::May, + Attribute::Must, + Attribute::Uuid, + ], + create_classes: vec![EntryClass::Object, EntryClass::ClassType,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_ACP_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_acp_manage", + uuid: UUID_IDM_ACP_ACP_MANAGE_V1, + description: "Builtin IDM Control for access profiles management.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ACCESS_CONTROL_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + EntryClass::Class.to_string(), + EntryClass::AccessControlProfile.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Description, + Attribute::AcpEnable, + Attribute::AcpReceiverGroup, + Attribute::AcpTargetScope, + Attribute::AcpSearchAttr, + Attribute::AcpModifyRemovedAttr, + Attribute::AcpModifyPresentAttr, + Attribute::AcpModifyClass, + Attribute::AcpCreateClass, + Attribute::AcpCreateAttr, + ], + modify_removed_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Description, + Attribute::AcpEnable, + Attribute::AcpReceiverGroup, + Attribute::AcpTargetScope, + Attribute::AcpSearchAttr, + Attribute::AcpModifyRemovedAttr, + Attribute::AcpModifyPresentAttr, + Attribute::AcpModifyClass, + Attribute::AcpCreateClass, + Attribute::AcpCreateAttr, + ], + modify_present_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Description, + Attribute::AcpEnable, + Attribute::AcpReceiverGroup, + Attribute::AcpTargetScope, + Attribute::AcpSearchAttr, + Attribute::AcpModifyRemovedAttr, + Attribute::AcpModifyPresentAttr, + Attribute::AcpModifyClass, + Attribute::AcpCreateClass, + Attribute::AcpCreateAttr, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Description, + Attribute::AcpEnable, + Attribute::AcpReceiverGroup, + Attribute::AcpTargetScope, + Attribute::AcpSearchAttr, + Attribute::AcpModifyRemovedAttr, + Attribute::AcpModifyPresentAttr, + Attribute::AcpModifyClass, + Attribute::AcpCreateClass, + Attribute::AcpCreateAttr, + ], + modify_classes: vec![ + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + EntryClass::AccessControlModify, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + ], + create_classes: vec![ + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + EntryClass::AccessControlModify, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + ], + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_READ_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_read", + uuid: UUID_IDM_ACP_GROUP_READ, + description: + "Builtin IDM Control for allowing all groups to be read by access control admins", + receiver: BuiltinAcpReceiver::Group(vec![ + UUID_IDM_ACCESS_CONTROL_ADMINS, + // UUID_IDM_SERVICE_DESK, + // UUID_IDM_PEOPLE_ADMINS, + ]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::DynMember, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::Description, + Attribute::Member, + Attribute::EntryManagedBy, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_ENTRY_MANAGED_BY_MODIFY_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_entry_managed_by_modify", + uuid: UUID_IDM_ACP_GROUP_ENTRY_MANAGED_BY_MODIFY, + description: "Builtin IDM Control for allowing entry_managed_by to be set on group entries", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ACCESS_CONTROL_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::Uuid, + Attribute::EntryManagedBy, + ], + modify_removed_attrs: vec![Attribute::EntryManagedBy], + modify_present_attrs: vec![Attribute::EntryManagedBy], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE_DL6: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_account_policy_manage", + uuid: UUID_IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE, + description: "Builtin IDM Control for management of account policy on groups", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ACCOUNT_POLICY_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::AuthSessionExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::PrivilegeExpiry, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + ], + modify_removed_attrs: vec![ + Attribute::Class, + Attribute::AuthSessionExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::PrivilegeExpiry, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + ], + modify_present_attrs: vec![ + Attribute::Class, + Attribute::AuthSessionExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::PrivilegeExpiry, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + ], + modify_classes: vec![EntryClass::AccountPolicy,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE_DL8: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_account_policy_manage", + uuid: UUID_IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE, + description: "Builtin IDM Control for management of account policy on groups", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ACCOUNT_POLICY_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::AuthSessionExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::PrivilegeExpiry, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + Attribute::AllowPrimaryCredFallback, + ], + modify_removed_attrs: vec![ + Attribute::Class, + Attribute::AuthSessionExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::PrivilegeExpiry, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + Attribute::AllowPrimaryCredFallback, + ], + modify_present_attrs: vec![ + Attribute::Class, + Attribute::AuthSessionExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::PrivilegeExpiry, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + Attribute::AllowPrimaryCredFallback, + ], + modify_classes: vec![EntryClass::AccountPolicy,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_OAUTH2_MANAGE_DL4: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_hp_oauth2_manage_priv", + uuid: UUID_IDM_ACP_OAUTH2_MANAGE_V1, + description: "Builtin IDM Control for managing oauth2 resource server integrations.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_OAUTH2_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::OAuth2ResourceServer), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + modify_removed_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::OAuth2ResourceServer, + EntryClass::OAuth2ResourceServerBasic, + EntryClass::OAuth2ResourceServerPublic, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_OAUTH2_MANAGE_DL5: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_hp_oauth2_manage_priv", + uuid: UUID_IDM_ACP_OAUTH2_MANAGE_V1, + description: "Builtin IDM Control for managing oauth2 resource server integrations.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_OAUTH2_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::OAuth2ResourceServer), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::Spn, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + modify_removed_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::Name, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Account, + EntryClass::OAuth2ResourceServer, + EntryClass::OAuth2ResourceServerBasic, + EntryClass::OAuth2ResourceServerPublic, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_OAUTH2_MANAGE_DL7: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_hp_oauth2_manage_priv", + uuid: UUID_IDM_ACP_OAUTH2_MANAGE_V1, + description: "Builtin IDM Control for managing oauth2 resource server integrations.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_OAUTH2_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::OAuth2ResourceServer), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::Spn, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + ], + modify_removed_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::Name, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Account, + EntryClass::OAuth2ResourceServer, + EntryClass::OAuth2ResourceServerBasic, + EntryClass::OAuth2ResourceServerPublic, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_OAUTH2_MANAGE_DL9: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_oauth2_manage", + uuid: UUID_IDM_ACP_OAUTH2_MANAGE_V1, + description: "Builtin IDM Control for managing OAuth2 resource server integrations.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_OAUTH2_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::OAuth2ResourceServer), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::Spn, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + Attribute::OAuth2DeviceFlowEnable, + ], + modify_removed_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + Attribute::OAuth2DeviceFlowEnable, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + Attribute::OAuth2DeviceFlowEnable, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::Name, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + Attribute::OAuth2DeviceFlowEnable, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Account, + EntryClass::OAuth2ResourceServer, + EntryClass::OAuth2ResourceServerBasic, + EntryClass::OAuth2ResourceServerPublic, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_DOMAIN_ADMIN_DL6: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_domain_admin", + uuid: UUID_IDM_ACP_DOMAIN_ADMIN_V1, + description: "Builtin IDM Control for granting domain info administration locally", + receiver: BuiltinAcpReceiver::Group(vec![UUID_DOMAIN_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + Attribute::Uuid.to_string(), + STR_UUID_DOMAIN_INFO.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::DomainDisplayName, + Attribute::DomainName, + Attribute::DomainLdapBasedn, + Attribute::DomainSsid, + Attribute::DomainUuid, + // Grants read access to the key object. + // But this means we have to specify every type of key object? + // Future william problem ... + Attribute::KeyInternalData, + Attribute::LdapAllowUnixPwBind, + Attribute::Version, + ], + modify_removed_attrs: vec![ + Attribute::DomainDisplayName, + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::LdapAllowUnixPwBind, + Attribute::KeyActionRevoke, + Attribute::KeyActionRotate, + ], + modify_present_attrs: vec![ + Attribute::DomainDisplayName, + Attribute::DomainLdapBasedn, + Attribute::DomainSsid, + Attribute::LdapAllowUnixPwBind, + Attribute::KeyActionRevoke, + Attribute::KeyActionRotate, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_DOMAIN_ADMIN_DL8: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_domain_admin", + uuid: UUID_IDM_ACP_DOMAIN_ADMIN_V1, + description: "Builtin IDM Control for granting domain info administration locally", + receiver: BuiltinAcpReceiver::Group(vec![UUID_DOMAIN_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + Attribute::Uuid.to_string(), + STR_UUID_DOMAIN_INFO.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::DomainDisplayName, + Attribute::DomainName, + Attribute::DomainLdapBasedn, + Attribute::DomainSsid, + Attribute::DomainUuid, + Attribute::KeyInternalData, + Attribute::LdapAllowUnixPwBind, + Attribute::Version, + Attribute::Image, + ], + modify_removed_attrs: vec![ + Attribute::DomainDisplayName, + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::LdapAllowUnixPwBind, + Attribute::KeyActionRevoke, + Attribute::KeyActionRotate, + Attribute::Image, + ], + modify_present_attrs: vec![ + Attribute::DomainDisplayName, + Attribute::DomainLdapBasedn, + Attribute::DomainSsid, + Attribute::LdapAllowUnixPwBind, + Attribute::KeyActionRevoke, + Attribute::KeyActionRotate, + Attribute::Image, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_DOMAIN_ADMIN_DL9: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_domain_admin", + uuid: UUID_IDM_ACP_DOMAIN_ADMIN_V1, + description: "Builtin IDM Control for granting domain info administration locally", + receiver: BuiltinAcpReceiver::Group(vec![UUID_DOMAIN_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + Attribute::Uuid.to_string(), + STR_UUID_DOMAIN_INFO.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::DomainAllowEasterEggs, + Attribute::DomainDisplayName, + Attribute::DomainName, + Attribute::DomainLdapBasedn, + Attribute::DomainSsid, + Attribute::DomainUuid, + Attribute::KeyInternalData, + Attribute::LdapAllowUnixPwBind, + Attribute::Version, + Attribute::Image, + ], + modify_removed_attrs: vec![ + Attribute::DomainDisplayName, + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::DomainAllowEasterEggs, + Attribute::LdapAllowUnixPwBind, + Attribute::KeyActionRevoke, + Attribute::KeyActionRotate, + Attribute::Image, + ], + modify_present_attrs: vec![ + Attribute::DomainDisplayName, + Attribute::DomainLdapBasedn, + Attribute::DomainSsid, + Attribute::DomainAllowEasterEggs, + Attribute::LdapAllowUnixPwBind, + Attribute::KeyActionRevoke, + Attribute::KeyActionRotate, + Attribute::Image, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SYNC_ACCOUNT_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch, + ], + name: "idm_acp_sync_account_manage", + uuid: UUID_IDM_ACP_SYNC_ACCOUNT_MANAGE_V1, + description: "Builtin IDM Control for managing IDM synchronisation accounts / connections", + receiver: BuiltinAcpReceiver::Group(vec![UUID_DOMAIN_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + Attribute::Class.to_string(), + EntryClass::SyncAccount.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Name, + Attribute::Description, + Attribute::JwsEs256PrivateKey, + Attribute::SyncTokenSession, + Attribute::SyncCredentialPortal, + Attribute::SyncYieldAuthority, + Attribute::SyncCookie, + ], + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::JwsEs256PrivateKey, + Attribute::SyncTokenSession, + Attribute::SyncCredentialPortal, + Attribute::SyncCookie, + Attribute::SyncYieldAuthority, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::SyncTokenSession, + Attribute::SyncCredentialPortal, + Attribute::SyncYieldAuthority, + ], + create_attrs: vec![Attribute::Class, Attribute::Name, Attribute::Description,], + create_classes: vec![EntryClass::Object, EntryClass::SyncAccount,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_ENTRY_MANAGER_V1: BuiltinAcp = BuiltinAcp{ + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_entry_manager", + uuid: UUID_IDM_ACP_GROUP_ENTRY_MANAGER_V1, + description: "Builtin IDM Control for allowing EntryManager to read and modify groups", + receiver: BuiltinAcpReceiver::EntryManager, + // Any group + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::Uuid, + Attribute::Description, + Attribute::Member, + Attribute::DynMember, + Attribute::EntryManagedBy, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::Member, + ], + modify_removed_attrs: vec![ + Attribute::Description, + Attribute::Member, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_RADIUS_SERVERS_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + name: "idm_acp_radius_servers", + uuid: UUID_IDM_ACP_RADIUS_SERVERS_V1, + description: + "Builtin IDM Control for RADIUS servers to read credentials and other needed details.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_RADIUS_SERVERS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Pres(EntryClass::Class.to_string()), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::Uuid, + Attribute::RadiusSecret, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_RADIUS_SECRET_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch, + ], + name: "idm_acp_radius_secret_manage", + uuid: UUID_IDM_ACP_RADIUS_SECRET_MANAGE_V1, + description: "Builtin IDM Control allowing reads and writes to user radius secrets.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_RADIUS_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Account), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![Attribute::RadiusSecret], + modify_present_attrs: vec![Attribute::RadiusSecret], + modify_removed_attrs: vec![Attribute::RadiusSecret], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_MAIL_SERVERS_DL8: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + name: "idm_acp_mail_servers", + uuid: UUID_IDM_ACP_MAIL_SERVERS, + description: + "Builtin IDM Control for MAIL servers to read email addresses and other needed attributes.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_MAIL_SERVERS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Or(vec![ + match_class_filter!(EntryClass::Account), + match_class_filter!(EntryClass::Group), + ]), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::Uuid, + Attribute::DisplayName, + Attribute::Mail, + Attribute::Member, + Attribute::DynMember, + Attribute::MemberOf, + Attribute::GidNumber, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_PEOPLE_SELF_WRITE_MAIL_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + name: "idm_acp_people_self_write_mail", + uuid: UUID_IDM_ACP_PEOPLE_SELF_WRITE_MAIL, + description: "Builtin IDM Control for self write of mail for people accounts.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_PEOPLE_SELF_MAIL_WRITE]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person).clone(), + match_class_filter!(EntryClass::Account).clone(), + ProtoFilter::SelfUuid, + ])), + modify_removed_attrs: vec![Attribute::Mail], + modify_present_attrs: vec![Attribute::Mail], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SELF_READ_V1: BuiltinAcp = BuiltinAcp { + name: "idm_acp_self_read", + uuid: UUID_IDM_ACP_SELF_READ, + description: + "Builtin IDM Control for self read - required for whoami and many other functions", + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ALL_ACCOUNTS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::SelfUuid), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::DisplayName, + Attribute::LegalName, + Attribute::Class, + Attribute::MemberOf, + Attribute::Mail, + Attribute::RadiusSecret, + Attribute::GidNumber, + Attribute::LoginShell, + Attribute::Uuid, + Attribute::SyncParentUuid, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::PrimaryCredential, + Attribute::UserAuthTokenSession, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SELF_READ_DL8: BuiltinAcp = BuiltinAcp { + name: "idm_acp_self_read", + uuid: UUID_IDM_ACP_SELF_READ, + description: + "Builtin IDM Control for self read - required for whoami and many other functions", + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ALL_ACCOUNTS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::SelfUuid), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::DisplayName, + Attribute::LegalName, + Attribute::Class, + Attribute::MemberOf, + Attribute::Mail, + Attribute::RadiusSecret, + Attribute::GidNumber, + Attribute::LoginShell, + Attribute::Uuid, + Attribute::SyncParentUuid, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::PrimaryCredential, + Attribute::UserAuthTokenSession, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::ApplicationPassword, + Attribute::SshPublicKey, + Attribute::UnixPassword, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SELF_WRITE_V1: BuiltinAcp = BuiltinAcp{ + name: "idm_acp_self_write", + uuid: UUID_IDM_ACP_SELF_WRITE_V1, + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + description: "Builtin IDM Control for self write - required for people to update their own identities and credentials in line with best practices.", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_ALL_PERSONS] ), + target: BuiltinAcpTarget::Filter(ProtoFilter::SelfUuid), + modify_removed_attrs: vec![ + Attribute::DisplayName, + Attribute::LegalName, + Attribute::RadiusSecret, + Attribute::PrimaryCredential, + Attribute::SshPublicKey, + Attribute::UnixPassword, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::UserAuthTokenSession, + Attribute::ApplicationPassword, + ], + modify_present_attrs: vec![ + Attribute::DisplayName, + Attribute::LegalName, + Attribute::RadiusSecret, + Attribute::PrimaryCredential, + Attribute::SshPublicKey, + Attribute::UnixPassword, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::ApplicationPassword, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SELF_WRITE_DL7: BuiltinAcp = BuiltinAcp{ + name: "idm_acp_self_write", + uuid: UUID_IDM_ACP_SELF_WRITE_V1, + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + description: "Builtin IDM Control for self write - required for people to update their own credentials in line with best practices.", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_ALL_PERSONS] ), + target: BuiltinAcpTarget::Filter(ProtoFilter::SelfUuid), + modify_removed_attrs: vec![ + Attribute::RadiusSecret, + Attribute::PrimaryCredential, + Attribute::SshPublicKey, + Attribute::UnixPassword, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::UserAuthTokenSession, + ], + modify_present_attrs: vec![ + Attribute::RadiusSecret, + Attribute::PrimaryCredential, + Attribute::SshPublicKey, + Attribute::UnixPassword, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SELF_WRITE_DL8: BuiltinAcp = BuiltinAcp{ + name: "idm_acp_self_write", + uuid: UUID_IDM_ACP_SELF_WRITE_V1, + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + description: "Builtin IDM Control for self write - required for people to update their own credentials in line with best practices.", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_ALL_PERSONS] ), + target: BuiltinAcpTarget::Filter(ProtoFilter::SelfUuid), + modify_removed_attrs: vec![ + Attribute::RadiusSecret, + Attribute::PrimaryCredential, + Attribute::SshPublicKey, + Attribute::UnixPassword, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::UserAuthTokenSession, + Attribute::ApplicationPassword, + ], + modify_present_attrs: vec![ + Attribute::RadiusSecret, + Attribute::PrimaryCredential, + Attribute::SshPublicKey, + Attribute::UnixPassword, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::ApplicationPassword, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SELF_NAME_WRITE_V1: BuiltinAcp = BuiltinAcp{ + name: "idm_acp_self_name_write", + uuid: UUID_IDM_ACP_SELF_NAME_WRITE_V1, + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + description: "Builtin IDM Control for self write of name - required for people to update their own identities in line with best practices.", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_ALL_PERSONS] ), + target: BuiltinAcpTarget::Filter(ProtoFilter::SelfUuid), + modify_removed_attrs: vec![ + Attribute::Name, + ], + modify_present_attrs: vec![ + Attribute::Name, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SELF_NAME_WRITE_DL7: BuiltinAcp = BuiltinAcp{ + name: "idm_acp_self_name_write", + uuid: UUID_IDM_ACP_SELF_NAME_WRITE_V1, + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + description: "Builtin IDM Control for self write of name - required for people to update their own identities in line with best practices.", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_PEOPLE_SELF_NAME_WRITE] ), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::SelfUuid, + match_class_filter!(EntryClass::Person).clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::DisplayName, + Attribute::LegalName, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::DisplayName, + Attribute::LegalName, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_ACCOUNT_SELF_WRITE_V1: BuiltinAcp = BuiltinAcp { + name: "idm_acp_account_self_write", + uuid: UUID_IDM_ACP_ACCOUNT_SELF_WRITE_V1, + description: "Builtin IDM Control for self write - required for accounts to update their own session state.", + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify + ], + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_ALL_ACCOUNTS] ), + target: BuiltinAcpTarget::Filter(ProtoFilter::SelfUuid), + modify_removed_attrs: vec![ + Attribute::UserAuthTokenSession + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_ALL_ACCOUNTS_POSIX_READ_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + name: "idm_acp_all_accounts_posix_read", + uuid: UUID_IDM_ACP_ALL_ACCOUNTS_POSIX_READ_V1, + description: + "Builtin IDM Control for reading minimal posix attrs - applies anonymous and all authenticated accounts.", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_ALL_ACCOUNTS] ), + target: BuiltinAcpTarget::Filter( ProtoFilter::And( + vec![ + ProtoFilter::Or(vec![ + match_class_filter!(EntryClass::Account), + match_class_filter!(EntryClass::Group), + ]), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ] + )), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::DisplayName, + Attribute::Class, + Attribute::MemberOf, + Attribute::Member, + Attribute::DynMember, + Attribute::Uuid, + Attribute::GidNumber, + Attribute::LoginShell, + Attribute::SshPublicKey, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_ACCOUNT_MAIL_READ_DL6: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch + ], + name: "idm_acp_account_mail_read", + uuid: UUID_IDM_ACP_ACCOUNT_MAIL_READ_V1, + description: "Builtin IDM Control for reading account and group mail attributes.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ACCOUNT_MAIL_READ]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Or(vec![ + match_class_filter!(EntryClass::Account), + match_class_filter!(EntryClass::Group), + ]), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![Attribute::Mail], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SYSTEM_CONFIG_ACCOUNT_POLICY_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_system_config_account_policy_manage", + uuid: UUID_IDM_ACP_SYSTEM_CONFIG_ACCOUNT_POLICY_MANAGE_V1, + description: "Builtin IDM Control for granting system configuration of account policy", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ACCOUNT_POLICY_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + Attribute::Uuid.to_string(), + STR_UUID_SYSTEM_CONFIG.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Description, + Attribute::BadlistPassword, + Attribute::DeniedName, + Attribute::AuthSessionExpiry, + Attribute::PrivilegeExpiry, + Attribute::Version, + ], + modify_removed_attrs: vec![ + Attribute::BadlistPassword, + Attribute::DeniedName, + Attribute::AuthSessionExpiry, + Attribute::PrivilegeExpiry, + ], + modify_present_attrs: vec![ + Attribute::BadlistPassword, + Attribute::DeniedName, + Attribute::AuthSessionExpiry, + Attribute::PrivilegeExpiry, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_HP_GROUP_UNIX_MANAGE_V1: BuiltinAcp = BuiltinAcp{ + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_hp_group_unix_manage", + uuid: UUID_IDM_ACP_HP_GROUP_UNIX_MANAGE_V1, + description: "Builtin IDM Control for managing and extending high privilege groups with unix attributes", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_UNIX_ADMINS] ), + // HP group, not Recycled/Tombstone + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_HP.clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::DynMember, + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::Description, + Attribute::Member, + Attribute::GidNumber, + ], + modify_removed_attrs: vec![ + Attribute::GidNumber, + ], + modify_present_attrs: vec![ + Attribute::Class, + Attribute::GidNumber, + ], + modify_classes: vec![ + EntryClass::PosixGroup, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_MANAGE_DL6: BuiltinAcp = BuiltinAcp{ + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_manage", + uuid: UUID_IDM_ACP_GROUP_MANAGE_V1, + description: "Builtin IDM Control for creating and deleting groups in the directory", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_GROUP_ADMINS] ), + // group which is not in HP, Recycled, Tombstone + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::Uuid, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + Attribute::DynMember, + Attribute::EntryManagedBy, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + Attribute::EntryManagedBy, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Group, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + ], + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_MANAGE_DL9: BuiltinAcp = BuiltinAcp{ + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_manage", + uuid: UUID_IDM_ACP_GROUP_MANAGE_V1, + description: "Builtin IDM Control for creating and deleting groups in the directory", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_GROUP_ADMINS] ), + // group which is not in HP, Recycled, Tombstone + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::Uuid, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + Attribute::DynMember, + Attribute::EntryManagedBy, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + Attribute::EntryManagedBy, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Group, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + Attribute::EntryManagedBy, + ], + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + Attribute::EntryManagedBy, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_UNIX_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_unix_manage", + uuid: UUID_IDM_ACP_GROUP_UNIX_MANAGE_V1, + description: "Builtin IDM Control for managing unix groups", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_UNIX_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + search_attrs: vec![ + Attribute::DynMember, + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::Description, + Attribute::Member, + Attribute::GidNumber, + ], + modify_removed_attrs: vec![Attribute::GidNumber,], + modify_present_attrs: vec![Attribute::Class, Attribute::GidNumber,], + modify_classes: vec![EntryClass::PosixGroup,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_ACCOUNT_UNIX_EXTEND_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_account_unix_extend", + uuid: UUID_IDM_ACP_ACCOUNT_UNIX_EXTEND_V1, + description: "Builtin IDM Control for managing and extending unix accounts", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_UNIX_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Account), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::Description, + Attribute::GidNumber, + Attribute::LoginShell, + Attribute::UnixPassword, + Attribute::SshPublicKey, + ], + modify_removed_attrs: vec![ + Attribute::GidNumber, + Attribute::LoginShell, + Attribute::UnixPassword, + Attribute::SshPublicKey, + ], + modify_present_attrs: vec![ + Attribute::Class, + Attribute::GidNumber, + Attribute::LoginShell, + Attribute::UnixPassword, + Attribute::SshPublicKey, + ], + modify_classes: vec![EntryClass::PosixAccount,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_PEOPLE_PII_READ_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + name: "idm_acp_people_pii_read", + uuid: UUID_IDM_ACP_PEOPLE_PII_READ_V1, + description: "Builtin IDM Control for reading personal and sensitive data.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_PEOPLE_ADMINS, UUID_IDM_PEOPLE_PII_READ]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person).clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::DisplayName, + Attribute::LegalName, + Attribute::Mail, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_PEOPLE_PII_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify + ], + name: "idm_acp_people_pii_manage", + uuid: UUID_IDM_ACP_PEOPLE_PII_MANAGE_V1, + description: "Builtin IDM Control for modifying peoples personal and sensitive data", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_PEOPLE_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::DisplayName, + Attribute::LegalName, + Attribute::Mail, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::DisplayName, + Attribute::LegalName, + Attribute::Mail, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_PEOPLE_CREATE_DL6: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + ], + name: "idm_acp_people_create", + uuid: UUID_IDM_ACP_PEOPLE_CREATE_V1, + description: "Builtin IDM Control for creating new persons.", + receiver: BuiltinAcpReceiver::Group(vec![ + UUID_IDM_PEOPLE_ADMINS, + UUID_IDM_PEOPLE_ON_BOARDING + ]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person).clone(), + match_class_filter!(EntryClass::Account).clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + create_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Name, + Attribute::DisplayName, + Attribute::Mail, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + ], + create_classes: vec![EntryClass::Object, EntryClass::Account, EntryClass::Person,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_PEOPLE_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + name: "idm_acp_people_manage", + uuid: UUID_IDM_ACP_PEOPLE_MANAGE_V1, + description: "Builtin IDM Control for management of peoples non sensitive attributes.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_PEOPLE_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person), + match_class_filter!(EntryClass::Account), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + modify_removed_attrs: vec![Attribute::AccountExpire, Attribute::AccountValidFrom,], + modify_present_attrs: vec![Attribute::AccountExpire, Attribute::AccountValidFrom,], + ..Default::default() + }; +} + +// Person Read +lazy_static! { + pub static ref IDM_ACP_PEOPLE_READ_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + name: "idm_acp_people_read", + uuid: UUID_IDM_ACP_PEOPLE_READ_V1, + description: "Builtin IDM Control for reading non-sensitive data.", + receiver: BuiltinAcpReceiver::Group(vec![ + UUID_IDM_PEOPLE_ADMINS, + UUID_IDM_PEOPLE_PII_READ, + UUID_IDM_ACCOUNT_MAIL_READ, + UUID_IDM_SERVICE_DESK + ]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person).clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::Uuid, + Attribute::DisplayName, + Attribute::MemberOf, + Attribute::Uuid, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + ], + ..Default::default() + }; +} + +// Person Delete +lazy_static! { + pub static ref IDM_ACP_PEOPLE_DELETE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlDelete, + ], + name: "idm_acp_people_delete", + uuid: UUID_IDM_ACP_PEOPLE_DELETE_V1, + description: "Builtin IDM Control for deleting persons.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_PEOPLE_ADMINS,]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person).clone(), + match_class_filter!(EntryClass::Account).clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + ..Default::default() + }; +} + +// Person Account Credential Reset +lazy_static! { + pub static ref IDM_ACP_PEOPLE_CREDENTIAL_RESET_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_people_credential_reset", + uuid: UUID_IDM_ACP_PEOPLE_CREDENTIAL_RESET_V1, + description: "Builtin IDM Control for resetting peoples credentials ", + receiver: BuiltinAcpReceiver::Group(vec![ + UUID_IDM_PEOPLE_ADMINS, + UUID_IDM_SERVICE_DESK, + UUID_IDM_PEOPLE_ON_BOARDING, + ]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person), + match_class_filter!(EntryClass::Account), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Name, + Attribute::Spn, + Attribute::PrimaryCredential, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + modify_removed_attrs: vec![ + Attribute::PrimaryCredential, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + modify_present_attrs: vec![ + Attribute::PrimaryCredential, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + ..Default::default() + }; +} + +// HP Person Account Credential Reset +lazy_static! { + pub static ref IDM_ACP_HP_PEOPLE_CREDENTIAL_RESET_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_hp_people_credential_reset", + uuid: UUID_IDM_ACP_HP_PEOPLE_CREDENTIAL_RESET_V1, + description: "Builtin IDM Control for resetting high privilege peoples credentials ", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_PEOPLE_ADMINS,]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person), + match_class_filter!(EntryClass::Account), + FILTER_HP.clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Name, + Attribute::Spn, + Attribute::PrimaryCredential, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + modify_removed_attrs: vec![ + Attribute::PrimaryCredential, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + modify_present_attrs: vec![ + Attribute::PrimaryCredential, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + ..Default::default() + }; +} + +// Service Account Create/Manage +// needs to be able to assign to entry managed by +lazy_static! { + pub static ref IDM_ACP_SERVICE_ACCOUNT_CREATE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + ], + name: "idm_acp_service_account_create", + uuid: UUID_IDM_ACP_SERVICE_ACCOUNT_CREATE_V1, + description: "Builtin IDM Control for creating new service accounts.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_SERVICE_ACCOUNT_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::ServiceAccount).clone(), + match_class_filter!(EntryClass::Account).clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + create_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::DisplayName, + Attribute::EntryManagedBy, + Attribute::Description, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Account, + EntryClass::ServiceAccount, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SERVICE_ACCOUNT_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify + ], + name: "idm_acp_service_account_manage", + uuid: UUID_IDM_ACP_SERVICE_ACCOUNT_MANAGE_V1, + description: "Builtin IDM Control for modifying service account data", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_SERVICE_ACCOUNT_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::ServiceAccount).clone(), + match_class_filter!(EntryClass::Account).clone(), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::DisplayName, + Attribute::Mail, + Attribute::SshPublicKey, + Attribute::UnixPassword, + Attribute::PrimaryCredential, + Attribute::ApiTokenSession, + Attribute::UserAuthTokenSession, + ], + modify_present_attrs: vec![Attribute::Name, Attribute::DisplayName, Attribute::Mail,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SERVICE_ACCOUNT_DELETE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlDelete, + ], + name: "idm_acp_service_account_delete", + uuid: UUID_IDM_ACP_SERVICE_ACCOUNT_DELETE_V1, + description: "Builtin IDM Control for deleting service accounts.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_SERVICE_ACCOUNT_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::ServiceAccount).clone(), + match_class_filter!(EntryClass::Account).clone(), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + ..Default::default() + }; +} + +// Service Account Credential Manage +// entry managed by? + +lazy_static! { + pub static ref IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGER_V1: BuiltinAcp = BuiltinAcp{ + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_service_account_entry_manager", + uuid: UUID_IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGER_V1, + description: "Builtin IDM Control for allowing entry managers to modify service accounts", + receiver: BuiltinAcpReceiver::EntryManager, + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Account), + match_class_filter!(EntryClass::ServiceAccount), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::Uuid, + Attribute::EntryManagedBy, + Attribute::DisplayName, + Attribute::SshPublicKey, + Attribute::GidNumber, + Attribute::LoginShell, + Attribute::UnixPassword, + Attribute::PassKeys, + Attribute::PrimaryCredential, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::ApiTokenSession, + Attribute::UserAuthTokenSession, + ], + modify_removed_attrs: vec![ + Attribute::DisplayName, + Attribute::SshPublicKey, + Attribute::PrimaryCredential, + Attribute::UnixPassword, + // For legacy upgrades we allow removing this. + Attribute::PassKeys, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::ApiTokenSession, + Attribute::UserAuthTokenSession, + ], + modify_present_attrs: vec![ + Attribute::DisplayName, + Attribute::SshPublicKey, + Attribute::PrimaryCredential, + // Should this be a thing? I think no? + // Attribute::UnixPassword, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::ApiTokenSession, + ], + ..Default::default() + }; +} + +// Service Account Access Manager +lazy_static! { + pub static ref IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_service_account_entry_managed_by_modify", + uuid: UUID_IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY, + description: + "Builtin IDM Control for allowing entry_managed_by to be set on service account entries", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_SERVICE_ACCOUNT_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::ServiceAccount).clone(), + match_class_filter!(EntryClass::Account).clone(), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::Uuid, + Attribute::EntryManagedBy, + ], + modify_removed_attrs: vec![Attribute::EntryManagedBy], + modify_present_attrs: vec![Attribute::EntryManagedBy], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_HP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_hp_service_account_entry_managed_by", + uuid: UUID_IDM_ACP_HP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY, + description: "Builtin IDM Control for allowing entry_managed_by to be set on high priv service account entries", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ACCESS_CONTROL_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::ServiceAccount).clone(), + match_class_filter!(EntryClass::Account).clone(), + FILTER_HP.clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::Uuid, + Attribute::EntryManagedBy, + ], + modify_removed_attrs: vec![Attribute::EntryManagedBy], + modify_present_attrs: vec![Attribute::EntryManagedBy], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_HP_CLIENT_CERTIFICATE_MANAGER_DL7: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_hp_client_certificate_manager", + uuid: UUID_IDM_ACP_HP_CLIENT_CERTIFICATE_MANAGER, + description: "Builtin IDM Control for allowing client certificate management.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_CLIENT_CERTIFICATE_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + EntryClass::Class.to_string(), + EntryClass::ClientCertificate.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Certificate, + Attribute::Refers, + ], + modify_removed_attrs: vec![Attribute::Certificate, Attribute::Refers,], + modify_present_attrs: vec![Attribute::Certificate, Attribute::Refers,], + create_attrs: vec![Attribute::Class, Attribute::Certificate, Attribute::Refers,], + create_classes: vec![EntryClass::Object, EntryClass::ClientCertificate,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_APPLICATION_MANAGE_DL8: BuiltinAcp = BuiltinAcp{ + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_application_manage", + uuid: UUID_IDM_ACP_APPLICATION_MANAGE, + description: "Builtin IDM Control for creating and deleting applications in the directory", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_APPLICATION_ADMINS] ), + // Any application + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Application), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Name, + Attribute::Description, + Attribute::DisplayName, + Attribute::Mail, + Attribute::UnixPassword, + Attribute::ApiTokenSession, + Attribute::UserAuthTokenSession, + Attribute::LinkedGroup, + Attribute::EntryManagedBy, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Name, + Attribute::Description, + Attribute::DisplayName, + Attribute::Mail, + Attribute::LinkedGroup, + Attribute::EntryManagedBy, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Account, + EntryClass::ServiceAccount, + EntryClass::Application, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::DisplayName, + Attribute::Mail, + Attribute::UnixPassword, + Attribute::ApiTokenSession, + Attribute::LinkedGroup, + Attribute::EntryManagedBy, + ], + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::DisplayName, + Attribute::Mail, + Attribute::UnixPassword, + Attribute::ApiTokenSession, + Attribute::UserAuthTokenSession, + Attribute::LinkedGroup, + Attribute::EntryManagedBy, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_APPLICATION_ENTRY_MANAGER_DL8: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_application_entry_manager", + uuid: UUID_IDM_ACP_APPLICATION_ENTRY_MANAGER, + description: "Builtin IDM Control for allowing EntryManager to read and modify applications", + receiver: BuiltinAcpReceiver::EntryManager, + // Applications that belong to the Entry Manager. + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Application), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Name, + Attribute::DisplayName, + Attribute::Mail, + Attribute::UnixPassword, + Attribute::ApiTokenSession, + Attribute::UserAuthTokenSession, + Attribute::Description, + Attribute::LinkedGroup, + Attribute::EntryManagedBy, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::DisplayName, + Attribute::Mail, + Attribute::UnixPassword, + Attribute::ApiTokenSession, + Attribute::LinkedGroup, + ], + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::DisplayName, + Attribute::Mail, + Attribute::UnixPassword, + Attribute::ApiTokenSession, + Attribute::UserAuthTokenSession, + Attribute::LinkedGroup, + ], + ..Default::default() + }; +} diff --git a/server/lib/src/migration_data/dl8/accounts.rs b/server/lib/src/migration_data/dl8/accounts.rs new file mode 100644 index 000000000..f7b6a065a --- /dev/null +++ b/server/lib/src/migration_data/dl8/accounts.rs @@ -0,0 +1,35 @@ +//! Constant Entries for the IDM +use crate::constants::uuids::*; +use crate::migration_data::types::BuiltinAccount; +use kanidm_proto::v1::AccountType; + +lazy_static! { + /// Builtin System Admin account. + pub static ref BUILTIN_ACCOUNT_IDM_ADMIN: BuiltinAccount = BuiltinAccount { + account_type: AccountType::ServiceAccount, + entry_managed_by: None, + name: "idm_admin", + uuid: UUID_IDM_ADMIN, + description: "Builtin IDM Admin account.", + displayname: "IDM Administrator", + }; + + /// Builtin System Admin account. + pub static ref BUILTIN_ACCOUNT_ADMIN: BuiltinAccount = BuiltinAccount { + account_type: AccountType::ServiceAccount, + entry_managed_by: None, + name: "admin", + uuid: UUID_ADMIN, + description: "Builtin System Admin account.", + displayname: "System Administrator", + }; + + pub static ref BUILTIN_ACCOUNT_ANONYMOUS_DL6: BuiltinAccount = BuiltinAccount { + account_type: AccountType::ServiceAccount, + entry_managed_by: Some(UUID_IDM_ADMINS), + name: "anonymous", + uuid: UUID_ANONYMOUS, + description: "Anonymous access account.", + displayname: "Anonymous", + }; +} diff --git a/server/lib/src/constants/groups.rs b/server/lib/src/migration_data/dl8/groups.rs similarity index 90% rename from server/lib/src/constants/groups.rs rename to server/lib/src/migration_data/dl8/groups.rs index 29b402414..0955f9009 100644 --- a/server/lib/src/constants/groups.rs +++ b/server/lib/src/migration_data/dl8/groups.rs @@ -106,7 +106,9 @@ lazy_static! { members: vec![], ..Default::default() }; +} +lazy_static! { // These are the "finer" roles. They encapsulate different concepts in the system. // The next section is the "system style" roles. These adjust the operation of // kanidm and relate to it's internals and how it functions. @@ -404,46 +406,3 @@ lazy_static! { ..Default::default() }; } - -/// Make a list of all the non-admin BuiltinGroup's that are created by default, doing it in a standard-ish way so we can use it around the platform -pub fn idm_builtin_non_admin_groups() -> Vec<&'static BuiltinGroup> { - // Create any system default schema entries. - vec![ - &BUILTIN_GROUP_DOMAIN_ADMINS, - &BUILTIN_GROUP_SCHEMA_ADMINS, - &BUILTIN_GROUP_ACCESS_CONTROL_ADMINS, - &BUILTIN_GROUP_UNIX_ADMINS, - &BUILTIN_GROUP_RECYCLE_BIN_ADMINS, - &BUILTIN_GROUP_SERVICE_DESK, - &BUILTIN_GROUP_OAUTH2_ADMINS, - &BUILTIN_GROUP_RADIUS_SERVICE_ADMINS, - &BUILTIN_GROUP_ACCOUNT_POLICY_ADMINS, - &BUILTIN_GROUP_PEOPLE_ADMINS, - &BUILTIN_GROUP_PEOPLE_PII_READ, - &BUILTIN_GROUP_PEOPLE_ON_BOARDING, - &BUILTIN_GROUP_SERVICE_ACCOUNT_ADMINS, - &BUILTIN_GROUP_MAIL_SERVICE_ADMINS_DL8, - &IDM_GROUP_ADMINS_V1, - &IDM_ALL_PERSONS, - &IDM_ALL_ACCOUNTS, - &BUILTIN_IDM_RADIUS_SERVERS_V1, - &BUILTIN_IDM_MAIL_SERVERS_DL8, - &BUILTIN_GROUP_PEOPLE_SELF_NAME_WRITE_DL7, - &IDM_PEOPLE_SELF_MAIL_WRITE_DL7, - &BUILTIN_GROUP_CLIENT_CERTIFICATE_ADMINS_DL7, - &BUILTIN_GROUP_APPLICATION_ADMINS_DL8, - // Write deps on read, so write must be added first. - // All members must exist before we write HP - &IDM_HIGH_PRIVILEGE_DL8, - // other things - &IDM_UI_ENABLE_EXPERIMENTAL_FEATURES, - &IDM_ACCOUNT_MAIL_READ, - ] -} - -pub fn idm_builtin_admin_groups() -> Vec<&'static BuiltinGroup> { - vec![ - &BUILTIN_GROUP_SYSTEM_ADMINS_V1, - &BUILTIN_GROUP_IDM_ADMINS_V1, - ] -} diff --git a/server/lib/src/migration_data/dl8/key_providers.rs b/server/lib/src/migration_data/dl8/key_providers.rs new file mode 100644 index 000000000..f6cd2b3cf --- /dev/null +++ b/server/lib/src/migration_data/dl8/key_providers.rs @@ -0,0 +1,18 @@ +use crate::constants::entries::{Attribute, EntryClass}; +use crate::constants::uuids::UUID_KEY_PROVIDER_INTERNAL; +use crate::entry::{Entry, EntryInit, EntryInitNew, EntryNew}; +use crate::value::Value; + +lazy_static! { + pub static ref E_KEY_PROVIDER_INTERNAL_DL6: EntryInitNew = entry_init!( + (Attribute::Class, EntryClass::Object.to_value()), + (Attribute::Class, EntryClass::KeyProvider.to_value()), + (Attribute::Class, EntryClass::KeyProviderInternal.to_value()), + (Attribute::Uuid, Value::Uuid(UUID_KEY_PROVIDER_INTERNAL)), + (Attribute::Name, Value::new_iname("key_provider_internal")), + ( + Attribute::Description, + Value::new_utf8s("The default database internal cryptographic key provider.") + ) + ); +} diff --git a/server/lib/src/migration_data/dl8/mod.rs b/server/lib/src/migration_data/dl8/mod.rs new file mode 100644 index 000000000..df1114e84 --- /dev/null +++ b/server/lib/src/migration_data/dl8/mod.rs @@ -0,0 +1,273 @@ +mod access; +mod accounts; +mod groups; +mod key_providers; +mod schema; +mod system_config; + +use self::access::*; +use self::accounts::*; +use self::groups::*; +use self::key_providers::*; +use self::schema::*; +use self::system_config::*; + +use crate::prelude::EntryInitNew; +use kanidm_proto::internal::OperationError; + +pub fn phase_1_schema_attrs() -> Vec { + vec![ + SCHEMA_ATTR_SYNC_CREDENTIAL_PORTAL.clone().into(), + SCHEMA_ATTR_SYNC_YIELD_AUTHORITY.clone().into(), + SCHEMA_ATTR_ACCOUNT_EXPIRE.clone().into(), + SCHEMA_ATTR_ACCOUNT_VALID_FROM.clone().into(), + SCHEMA_ATTR_API_TOKEN_SESSION.clone().into(), + SCHEMA_ATTR_AUTH_SESSION_EXPIRY.clone().into(), + SCHEMA_ATTR_AUTH_PRIVILEGE_EXPIRY.clone().into(), + SCHEMA_ATTR_AUTH_PASSWORD_MINIMUM_LENGTH.clone().into(), + SCHEMA_ATTR_BADLIST_PASSWORD.clone().into(), + SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN.clone().into(), + SCHEMA_ATTR_ATTESTED_PASSKEYS.clone().into(), + SCHEMA_ATTR_DOMAIN_DISPLAY_NAME.clone().into(), + SCHEMA_ATTR_DOMAIN_LDAP_BASEDN.clone().into(), + SCHEMA_ATTR_DOMAIN_NAME.clone().into(), + SCHEMA_ATTR_LDAP_ALLOW_UNIX_PW_BIND.clone().into(), + SCHEMA_ATTR_DOMAIN_SSID.clone().into(), + SCHEMA_ATTR_DOMAIN_TOKEN_KEY.clone().into(), + SCHEMA_ATTR_DOMAIN_UUID.clone().into(), + SCHEMA_ATTR_DYNGROUP_FILTER.clone().into(), + SCHEMA_ATTR_EC_KEY_PRIVATE.clone().into(), + SCHEMA_ATTR_ES256_PRIVATE_KEY_DER.clone().into(), + SCHEMA_ATTR_FERNET_PRIVATE_KEY_STR.clone().into(), + SCHEMA_ATTR_GIDNUMBER.clone().into(), + SCHEMA_ATTR_GRANT_UI_HINT.clone().into(), + SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY.clone().into(), + SCHEMA_ATTR_LOGINSHELL.clone().into(), + SCHEMA_ATTR_NAME_HISTORY.clone().into(), + SCHEMA_ATTR_NSUNIQUEID.clone().into(), + SCHEMA_ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE + .clone() + .into(), + SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP.clone().into(), + SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE.clone().into(), + SCHEMA_ATTR_OAUTH2_PREFER_SHORT_USERNAME.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_BASIC_SECRET.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_IMPLICIT_SCOPES.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_NAME.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_ORIGIN_LANDING.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_TOKEN_KEY.clone().into(), + SCHEMA_ATTR_OAUTH2_SESSION.clone().into(), + SCHEMA_ATTR_PASSKEYS.clone().into(), + SCHEMA_ATTR_PRIMARY_CREDENTIAL.clone().into(), + SCHEMA_ATTR_PRIVATE_COOKIE_KEY.clone().into(), + SCHEMA_ATTR_RADIUS_SECRET.clone().into(), + SCHEMA_ATTR_RS256_PRIVATE_KEY_DER.clone().into(), + SCHEMA_ATTR_SSH_PUBLICKEY.clone().into(), + SCHEMA_ATTR_SYNC_COOKIE.clone().into(), + SCHEMA_ATTR_SYNC_TOKEN_SESSION.clone().into(), + SCHEMA_ATTR_UNIX_PASSWORD.clone().into(), + SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION.clone().into(), + SCHEMA_ATTR_DENIED_NAME.clone().into(), + SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM.clone().into(), + SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST.clone().into(), + // DL4 + SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP_DL4.clone().into(), + SCHEMA_ATTR_OAUTH2_ALLOW_LOCALHOST_REDIRECT_DL4 + .clone() + .into(), + // DL5 + // DL6 + SCHEMA_ATTR_LIMIT_SEARCH_MAX_RESULTS_DL6.clone().into(), + SCHEMA_ATTR_LIMIT_SEARCH_MAX_FILTER_TEST_DL6.clone().into(), + SCHEMA_ATTR_KEY_INTERNAL_DATA_DL6.clone().into(), + SCHEMA_ATTR_KEY_PROVIDER_DL6.clone().into(), + SCHEMA_ATTR_KEY_ACTION_ROTATE_DL6.clone().into(), + SCHEMA_ATTR_KEY_ACTION_REVOKE_DL6.clone().into(), + SCHEMA_ATTR_KEY_ACTION_IMPORT_JWS_ES256_DL6.clone().into(), + // DL7 + SCHEMA_ATTR_PATCH_LEVEL_DL7.clone().into(), + SCHEMA_ATTR_DOMAIN_DEVELOPMENT_TAINT_DL7.clone().into(), + SCHEMA_ATTR_REFERS_DL7.clone().into(), + SCHEMA_ATTR_CERTIFICATE_DL7.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_ORIGIN_DL7.clone().into(), + SCHEMA_ATTR_OAUTH2_STRICT_REDIRECT_URI_DL7.clone().into(), + SCHEMA_ATTR_MAIL_DL7.clone().into(), + SCHEMA_ATTR_LEGALNAME_DL7.clone().into(), + SCHEMA_ATTR_DISPLAYNAME_DL7.clone().into(), + // DL8 + SCHEMA_ATTR_LINKED_GROUP_DL8.clone().into(), + SCHEMA_ATTR_APPLICATION_PASSWORD_DL8.clone().into(), + SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK_DL8.clone().into(), + ] +} + +pub fn phase_2_schema_classes() -> Vec { + vec![ + SCHEMA_CLASS_DYNGROUP.clone().into(), + SCHEMA_CLASS_ORGPERSON.clone().into(), + SCHEMA_CLASS_POSIXACCOUNT.clone().into(), + SCHEMA_CLASS_POSIXGROUP.clone().into(), + SCHEMA_CLASS_SYSTEM_CONFIG.clone().into(), + // DL4 + SCHEMA_CLASS_OAUTH2_RS_PUBLIC_DL4.clone().into(), + // DL5 + // SCHEMA_CLASS_PERSON_DL5.clone().into(), + SCHEMA_CLASS_ACCOUNT_DL5.clone().into(), + // SCHEMA_CLASS_OAUTH2_RS_DL5.clone().into(), + SCHEMA_CLASS_OAUTH2_RS_BASIC_DL5.clone().into(), + // DL6 + // SCHEMA_CLASS_ACCOUNT_POLICY_DL6.clone().into(), + // SCHEMA_CLASS_SERVICE_ACCOUNT_DL6.clone().into(), + // SCHEMA_CLASS_SYNC_ACCOUNT_DL6.clone().into(), + SCHEMA_CLASS_GROUP_DL6.clone().into(), + SCHEMA_CLASS_KEY_PROVIDER_DL6.clone().into(), + SCHEMA_CLASS_KEY_PROVIDER_INTERNAL_DL6.clone().into(), + SCHEMA_CLASS_KEY_OBJECT_DL6.clone().into(), + SCHEMA_CLASS_KEY_OBJECT_JWT_ES256_DL6.clone().into(), + SCHEMA_CLASS_KEY_OBJECT_JWE_A128GCM_DL6.clone().into(), + SCHEMA_CLASS_KEY_OBJECT_INTERNAL_DL6.clone().into(), + // SCHEMA_CLASS_DOMAIN_INFO_DL6.clone().into(), + // DL7 + // SCHEMA_CLASS_DOMAIN_INFO_DL7.clone().into(), + SCHEMA_CLASS_SERVICE_ACCOUNT_DL7.clone().into(), + SCHEMA_CLASS_SYNC_ACCOUNT_DL7.clone().into(), + SCHEMA_CLASS_CLIENT_CERTIFICATE_DL7.clone().into(), + SCHEMA_CLASS_OAUTH2_RS_DL7.clone().into(), + // DL8 + SCHEMA_CLASS_ACCOUNT_POLICY_DL8.clone().into(), + SCHEMA_CLASS_APPLICATION_DL8.clone().into(), + SCHEMA_CLASS_PERSON_DL8.clone().into(), + SCHEMA_CLASS_DOMAIN_INFO_DL8.clone().into(), + ] +} + +pub fn phase_3_key_provider() -> Vec { + vec![E_KEY_PROVIDER_INTERNAL_DL6.clone()] +} + +pub fn phase_4_system_entries() -> Vec { + vec![ + E_SYSTEM_INFO_V1.clone(), + E_DOMAIN_INFO_DL6.clone(), + E_SYSTEM_CONFIG_V1.clone(), + ] +} + +pub fn phase_5_builtin_admin_entries() -> Result, OperationError> { + Ok(vec![ + BUILTIN_ACCOUNT_ADMIN.clone().into(), + BUILTIN_ACCOUNT_IDM_ADMIN.clone().into(), + BUILTIN_GROUP_SYSTEM_ADMINS_V1.clone().try_into()?, + BUILTIN_GROUP_IDM_ADMINS_V1.clone().try_into()?, + // We need to push anonymous *after* groups due to entry-managed-by + BUILTIN_ACCOUNT_ANONYMOUS_DL6.clone().into(), + ]) +} + +pub fn phase_6_builtin_non_admin_entries() -> Result, OperationError> { + Ok(vec![ + BUILTIN_GROUP_DOMAIN_ADMINS.clone().try_into()?, + BUILTIN_GROUP_SCHEMA_ADMINS.clone().try_into()?, + BUILTIN_GROUP_ACCESS_CONTROL_ADMINS.clone().try_into()?, + BUILTIN_GROUP_UNIX_ADMINS.clone().try_into()?, + BUILTIN_GROUP_RECYCLE_BIN_ADMINS.clone().try_into()?, + BUILTIN_GROUP_SERVICE_DESK.clone().try_into()?, + BUILTIN_GROUP_OAUTH2_ADMINS.clone().try_into()?, + BUILTIN_GROUP_RADIUS_SERVICE_ADMINS.clone().try_into()?, + BUILTIN_GROUP_ACCOUNT_POLICY_ADMINS.clone().try_into()?, + BUILTIN_GROUP_PEOPLE_ADMINS.clone().try_into()?, + BUILTIN_GROUP_PEOPLE_PII_READ.clone().try_into()?, + BUILTIN_GROUP_PEOPLE_ON_BOARDING.clone().try_into()?, + BUILTIN_GROUP_SERVICE_ACCOUNT_ADMINS.clone().try_into()?, + BUILTIN_GROUP_MAIL_SERVICE_ADMINS_DL8.clone().try_into()?, + IDM_GROUP_ADMINS_V1.clone().try_into()?, + IDM_ALL_PERSONS.clone().try_into()?, + IDM_ALL_ACCOUNTS.clone().try_into()?, + BUILTIN_IDM_RADIUS_SERVERS_V1.clone().try_into()?, + BUILTIN_IDM_MAIL_SERVERS_DL8.clone().try_into()?, + BUILTIN_GROUP_PEOPLE_SELF_NAME_WRITE_DL7 + .clone() + .try_into()?, + IDM_PEOPLE_SELF_MAIL_WRITE_DL7.clone().try_into()?, + BUILTIN_GROUP_CLIENT_CERTIFICATE_ADMINS_DL7 + .clone() + .try_into()?, + BUILTIN_GROUP_APPLICATION_ADMINS_DL8.clone().try_into()?, + // Write deps on read.clone().try_into()?, so write must be added first. + // All members must exist before we write HP + IDM_HIGH_PRIVILEGE_DL8.clone().try_into()?, + // other things + IDM_UI_ENABLE_EXPERIMENTAL_FEATURES.clone().try_into()?, + IDM_ACCOUNT_MAIL_READ.clone().try_into()?, + ]) +} + +pub fn phase_7_builtin_access_control_profiles() -> Vec { + vec![ + // Built in access controls. + IDM_ACP_RECYCLE_BIN_SEARCH_V1.clone().into(), + IDM_ACP_RECYCLE_BIN_REVIVE_V1.clone().into(), + IDM_ACP_SCHEMA_WRITE_ATTRS_V1.clone().into(), + IDM_ACP_SCHEMA_WRITE_CLASSES_V1.clone().into(), + IDM_ACP_ACP_MANAGE_V1.clone().into(), + IDM_ACP_GROUP_ENTRY_MANAGED_BY_MODIFY_V1.clone().into(), + IDM_ACP_GROUP_ENTRY_MANAGER_V1.clone().into(), + IDM_ACP_SYNC_ACCOUNT_MANAGE_V1.clone().into(), + IDM_ACP_RADIUS_SERVERS_V1.clone().into(), + IDM_ACP_RADIUS_SECRET_MANAGE_V1.clone().into(), + IDM_ACP_PEOPLE_SELF_WRITE_MAIL_V1.clone().into(), + // IDM_ACP_SELF_READ_V1.clone(), + // IDM_ACP_SELF_WRITE_V1.clone(), + IDM_ACP_ACCOUNT_SELF_WRITE_V1.clone().into(), + // IDM_ACP_SELF_NAME_WRITE_V1.clone(), + IDM_ACP_ALL_ACCOUNTS_POSIX_READ_V1.clone().into(), + IDM_ACP_SYSTEM_CONFIG_ACCOUNT_POLICY_MANAGE_V1 + .clone() + .into(), + IDM_ACP_GROUP_UNIX_MANAGE_V1.clone().into(), + IDM_ACP_HP_GROUP_UNIX_MANAGE_V1.clone().into(), + IDM_ACP_GROUP_READ_V1.clone().into(), + IDM_ACP_ACCOUNT_UNIX_EXTEND_V1.clone().into(), + IDM_ACP_PEOPLE_PII_READ_V1.clone().into(), + IDM_ACP_PEOPLE_PII_MANAGE_V1.clone().into(), + IDM_ACP_PEOPLE_READ_V1.clone().into(), + IDM_ACP_PEOPLE_MANAGE_V1.clone().into(), + IDM_ACP_PEOPLE_DELETE_V1.clone().into(), + IDM_ACP_PEOPLE_CREDENTIAL_RESET_V1.clone().into(), + IDM_ACP_HP_PEOPLE_CREDENTIAL_RESET_V1.clone().into(), + IDM_ACP_SERVICE_ACCOUNT_CREATE_V1.clone().into(), + IDM_ACP_SERVICE_ACCOUNT_DELETE_V1.clone().into(), + IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGER_V1.clone().into(), + IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1 + .clone() + .into(), + IDM_ACP_HP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1 + .clone() + .into(), + IDM_ACP_SERVICE_ACCOUNT_MANAGE_V1.clone().into(), + // DL4 + // DL5 + // IDM_ACP_OAUTH2_MANAGE_DL5.clone(), + // DL6 + // IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE_DL6.clone(), + IDM_ACP_PEOPLE_CREATE_DL6.clone().into(), + IDM_ACP_GROUP_MANAGE_DL6.clone().into(), + IDM_ACP_ACCOUNT_MAIL_READ_DL6.clone().into(), + // IDM_ACP_DOMAIN_ADMIN_DL6.clone(), + // DL7 + // IDM_ACP_SELF_WRITE_DL7.clone(), + IDM_ACP_SELF_NAME_WRITE_DL7.clone().into(), + IDM_ACP_HP_CLIENT_CERTIFICATE_MANAGER_DL7.clone().into(), + IDM_ACP_OAUTH2_MANAGE_DL7.clone().into(), + // DL8 + IDM_ACP_SELF_READ_DL8.clone().into(), + IDM_ACP_SELF_WRITE_DL8.clone().into(), + IDM_ACP_APPLICATION_MANAGE_DL8.clone().into(), + IDM_ACP_APPLICATION_ENTRY_MANAGER_DL8.clone().into(), + IDM_ACP_MAIL_SERVERS_DL8.clone().into(), + IDM_ACP_DOMAIN_ADMIN_DL8.clone().into(), + IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE_DL8.clone().into(), + ] +} diff --git a/server/lib/src/migration_data/dl8/schema.rs b/server/lib/src/migration_data/dl8/schema.rs new file mode 100644 index 000000000..1a3ebbca9 --- /dev/null +++ b/server/lib/src/migration_data/dl8/schema.rs @@ -0,0 +1,1506 @@ +//! Schema Entries +use crate::constants::entries::{Attribute, EntryClass}; +use crate::constants::uuids::*; +use crate::schema::{SchemaAttribute, SchemaClass}; +use crate::value::IndexType; +use crate::value::SyntaxType; + +lazy_static!( + +pub static ref SCHEMA_ATTR_DISPLAYNAME: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DISPLAYNAME, + name: Attribute::DisplayName, + description: "The publicly visible display name of this person".to_string(), + + index: vec![IndexType::Equality], + sync_allowed: true, + syntax: SyntaxType::Utf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DISPLAYNAME_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DISPLAYNAME, + name: Attribute::DisplayName, + description: "The publicly visible display name of this person".to_string(), + + index: vec![IndexType::Equality, IndexType::SubString], + sync_allowed: true, + syntax: SyntaxType::Utf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_MAIL: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_MAIL, + name: Attribute::Mail, + description: "Mail addresses of the object".to_string(), + + index: vec![IndexType::Equality], + unique: true, + multivalue: true, + sync_allowed: true, + syntax: SyntaxType::EmailAddress, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_MAIL_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_MAIL, + name: Attribute::Mail, + description: "Mail addresses of the object".to_string(), + + index: vec![IndexType::Equality, IndexType::SubString], + unique: true, + multivalue: true, + sync_allowed: true, + syntax: SyntaxType::EmailAddress, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_EC_KEY_PRIVATE: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_EC_KEY_PRIVATE, + name: Attribute::IdVerificationEcKey, + description: "Account verification private key".to_string(), + + index: vec![IndexType::Presence], + unique: false, + sync_allowed: false, + syntax: SyntaxType::EcKeyPrivate, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_SSH_PUBLICKEY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_SSH_PUBLICKEY, + name: Attribute::SshPublicKey, + description: "SSH public keys of the object".to_string(), + + multivalue: true, + sync_allowed: true, + syntax: SyntaxType::SshKey, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_PRIMARY_CREDENTIAL: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_PRIMARY_CREDENTIAL, + name: Attribute::PrimaryCredential, + description: "Primary credential material of the account for authentication interactively".to_string(), + + index: vec![IndexType::Presence], + sync_allowed: true, + syntax: SyntaxType::Credential, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_LEGALNAME: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_LEGALNAME, + name: Attribute::LegalName, + description: "The private and sensitive legal name of this person".to_string(), + + index: vec![IndexType::Equality], + sync_allowed: true, + syntax: SyntaxType::Utf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_LEGALNAME_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_LEGALNAME, + name: Attribute::LegalName, + description: "The private and sensitive legal name of this person".to_string(), + + index: vec![IndexType::Equality, IndexType::SubString], + sync_allowed: true, + syntax: SyntaxType::Utf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_NAME_HISTORY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_NAME_HISTORY, + name: Attribute::NameHistory, + description: "The history of names that a person has had".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + sync_allowed: true, + syntax: SyntaxType::AuditLogString, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_RADIUS_SECRET: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_RADIUS_SECRET, + name: Attribute::RadiusSecret, + description: "The accounts generated radius secret for device network authentication".to_string(), + + sync_allowed: true, + syntax: SyntaxType::SecretUtf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_NAME: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_NAME, + name: Attribute::DomainName, + description: "The domain's DNS name for webauthn and SPN generation purposes".to_string(), + + index: vec![IndexType::Equality, IndexType::Presence], + unique: true, + syntax: SyntaxType::Utf8StringIname, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_LDAP_ALLOW_UNIX_PW_BIND: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_LDAP_ALLOW_UNIX_PW_BIND, + name: Attribute::LdapAllowUnixPwBind, + description: "Configuration to enable binds to LDAP objects using their UNIX password".to_string(), + + unique: false, + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_LDAP_BASEDN: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_LDAP_BASEDN, + name: Attribute::DomainLdapBasedn, + description: "The domain's optional ldap basedn. If unset defaults to domain components of domain name".to_string(), + + unique: true, + syntax: SyntaxType::Utf8StringInsensitive, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_DISPLAY_NAME: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_DISPLAY_NAME, + name: Attribute::DomainDisplayName, + description: "The user-facing display name of the Kanidm domain".to_string(), + + index: vec![IndexType::Equality], + syntax: SyntaxType::Utf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_UUID: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_UUID, + name: Attribute::DomainUuid, + description: "The domain's uuid, used in CSN and trust relationships".to_string(), + + index: vec![IndexType::Equality], + unique: true, + syntax: SyntaxType::Uuid, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_SSID: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_SSID, + name: Attribute::DomainSsid, + description: "The domains site-wide SSID for device autoconfiguration of wireless".to_string(), + + index: vec![IndexType::Equality], + unique: true, + syntax: SyntaxType::Utf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DENIED_NAME: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DENIED_NAME, + name: Attribute::DeniedName, + description: "Iname values that are not allowed to be used in 'name'.".to_string(), + + syntax: SyntaxType::Utf8StringIname, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DENIED_NAME_DL10: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DENIED_NAME, + name: Attribute::DeniedName, + description: "Iname values that are not allowed to be used in 'name'.".to_string(), + + syntax: SyntaxType::Utf8StringIname, + multivalue: true, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_TOKEN_KEY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_TOKEN_KEY, + name: Attribute::DomainTokenKey, + description: "The domain token encryption private key (NOT USED)".to_string(), + + syntax: SyntaxType::SecretUtf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_FERNET_PRIVATE_KEY_STR: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_FERNET_PRIVATE_KEY_STR, + name: Attribute::FernetPrivateKeyStr, + description: "The token encryption private key".to_string(), + + syntax: SyntaxType::SecretUtf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_GIDNUMBER: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_GIDNUMBER, + name: Attribute::GidNumber, + description: "The groupid (uid) number of a group or account.to_string(). This is the same value as the UID number on posix accounts for security reasons".to_string(), + + index: vec![IndexType::Equality], + unique: true, + sync_allowed: true, + syntax: SyntaxType::Uint32, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_BADLIST_PASSWORD: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_BADLIST_PASSWORD, + name: Attribute::BadlistPassword, + description: "A password that is badlisted meaning that it can not be set as a valid password by any user account".to_string(), + + multivalue: true, + syntax: SyntaxType::Utf8StringInsensitive, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_AUTH_SESSION_EXPIRY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_AUTH_SESSION_EXPIRY, + name: Attribute::AuthSessionExpiry, + description: "An expiration time for an authentication session".to_string(), + + syntax: SyntaxType::Uint32, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_AUTH_PRIVILEGE_EXPIRY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_AUTH_PRIVILEGE_EXPIRY, + name: Attribute::PrivilegeExpiry, + description: "An expiration time for a privileged authentication session".to_string(), + + syntax: SyntaxType::Uint32, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_AUTH_PASSWORD_MINIMUM_LENGTH: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_AUTH_PASSWORD_MINIMUM_LENGTH, + name: Attribute::AuthPasswordMinimumLength, + description: "Minimum length of passwords".to_string(), + + syntax: SyntaxType::Uint32, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_LOGINSHELL: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_LOGINSHELL, + name: Attribute::LoginShell, + description: "A POSIX user's UNIX login shell".to_string(), + + sync_allowed: true, + syntax: SyntaxType::Utf8StringInsensitive, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_UNIX_PASSWORD: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_UNIX_PASSWORD, + name: Attribute::UnixPassword, + description: "A POSIX user's UNIX login password".to_string(), + + index: vec![IndexType::Presence], + syntax: SyntaxType::Credential, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_NSUNIQUEID: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_NSUNIQUEID, + name: Attribute::NsUniqueId, + description: "A unique id compatibility for 389-ds/dsee".to_string(), + + index: vec![IndexType::Equality], + unique: true, + sync_allowed: true, + syntax: SyntaxType::NsUniqueId, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_ACCOUNT_EXPIRE: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_ACCOUNT_EXPIRE, + name: Attribute::AccountExpire, + description: "The datetime after which this account no longer may authenticate".to_string(), + + sync_allowed: true, + syntax: SyntaxType::DateTime, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_ACCOUNT_VALID_FROM: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_ACCOUNT_VALID_FROM, + name: Attribute::AccountValidFrom, + description: "The datetime after which this account may commence authenticating".to_string(), + + sync_allowed: true, + syntax: SyntaxType::DateTime, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST, + name: Attribute::WebauthnAttestationCaList, + description: "A set of CA's that limit devices that can be used with webauthn".to_string(), + + syntax: SyntaxType::WebauthnAttestationCaList, + multivalue: true, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_NAME: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_NAME, + name: Attribute::OAuth2RsName, + description: "The unique name of an external Oauth2 resource".to_string(), + + index: vec![IndexType::Equality], + unique: true, + syntax: SyntaxType::Utf8StringIname, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_ORIGIN: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_ORIGIN, + name: Attribute::OAuth2RsOrigin, + description: "The origin domain of an oauth2 resource server".to_string(), + + syntax: SyntaxType::Url, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_ORIGIN_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_ORIGIN, + name: Attribute::OAuth2RsOrigin, + description: "The origin domain of an OAuth2 client".to_string(), + + syntax: SyntaxType::Url, + multivalue: true, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_ORIGIN_LANDING: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_ORIGIN_LANDING, + name: Attribute::OAuth2RsOriginLanding, + description: "The landing page of an RS, that will automatically trigger the auth process".to_string(), + + syntax: SyntaxType::Url, + ..Default::default() +}; + +// Introduced in DomainLevel4 +pub static ref SCHEMA_ATTR_OAUTH2_ALLOW_LOCALHOST_REDIRECT_DL4: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_ALLOW_LOCALHOST_REDIRECT, + name: Attribute::OAuth2AllowLocalhostRedirect, + description: "Allow public clients associated to this RS to redirect to localhost".to_string(), + + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP_DL4: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP, + name: Attribute::OAuth2RsClaimMap, + description: "A set of custom claims mapped to group memberships of accounts".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + // CHANGE ME + syntax: SyntaxType::OauthClaimMap, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP, + name: Attribute::OAuth2RsScopeMap, + description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + syntax: SyntaxType::OauthScopeMap, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP, + name: Attribute::OAuth2RsSupScopeMap, + description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + syntax: SyntaxType::OauthScopeMap, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_BASIC_SECRET: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_BASIC_SECRET, + name: Attribute::OAuth2RsBasicSecret, + description: "When using oauth2 basic authentication, the secret string of the resource server".to_string(), + + syntax: SyntaxType::SecretUtf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_TOKEN_KEY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_TOKEN_KEY, + name: Attribute::OAuth2RsTokenKey, + description: "An oauth2 resource servers unique token signing key".to_string(), + + syntax: SyntaxType::SecretUtf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_IMPLICIT_SCOPES: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_IMPLICIT_SCOPES, + name: Attribute::OAuth2RsImplicitScopes, + description: "An oauth2 resource servers scopes that are implicitly granted to all users".to_string(), + + multivalue: true, + syntax: SyntaxType::OauthScope, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP, + name: Attribute::OAuth2ConsentScopeMap, + description: "A set of scopes mapped from a relying server to a user, where the user has previously consented to the following. If changed or deleted, consent will be re-sought".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + syntax: SyntaxType::OauthScopeMap, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_STRICT_REDIRECT_URI_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_STRICT_REDIRECT_URI, + name: Attribute::OAuth2StrictRedirectUri, + description: "Represents if strict redirect uri enforcement is enabled.".to_string(), + + syntax: SyntaxType::Boolean, + ..Default::default() +}; + + +pub static ref SCHEMA_ATTR_OAUTH2_DEVICE_FLOW_ENABLE_DL9: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_DEVICE_FLOW_ENABLE, + name: Attribute::OAuth2DeviceFlowEnable, + description: "Represents if OAuth2 Device Flow is permitted on this client.".to_string(), + + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_ES256_PRIVATE_KEY_DER: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_ES256_PRIVATE_KEY_DER, + name: Attribute::Es256PrivateKeyDer, + description: "An es256 private key".to_string(), + + syntax: SyntaxType::PrivateBinary, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_RS256_PRIVATE_KEY_DER: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_RS256_PRIVATE_KEY_DER, + name: Attribute::Rs256PrivateKeyDer, + description: "An rs256 private key".to_string(), + + syntax: SyntaxType::PrivateBinary, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY, + name: Attribute::JwsEs256PrivateKey, + description: "An es256 private key for jws".to_string(), + + index: vec![IndexType::Equality], + unique: true, + syntax: SyntaxType::JwsKeyEs256, + ..Default::default() +}; + +// TO BE REMOVED IN A FUTURE RELEASE +pub static ref SCHEMA_ATTR_PRIVATE_COOKIE_KEY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_PRIVATE_COOKIE_KEY, + name: Attribute::PrivateCookieKey, + description: "An private cookie hmac key".to_string(), + + syntax: SyntaxType::PrivateBinary, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE, + name: Attribute::OAuth2AllowInsecureClientDisablePkce, + description: "Allows disabling of PKCE for insecure OAuth2 clients".to_string(), + + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE, + name: Attribute::OAuth2JwtLegacyCryptoEnable, + description: "Allows enabling legacy JWT cryptograhpy for clients".to_string(), + + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN, + name: Attribute::CredentialUpdateIntentToken, + description: "The status of a credential update intent token".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + syntax: SyntaxType::IntentToken, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_PASSKEYS: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_PASSKEYS, + name: Attribute::PassKeys, + description: "A set of registered passkeys".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + sync_allowed: true, + syntax: SyntaxType::Passkey, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_ATTESTED_PASSKEYS: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_ATTESTED_PASSKEYS, + name: Attribute::AttestedPasskeys, + description: "A set of registered device keys".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + sync_allowed: true, + syntax: SyntaxType::AttestedPasskey, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DYNGROUP_FILTER: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DYNGROUP_FILTER, + name: Attribute::DynGroupFilter, + description: "A filter describing the set of entries to add to a dynamic group".to_string(), + + syntax: SyntaxType::JsonFilter, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_PREFER_SHORT_USERNAME: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_PREFER_SHORT_USERNAME, + name: Attribute::OAuth2PreferShortUsername, + description: "Use 'name' instead of 'spn' in the preferred_username claim".to_string(), + + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_API_TOKEN_SESSION: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_API_TOKEN_SESSION, + name: Attribute::ApiTokenSession, + description: "A session entry related to an issued API token".to_string(), + + index: vec![IndexType::Equality], + unique: true, + multivalue: true, + syntax: SyntaxType::ApiToken, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION, + name: Attribute::UserAuthTokenSession, + description: "A session entry related to an issued user auth token".to_string(), + + index: vec![IndexType::Equality], + unique: true, + multivalue: true, + syntax: SyntaxType::Session, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_SESSION: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_SESSION, + name: Attribute::OAuth2Session, + description: "A session entry to an active oauth2 session, bound to a parent user auth token".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + syntax: SyntaxType::Oauth2Session, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_SYNC_TOKEN_SESSION: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_SYNC_TOKEN_SESSION, + name: Attribute::SyncTokenSession, + description: "A session entry related to an issued sync token".to_string(), + + index: vec![IndexType::Equality], + unique: true, + syntax: SyntaxType::ApiToken, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_SYNC_COOKIE: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_SYNC_COOKIE, + name: Attribute::SyncCookie, + description: "A private sync cookie for a remote IDM source".to_string(), + + syntax: SyntaxType::PrivateBinary, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_GRANT_UI_HINT: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_GRANT_UI_HINT, + name: Attribute::GrantUiHint, + description: "A UI hint that is granted via membership to a group".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + syntax: SyntaxType::UiHint, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_SYNC_CREDENTIAL_PORTAL: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_SYNC_CREDENTIAL_PORTAL, + name: Attribute::SyncCredentialPortal, + description: "The url of an external credential portal for synced accounts to visit to update their credentials".to_string(), + + syntax: SyntaxType::Url, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_SYNC_YIELD_AUTHORITY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_SYNC_YIELD_AUTHORITY, + name: Attribute::SyncYieldAuthority, + description: "A set of attributes that have their authority yielded to Kanidm in a sync agreement".to_string(), + + multivalue: true, + syntax: SyntaxType::Utf8StringInsensitive, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM, + name: Attribute::CredentialTypeMinimum, + description: "The minimum level of credential type that can satisfy this policy".to_string(), + + multivalue: false, + syntax: SyntaxType::CredentialType, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_LIMIT_SEARCH_MAX_RESULTS_DL6: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_LIMIT_SEARCH_MAX_RESULTS, + name: Attribute::LimitSearchMaxResults, + description: "The maximum number of query results that may be returned in a single operation".to_string(), + + multivalue: false, + syntax: SyntaxType::Uint32, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_LIMIT_SEARCH_MAX_FILTER_TEST_DL6: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_LIMIT_SEARCH_MAX_FILTER_TEST, + name: Attribute::LimitSearchMaxFilterTest, + description: "The maximum number of entries that may be examined in a partially indexed query".to_string(), + + multivalue: false, + syntax: SyntaxType::Uint32, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_KEY_INTERNAL_DATA_DL6: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_KEY_INTERNAL_DATA, + name: Attribute::KeyInternalData, + description: "".to_string(), + multivalue: true, + syntax: SyntaxType::KeyInternal, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_KEY_PROVIDER_DL6: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_KEY_PROVIDER, + name: Attribute::KeyProvider, + description: "".to_string(), + multivalue: false, + syntax: SyntaxType::ReferenceUuid, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_KEY_ACTION_ROTATE_DL6: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_KEY_ACTION_ROTATE, + name: Attribute::KeyActionRotate, + description: "".to_string(), + multivalue: false, + // Ephemeral action. + phantom: true, + syntax: SyntaxType::DateTime, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_KEY_ACTION_REVOKE_DL6: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_KEY_ACTION_REVOKE, + name: Attribute::KeyActionRevoke, + description: "".to_string(), + multivalue: true, + // Ephemeral action. + phantom: true, + syntax: SyntaxType::HexString, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_KEY_ACTION_IMPORT_JWS_ES256_DL6: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_KEY_ACTION_IMPORT_JWS_ES256, + name: Attribute::KeyActionImportJwsEs256, + description: "".to_string(), + multivalue: true, + // Ephemeral action. + phantom: true, + syntax: SyntaxType::PrivateBinary, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_PATCH_LEVEL_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_PATCH_LEVEL, + name: Attribute::PatchLevel, + description: "".to_string(), + syntax: SyntaxType::Uint32, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_DEVELOPMENT_TAINT_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_DEVELOPMENT_TAINT, + name: Attribute::DomainDevelopmentTaint, + description: "A flag to show that the domain has been run on a development build, and will need additional work to upgrade/migrate.".to_string(), + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_ALLOW_EASTER_EGGS_DL9: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_ALLOW_EASTER_EGGS, + name: Attribute::DomainAllowEasterEggs, + description: "A flag to enable easter eggs in the server that may not always be wanted by all users/deployments.".to_string(), + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_REFERS_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_REFERS, + name: Attribute::Refers, + description: "A reference to linked object".to_string(), + multivalue: false, + syntax: SyntaxType::ReferenceUuid, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_LINKED_GROUP_DL8: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_LINKED_GROUP, + name: Attribute::LinkedGroup, + description: "A reference linking a group to an entry".to_string(), + + multivalue: false, + syntax: SyntaxType::ReferenceUuid, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK_DL8: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK, + name: Attribute::AllowPrimaryCredFallback, + description: "Allow fallback to primary password if no POSIX password exists".to_string(), + + multivalue: false, + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_CERTIFICATE_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_CERTIFICATE, + name: Attribute::Certificate, + description: "An x509 Certificate".to_string(), + multivalue: false, + syntax: SyntaxType::Certificate, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_APPLICATION_PASSWORD_DL8: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_APPLICATION_PASSWORD, + name: Attribute::ApplicationPassword, + description: "A set of application passwords".to_string(), + + multivalue: true, + syntax: SyntaxType::ApplicationPassword, + ..Default::default() +}; + +// === classes === + +pub static ref SCHEMA_CLASS_PERSON: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_PERSON, + name: EntryClass::Person.into(), + description: "Object representation of a person".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::Mail, + Attribute::LegalName, + ], + systemmust: vec![ + Attribute::DisplayName, + Attribute::Name, + Attribute::IdVerificationEcKey], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_PERSON_DL5: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_PERSON, + name: EntryClass::Person.into(), + description: "Object representation of a person".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::PrimaryCredential, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::CredentialUpdateIntentToken, + Attribute::SshPublicKey, + Attribute::RadiusSecret, + Attribute::OAuth2ConsentScopeMap, + Attribute::UserAuthTokenSession, + Attribute::OAuth2Session, + Attribute::Mail, + Attribute::LegalName, + ], + systemmust: vec![ + Attribute::IdVerificationEcKey + ], + systemexcludes: vec![EntryClass::ServiceAccount.into(), EntryClass::Application.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_PERSON_DL8: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_PERSON, + name: EntryClass::Person.into(), + description: "Object representation of a person".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::PrimaryCredential, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::CredentialUpdateIntentToken, + Attribute::SshPublicKey, + Attribute::RadiusSecret, + Attribute::OAuth2ConsentScopeMap, + Attribute::UserAuthTokenSession, + Attribute::OAuth2Session, + Attribute::Mail, + Attribute::LegalName, + Attribute::ApplicationPassword, + ], + systemmust: vec![ + Attribute::IdVerificationEcKey + ], + systemexcludes: vec![EntryClass::ServiceAccount.into(), EntryClass::Application.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_ORGPERSON: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_ORGPERSON, + name: EntryClass::OrgPerson.into(), + description: "Object representation of an org person".to_string(), + + systemmay: vec![ + Attribute::LegalName + ], + systemmust: vec![ + Attribute::Mail, + Attribute::DisplayName, + Attribute::Name + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_GROUP_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_GROUP, + name: EntryClass::Group.into(), + description: "Object representation of a group".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::Member, + Attribute::GrantUiHint, + Attribute::Description, + Attribute::Mail, + ], + systemmust: vec![ + Attribute::Name, + Attribute::Spn], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_DYNGROUP: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_DYNGROUP, + name: EntryClass::DynGroup.into(), + description: "Object representation of a dynamic group".to_string(), + + systemmust: vec![Attribute::DynGroupFilter], + systemmay: vec![Attribute::DynMember], + systemsupplements: vec![Attribute::Group.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_ACCOUNT_POLICY_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_ACCOUNT_POLICY, + name: EntryClass::AccountPolicy.into(), + description: "Policies applied to accounts that are members of a group".to_string(), + + systemmay: vec![ + Attribute::AuthSessionExpiry, + Attribute::PrivilegeExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + ], + systemsupplements: vec![Attribute::Group.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_ACCOUNT_POLICY_DL8: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_ACCOUNT_POLICY, + name: EntryClass::AccountPolicy.into(), + description: "Policies applied to accounts that are members of a group".to_string(), + + systemmay: vec![ + Attribute::AuthSessionExpiry, + Attribute::PrivilegeExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + Attribute::AllowPrimaryCredFallback, + ], + systemsupplements: vec![Attribute::Group.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_ACCOUNT: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_ACCOUNT, + name: EntryClass::Account.into(), + description: "Object representation of an account".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::PrimaryCredential, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::CredentialUpdateIntentToken, + Attribute::SshPublicKey, + Attribute::RadiusSecret, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::Mail, + Attribute::OAuth2ConsentScopeMap, + Attribute::UserAuthTokenSession, + Attribute::OAuth2Session, + Attribute::Description, + Attribute::NameHistory, + ], + systemmust: vec![ + Attribute::DisplayName, + Attribute::Name, + Attribute::Spn + ], + systemsupplements: vec![ + EntryClass::Person.into(), + EntryClass::ServiceAccount.into(), + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_ACCOUNT_DL5: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_ACCOUNT, + name: EntryClass::Account.into(), + description: "Object representation of an account".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::NameHistory, + ], + systemmust: vec![ + Attribute::DisplayName, + Attribute::Name, + Attribute::Spn + ], + systemsupplements: vec![ + EntryClass::Person.into(), + EntryClass::ServiceAccount.into(), + EntryClass::OAuth2ResourceServer.into(), + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_SERVICE_ACCOUNT_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_SERVICE_ACCOUNT, + name: EntryClass::ServiceAccount.into(), + description: "Object representation of service account".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::SshPublicKey, + Attribute::UserAuthTokenSession, + Attribute::OAuth2Session, + Attribute::OAuth2ConsentScopeMap, + Attribute::Description, + + Attribute::Mail, + Attribute::PrimaryCredential, + Attribute::ApiTokenSession, + + Attribute::JwsEs256PrivateKey, + ], + systemexcludes: vec![EntryClass::Person.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_SERVICE_ACCOUNT_DL7: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_SERVICE_ACCOUNT, + name: EntryClass::ServiceAccount.into(), + description: "Object representation of service account".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::SshPublicKey, + Attribute::UserAuthTokenSession, + Attribute::OAuth2Session, + Attribute::OAuth2ConsentScopeMap, + Attribute::Description, + + Attribute::Mail, + Attribute::PrimaryCredential, + Attribute::ApiTokenSession, + ], + systemexcludes: vec![EntryClass::Person.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_SYNC_ACCOUNT_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_SYNC_ACCOUNT, + name: EntryClass::SyncAccount.into(), + description: "Object representation of sync account".to_string(), + + systemmust: vec![Attribute::Name], + systemmay: vec![ + Attribute::SyncTokenSession, + Attribute::SyncCookie, + Attribute::SyncCredentialPortal, + Attribute::SyncYieldAuthority, + Attribute::JwsEs256PrivateKey, + ], + systemexcludes: vec![EntryClass::Account.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_SYNC_ACCOUNT_DL7: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_SYNC_ACCOUNT, + name: EntryClass::SyncAccount.into(), + description: "Object representation of sync account".to_string(), + + systemmust: vec![Attribute::Name], + systemmay: vec![ + Attribute::SyncTokenSession, + Attribute::SyncCookie, + Attribute::SyncCredentialPortal, + Attribute::SyncYieldAuthority, + ], + systemexcludes: vec![EntryClass::Account.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO, + name: EntryClass::DomainInfo.into(), + description: "Local domain information and configuration".to_string(), + + systemmay: vec![ + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::LdapAllowUnixPwBind, + Attribute::PrivateCookieKey, + Attribute::FernetPrivateKeyStr, + Attribute::Es256PrivateKeyDer, + Attribute::PatchLevel, + Attribute::DomainDevelopmentTaint, + ], + systemmust: vec![ + Attribute::Name, + Attribute::DomainUuid, + Attribute::DomainName, + Attribute::DomainDisplayName, + Attribute::Version, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL7: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO, + name: EntryClass::DomainInfo.into(), + description: "Local domain information and configuration".to_string(), + + systemmay: vec![ + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::LdapAllowUnixPwBind, + Attribute::PatchLevel, + Attribute::DomainDevelopmentTaint, + ], + systemmust: vec![ + Attribute::Name, + Attribute::DomainUuid, + Attribute::DomainName, + Attribute::DomainDisplayName, + Attribute::Version, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL8: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO, + name: EntryClass::DomainInfo.into(), + description: "Local domain information and configuration".to_string(), + + systemmay: vec![ + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::LdapAllowUnixPwBind, + Attribute::Image, + Attribute::PatchLevel, + Attribute::DomainDevelopmentTaint, + ], + systemmust: vec![ + Attribute::Name, + Attribute::DomainUuid, + Attribute::DomainName, + Attribute::DomainDisplayName, + Attribute::Version, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL9: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO, + name: EntryClass::DomainInfo.into(), + description: "Local domain information and configuration".to_string(), + + systemmay: vec![ + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::LdapAllowUnixPwBind, + Attribute::Image, + Attribute::PatchLevel, + Attribute::DomainDevelopmentTaint, + Attribute::DomainAllowEasterEggs, + ], + systemmust: vec![ + Attribute::Name, + Attribute::DomainUuid, + Attribute::DomainName, + Attribute::DomainDisplayName, + Attribute::Version, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL10: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO, + name: EntryClass::DomainInfo.into(), + description: "Local domain information and configuration".to_string(), + + systemmay: vec![ + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::LdapAllowUnixPwBind, + Attribute::Image, + Attribute::PatchLevel, + Attribute::DomainDevelopmentTaint, + Attribute::DomainAllowEasterEggs, + Attribute::DomainDisplayName, + ], + systemmust: vec![ + Attribute::Name, + Attribute::DomainUuid, + Attribute::DomainName, + Attribute::Version, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_POSIXGROUP: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_POSIXGROUP, + name: EntryClass::PosixGroup.into(), + description: "Object representation of a posix group, requires group".to_string(), + + sync_allowed: true, + systemmust: vec![Attribute::GidNumber], + systemsupplements: vec![Attribute::Group.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_POSIXACCOUNT: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_POSIXACCOUNT, + name: EntryClass::PosixAccount.into(), + description: "Object representation of a posix account, requires account".to_string(), + + sync_allowed: true, + systemmay: vec![Attribute::LoginShell, Attribute::UnixPassword], + systemmust: vec![Attribute::GidNumber], + systemsupplements: vec![Attribute::Account.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_SYSTEM_CONFIG: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_SYSTEM_CONFIG, + name: EntryClass::SystemConfig.into(), + description: "The class representing a system (topologies) configuration options".to_string(), + + systemmay: vec![ + Attribute::Description, + Attribute::BadlistPassword, + Attribute::AuthSessionExpiry, + Attribute::PrivilegeExpiry, + Attribute::DeniedName + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_OAUTH2_RS_DL4: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_OAUTH2_RS, + name: EntryClass::OAuth2ResourceServer.into(), + description: "The class representing a configured Oauth2 Resource Server".to_string(), + + systemmay: vec![ + Attribute::Description, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2RsOriginLanding, + Attribute::Image, + Attribute::OAuth2RsClaimMap, + ], + systemmust: vec![ + Attribute::OAuth2RsName, + Attribute::DisplayName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_OAUTH2_RS_DL5: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_OAUTH2_RS, + name: EntryClass::OAuth2ResourceServer.into(), + description: "The class representing a configured Oauth2 Resource Server".to_string(), + + systemmay: vec![ + Attribute::Description, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2RsOriginLanding, + Attribute::Image, + Attribute::OAuth2RsClaimMap, + Attribute::OAuth2Session, + ], + systemmust: vec![ + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_OAUTH2_RS_DL7: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_OAUTH2_RS, + name: EntryClass::OAuth2ResourceServer.into(), + description: "The class representing a configured OAuth2 Client".to_string(), + + systemmay: vec![ + Attribute::Description, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::Image, + Attribute::OAuth2RsClaimMap, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2StrictRedirectUri, + ], + systemmust: vec![ + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_OAUTH2_RS_DL9: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_OAUTH2_RS, + name: EntryClass::OAuth2ResourceServer.into(), + description: "The class representing a configured OAuth2 Client".to_string(), + + systemmay: vec![ + Attribute::Description, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::Image, + Attribute::OAuth2RsClaimMap, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2StrictRedirectUri, + Attribute::OAuth2DeviceFlowEnable, + ], + systemmust: vec![ + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_OAUTH2_RS_BASIC_DL5: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_OAUTH2_RS_BASIC, + name: EntryClass::OAuth2ResourceServerBasic.into(), + description: "The class representing a configured OAuth2 client authenticated with HTTP basic authentication".to_string(), + + systemmay: vec![ + Attribute::OAuth2AllowInsecureClientDisablePkce, + ], + systemmust: vec![ Attribute::OAuth2RsBasicSecret], + systemexcludes: vec![ EntryClass::OAuth2ResourceServerPublic.into()], + ..Default::default() +}; + +// Introduced in DomainLevel4 +pub static ref SCHEMA_CLASS_OAUTH2_RS_PUBLIC_DL4: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_OAUTH2_RS_PUBLIC, + name: EntryClass::OAuth2ResourceServerPublic.into(), + description: "The class representing a configured Public OAuth2 Client with PKCE verification".to_string(), + + systemmay: vec![Attribute::OAuth2AllowLocalhostRedirect], + systemexcludes: vec![EntryClass::OAuth2ResourceServerBasic.into()], + ..Default::default() +}; + +// ========================================= +// KeyProviders + +pub static ref SCHEMA_CLASS_KEY_PROVIDER_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_KEY_PROVIDER, + name: EntryClass::KeyProvider.into(), + description: "A provider for cryptographic key storage and operations".to_string(), + systemmay: vec![ + Attribute::Description, + ], + systemmust: vec![ + Attribute::Name, + ], + systemsupplements: vec![ + EntryClass::KeyProviderInternal.into(), + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_KEY_PROVIDER_INTERNAL_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_KEY_PROVIDER_INTERNAL, + name: EntryClass::KeyProviderInternal.into(), + description: "The Kanidm internal cryptographic key provider".to_string(), + ..Default::default() +}; + +// ========================================= +// KeyObjects + +pub static ref SCHEMA_CLASS_KEY_OBJECT_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_KEY_OBJECT, + name: EntryClass::KeyObject.into(), + description: "A cryptographic key object that can be used by a provider".to_string(), + systemmust: vec![ + Attribute::KeyProvider, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_KEY_OBJECT_JWT_ES256_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_KEY_OBJECT_JWT_ES256, + name: EntryClass::KeyObjectJwtEs256.into(), + description: "A marker class indicating that this keyobject must provide jwt es256 capability.".to_string(), + systemsupplements: vec![ + EntryClass::KeyObject.into(), + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_KEY_OBJECT_JWE_A128GCM_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_KEY_OBJECT_JWE_A128GCM, + name: EntryClass::KeyObjectJweA128GCM.into(), + description: "A marker class indicating that this keyobject must provide jwe aes-256-gcm capability.".to_string(), + systemsupplements: vec![ + EntryClass::KeyObject.into(), + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_KEY_OBJECT_INTERNAL_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_KEY_OBJECT_INTERNAL, + name: EntryClass::KeyObjectInternal.into(), + description: "A cryptographic key object that can be used by the internal provider".to_string(), + systemmay: vec![ + Attribute::KeyInternalData, + ], + systemsupplements: vec![ + EntryClass::KeyObject.into(), + ], + ..Default::default() +}; + +// ========================================= + +pub static ref SCHEMA_CLASS_CLIENT_CERTIFICATE_DL7: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_CLIENT_CERTIFICATE, + name: EntryClass::ClientCertificate.into(), + description: "A client authentication certificate".to_string(), + systemmay: vec![], + systemmust: vec![ + Attribute::Certificate, + Attribute::Refers, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_APPLICATION_DL8: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_APPLICATION, + name: EntryClass::Application.into(), + + description: "The class representing an application".to_string(), + systemmust: vec![Attribute::Name, Attribute::LinkedGroup], + systemmay: vec![Attribute::Description], + systemsupplements: vec![EntryClass::ServiceAccount.into()], + ..Default::default() +}; + +); diff --git a/server/lib/src/migration_data/dl8/system_config.rs b/server/lib/src/migration_data/dl8/system_config.rs new file mode 100644 index 000000000..107bd8bbe --- /dev/null +++ b/server/lib/src/migration_data/dl8/system_config.rs @@ -0,0 +1,1073 @@ +use crate::constants::uuids::*; + +use crate::entry::{Entry, EntryInit, EntryInitNew, EntryNew}; +use crate::prelude::{Attribute, EntryClass}; +use crate::value::Value; + +// Default entries for system_config +// This is separated because the password badlist section may become very long + +lazy_static! { + pub static ref E_SYSTEM_INFO_V1: EntryInitNew = entry_init!( + (Attribute::Class, EntryClass::Object.to_value()), + (Attribute::Class, EntryClass::SystemInfo.to_value()), + (Attribute::Class, EntryClass::System.to_value()), + (Attribute::Uuid, Value::Uuid(UUID_SYSTEM_INFO)), + ( + Attribute::Description, + Value::new_utf8s("System (local) info and metadata object.") + ), + (Attribute::Version, Value::Uint32(20)) + ); + pub static ref E_DOMAIN_INFO_DL6: EntryInitNew = entry_init!( + (Attribute::Class, EntryClass::Object.to_value()), + (Attribute::Class, EntryClass::DomainInfo.to_value()), + (Attribute::Class, EntryClass::System.to_value()), + (Attribute::Class, EntryClass::KeyObject.to_value()), + (Attribute::Class, EntryClass::KeyObjectJwtEs256.to_value()), + (Attribute::Class, EntryClass::KeyObjectJweA128GCM.to_value()), + (Attribute::Name, Value::new_iname("domain_local")), + (Attribute::Uuid, Value::Uuid(UUID_DOMAIN_INFO)), + ( + Attribute::Description, + Value::new_utf8s("This local domain's info and metadata object.") + ) + ); + pub static ref E_SYSTEM_CONFIG_V1: EntryInitNew = entry_init!( + (Attribute::Class, EntryClass::Object.to_value()), + (Attribute::Class, EntryClass::SystemConfig.to_value()), + (Attribute::Class, EntryClass::System.to_value()), + (Attribute::Uuid, Value::Uuid(UUID_SYSTEM_CONFIG)), + ( + Attribute::Description, + Value::new_utf8s("System (replicated) configuration options.") + ), + ( + Attribute::BadlistPassword, + Value::new_iutf8("bad@no3IBTyqHu$list") + ), + ( + Attribute::BadlistPassword, + Value::new_iutf8( + "demo_badlist_shohfie3aeci2oobur0aru9uushah6EiPi2woh4hohngoighaiRuepieN3ongoo1" + ) + ), + ( + Attribute::BadlistPassword, + Value::new_iutf8("100preteamare") + ), + (Attribute::BadlistPassword, Value::new_iutf8("14defebrero")), + (Attribute::BadlistPassword, Value::new_iutf8("1life1love")), + (Attribute::BadlistPassword, Value::new_iutf8("1life2live")), + (Attribute::BadlistPassword, Value::new_iutf8("1love1life")), + (Attribute::BadlistPassword, Value::new_iutf8("1love4life")), + (Attribute::BadlistPassword, Value::new_iutf8("212224236248")), + (Attribute::BadlistPassword, Value::new_iutf8("2813308004")), + ( + Attribute::BadlistPassword, + Value::new_iutf8("2fast2furious") + ), + (Attribute::BadlistPassword, Value::new_iutf8("2gether4ever")), + (Attribute::BadlistPassword, Value::new_iutf8("2pacshakur")), + ( + Attribute::BadlistPassword, + Value::new_iutf8("30secondstomars") + ), + (Attribute::BadlistPassword, Value::new_iutf8("3doorsdown")), + (Attribute::BadlistPassword, Value::new_iutf8("6cyclemind")), + ( + Attribute::BadlistPassword, + Value::new_iutf8("
), + EntryManager, +} + +#[derive(Clone, Debug, Default)] +/// Objects that are affected by the rules of this ACP. +pub enum BuiltinAcpTarget { + #[default] + None, + // Self, + Filter(ProtoFilter), + // MemberOf ( Uuid ), +} + +#[derive(Clone, Debug, Default)] +/// Built-in Access Control Profile definitions +pub struct BuiltinAcp { + classes: Vec, + pub name: &'static str, + uuid: Uuid, + description: &'static str, + receiver: BuiltinAcpReceiver, + target: BuiltinAcpTarget, + search_attrs: Vec, + modify_present_attrs: Vec, + modify_removed_attrs: Vec, + modify_classes: Vec, + create_classes: Vec, + create_attrs: Vec, +} + +impl From for EntryInitNew { + #[allow(clippy::panic)] + fn from(value: BuiltinAcp) -> Self { + let mut entry = EntryInitNew::default(); + + #[allow(clippy::panic)] + if value.name.is_empty() { + panic!("Builtin ACP has no name! {:?}", value); + } + #[allow(clippy::panic)] + if value.classes.is_empty() { + panic!("Builtin ACP has no classes! {:?}", value); + } + + value.classes.iter().for_each(|class| { + entry.add_ava(Attribute::Class, class.to_value()); + }); + + 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::Description, + [Value::new_utf8s(value.description)], + ); + + match &value.receiver { + #[allow(clippy::panic)] + BuiltinAcpReceiver::None => { + panic!("Builtin ACP has no receiver! {:?}", &value); + } + BuiltinAcpReceiver::Group(list) => { + entry.add_ava( + Attribute::Class, + EntryClass::AccessControlReceiverGroup.to_value(), + ); + for group in list { + entry.set_ava(Attribute::AcpReceiverGroup, [Value::Refer(*group)]); + } + } + BuiltinAcpReceiver::EntryManager => { + entry.add_ava( + Attribute::Class, + EntryClass::AccessControlReceiverEntryManager.to_value(), + ); + } + }; + + match &value.target { + #[allow(clippy::panic)] + BuiltinAcpTarget::None => { + panic!("Builtin ACP has no target! {:?}", &value); + } + BuiltinAcpTarget::Filter(proto_filter) => { + entry.add_ava( + Attribute::Class, + EntryClass::AccessControlTargetScope.to_value(), + ); + entry.set_ava( + Attribute::AcpTargetScope, + [Value::JsonFilt(proto_filter.clone())], + ); + } + } + + entry.set_ava( + Attribute::AcpSearchAttr, + value + .search_attrs + .into_iter() + .map(Value::from) + .collect::>(), + ); + value.modify_present_attrs.into_iter().for_each(|attr| { + entry.add_ava(Attribute::AcpModifyPresentAttr, Value::from(attr)); + }); + value.modify_removed_attrs.into_iter().for_each(|attr| { + entry.add_ava(Attribute::AcpModifyRemovedAttr, Value::from(attr)); + }); + value.modify_classes.into_iter().for_each(|class| { + entry.add_ava(Attribute::AcpModifyClass, Value::from(class)); + }); + value.create_classes.into_iter().for_each(|class| { + entry.add_ava(Attribute::AcpCreateClass, Value::from(class)); + }); + value.create_attrs.into_iter().for_each(|attr| { + entry.add_ava(Attribute::AcpCreateAttr, Value::from(attr)); + }); + entry + } +} + +lazy_static! { + pub static ref IDM_ACP_RECYCLE_BIN_SEARCH_V1: BuiltinAcp = BuiltinAcp { + uuid: UUID_IDM_ACP_RECYCLE_BIN_SEARCH_V1, + name: "idm_acp_recycle_bin_search", + description: "Builtin IDM recycle bin search permission.", + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_RECYCLE_BIN_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::Eq( + Attribute::Class.to_string(), + ATTR_RECYCLED.to_string() + )), + + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::LastModifiedCid, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_RECYCLE_BIN_REVIVE_V1: BuiltinAcp = BuiltinAcp { + uuid: UUID_IDM_ACP_RECYCLE_BIN_REVIVE_V1, + name: "idm_acp_recycle_bin_revive", + description: "Builtin IDM recycle bin revive permission.", + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_RECYCLE_BIN_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::Eq( + Attribute::Class.to_string(), + ATTR_RECYCLED.to_string() + )), + modify_removed_attrs: vec![Attribute::Class], + modify_classes: vec![EntryClass::Recycled], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SCHEMA_WRITE_ATTRS_V1: BuiltinAcp = BuiltinAcp{ + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_schema_write_attrs", + uuid: UUID_IDM_ACP_SCHEMA_WRITE_ATTRS_V1, + description: "Builtin IDM Control for management of schema attributes.", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_SCHEMA_ADMINS] ), + // has a class, and isn't recycled/tombstoned + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + ProtoFilter::Eq(EntryClass::Class.to_string(),EntryClass::AttributeType.to_string()), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::Index, + Attribute::Unique, + Attribute::MultiValue, + Attribute::AttributeName, + Attribute::Syntax, + Attribute::Uuid, + ], + modify_removed_attrs: vec![ + Attribute::Description, + Attribute::Index, + Attribute::Unique, + Attribute::MultiValue, + Attribute::Syntax, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::Index, + Attribute::Unique, + Attribute::MultiValue, + Attribute::Syntax, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::Index, + Attribute::Unique, + Attribute::MultiValue, + Attribute::AttributeName, + Attribute::Syntax, + Attribute::Uuid, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::AttributeType, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SCHEMA_WRITE_CLASSES_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_schema_write_classes", + uuid: UUID_IDM_ACP_SCHEMA_WRITE_CLASSES_V1, + description: "Builtin IDM Control for management of schema classes.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_SCHEMA_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + EntryClass::Class.to_string(), + EntryClass::ClassType.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::ClassName, + Attribute::Description, + Attribute::SystemMay, + Attribute::May, + Attribute::SystemMust, + Attribute::Must, + Attribute::Uuid, + ], + modify_removed_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::May, + Attribute::Must, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::May, + Attribute::Must, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::ClassName, + Attribute::Description, + Attribute::May, + Attribute::Must, + Attribute::Uuid, + ], + create_classes: vec![EntryClass::Object, EntryClass::ClassType,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_ACP_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_acp_manage", + uuid: UUID_IDM_ACP_ACP_MANAGE_V1, + description: "Builtin IDM Control for access profiles management.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ACCESS_CONTROL_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + EntryClass::Class.to_string(), + EntryClass::AccessControlProfile.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Description, + Attribute::AcpEnable, + Attribute::AcpReceiverGroup, + Attribute::AcpTargetScope, + Attribute::AcpSearchAttr, + Attribute::AcpModifyRemovedAttr, + Attribute::AcpModifyPresentAttr, + Attribute::AcpModifyClass, + Attribute::AcpCreateClass, + Attribute::AcpCreateAttr, + ], + modify_removed_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Description, + Attribute::AcpEnable, + Attribute::AcpReceiverGroup, + Attribute::AcpTargetScope, + Attribute::AcpSearchAttr, + Attribute::AcpModifyRemovedAttr, + Attribute::AcpModifyPresentAttr, + Attribute::AcpModifyClass, + Attribute::AcpCreateClass, + Attribute::AcpCreateAttr, + ], + modify_present_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Description, + Attribute::AcpEnable, + Attribute::AcpReceiverGroup, + Attribute::AcpTargetScope, + Attribute::AcpSearchAttr, + Attribute::AcpModifyRemovedAttr, + Attribute::AcpModifyPresentAttr, + Attribute::AcpModifyClass, + Attribute::AcpCreateClass, + Attribute::AcpCreateAttr, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Description, + Attribute::AcpEnable, + Attribute::AcpReceiverGroup, + Attribute::AcpTargetScope, + Attribute::AcpSearchAttr, + Attribute::AcpModifyRemovedAttr, + Attribute::AcpModifyPresentAttr, + Attribute::AcpModifyClass, + Attribute::AcpCreateClass, + Attribute::AcpCreateAttr, + ], + modify_classes: vec![ + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + EntryClass::AccessControlModify, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + ], + create_classes: vec![ + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + EntryClass::AccessControlModify, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + ], + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_READ_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_read", + uuid: UUID_IDM_ACP_GROUP_READ, + description: + "Builtin IDM Control for allowing all groups to be read by access control admins", + receiver: BuiltinAcpReceiver::Group(vec![ + UUID_IDM_ACCESS_CONTROL_ADMINS, + // UUID_IDM_SERVICE_DESK, + // UUID_IDM_PEOPLE_ADMINS, + ]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::DynMember, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::Description, + Attribute::Member, + Attribute::EntryManagedBy, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_ENTRY_MANAGED_BY_MODIFY_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_entry_managed_by_modify", + uuid: UUID_IDM_ACP_GROUP_ENTRY_MANAGED_BY_MODIFY, + description: "Builtin IDM Control for allowing entry_managed_by to be set on group entries", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ACCESS_CONTROL_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::Uuid, + Attribute::EntryManagedBy, + ], + modify_removed_attrs: vec![Attribute::EntryManagedBy], + modify_present_attrs: vec![Attribute::EntryManagedBy], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE_DL6: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_account_policy_manage", + uuid: UUID_IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE, + description: "Builtin IDM Control for management of account policy on groups", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ACCOUNT_POLICY_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::AuthSessionExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::PrivilegeExpiry, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + ], + modify_removed_attrs: vec![ + Attribute::Class, + Attribute::AuthSessionExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::PrivilegeExpiry, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + ], + modify_present_attrs: vec![ + Attribute::Class, + Attribute::AuthSessionExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::PrivilegeExpiry, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + ], + modify_classes: vec![EntryClass::AccountPolicy,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE_DL8: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_account_policy_manage", + uuid: UUID_IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE, + description: "Builtin IDM Control for management of account policy on groups", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ACCOUNT_POLICY_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::AuthSessionExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::PrivilegeExpiry, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + Attribute::AllowPrimaryCredFallback, + ], + modify_removed_attrs: vec![ + Attribute::Class, + Attribute::AuthSessionExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::PrivilegeExpiry, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + Attribute::AllowPrimaryCredFallback, + ], + modify_present_attrs: vec![ + Attribute::Class, + Attribute::AuthSessionExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::PrivilegeExpiry, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + Attribute::AllowPrimaryCredFallback, + ], + modify_classes: vec![EntryClass::AccountPolicy,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_OAUTH2_MANAGE_DL4: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_hp_oauth2_manage_priv", + uuid: UUID_IDM_ACP_OAUTH2_MANAGE_V1, + description: "Builtin IDM Control for managing oauth2 resource server integrations.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_OAUTH2_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::OAuth2ResourceServer), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + modify_removed_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::OAuth2ResourceServer, + EntryClass::OAuth2ResourceServerBasic, + EntryClass::OAuth2ResourceServerPublic, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_OAUTH2_MANAGE_DL5: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_hp_oauth2_manage_priv", + uuid: UUID_IDM_ACP_OAUTH2_MANAGE_V1, + description: "Builtin IDM Control for managing oauth2 resource server integrations.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_OAUTH2_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::OAuth2ResourceServer), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::Spn, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + modify_removed_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::Name, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Account, + EntryClass::OAuth2ResourceServer, + EntryClass::OAuth2ResourceServerBasic, + EntryClass::OAuth2ResourceServerPublic, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_OAUTH2_MANAGE_DL7: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_hp_oauth2_manage_priv", + uuid: UUID_IDM_ACP_OAUTH2_MANAGE_V1, + description: "Builtin IDM Control for managing oauth2 resource server integrations.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_OAUTH2_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::OAuth2ResourceServer), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::Spn, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + ], + modify_removed_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::Name, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Account, + EntryClass::OAuth2ResourceServer, + EntryClass::OAuth2ResourceServerBasic, + EntryClass::OAuth2ResourceServerPublic, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_OAUTH2_MANAGE_DL9: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_oauth2_manage", + uuid: UUID_IDM_ACP_OAUTH2_MANAGE_V1, + description: "Builtin IDM Control for managing OAuth2 resource server integrations.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_OAUTH2_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::OAuth2ResourceServer), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::Spn, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + Attribute::OAuth2DeviceFlowEnable, + ], + modify_removed_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + Attribute::OAuth2DeviceFlowEnable, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + Attribute::OAuth2DeviceFlowEnable, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::Name, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + Attribute::OAuth2DeviceFlowEnable, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Account, + EntryClass::OAuth2ResourceServer, + EntryClass::OAuth2ResourceServerBasic, + EntryClass::OAuth2ResourceServerPublic, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_DOMAIN_ADMIN_DL6: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_domain_admin", + uuid: UUID_IDM_ACP_DOMAIN_ADMIN_V1, + description: "Builtin IDM Control for granting domain info administration locally", + receiver: BuiltinAcpReceiver::Group(vec![UUID_DOMAIN_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + Attribute::Uuid.to_string(), + STR_UUID_DOMAIN_INFO.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::DomainDisplayName, + Attribute::DomainName, + Attribute::DomainLdapBasedn, + Attribute::DomainSsid, + Attribute::DomainUuid, + // Grants read access to the key object. + // But this means we have to specify every type of key object? + // Future william problem ... + Attribute::KeyInternalData, + Attribute::LdapAllowUnixPwBind, + Attribute::Version, + ], + modify_removed_attrs: vec![ + Attribute::DomainDisplayName, + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::LdapAllowUnixPwBind, + Attribute::KeyActionRevoke, + Attribute::KeyActionRotate, + ], + modify_present_attrs: vec![ + Attribute::DomainDisplayName, + Attribute::DomainLdapBasedn, + Attribute::DomainSsid, + Attribute::LdapAllowUnixPwBind, + Attribute::KeyActionRevoke, + Attribute::KeyActionRotate, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_DOMAIN_ADMIN_DL8: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_domain_admin", + uuid: UUID_IDM_ACP_DOMAIN_ADMIN_V1, + description: "Builtin IDM Control for granting domain info administration locally", + receiver: BuiltinAcpReceiver::Group(vec![UUID_DOMAIN_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + Attribute::Uuid.to_string(), + STR_UUID_DOMAIN_INFO.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::DomainDisplayName, + Attribute::DomainName, + Attribute::DomainLdapBasedn, + Attribute::DomainSsid, + Attribute::DomainUuid, + Attribute::KeyInternalData, + Attribute::LdapAllowUnixPwBind, + Attribute::Version, + Attribute::Image, + ], + modify_removed_attrs: vec![ + Attribute::DomainDisplayName, + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::LdapAllowUnixPwBind, + Attribute::KeyActionRevoke, + Attribute::KeyActionRotate, + Attribute::Image, + ], + modify_present_attrs: vec![ + Attribute::DomainDisplayName, + Attribute::DomainLdapBasedn, + Attribute::DomainSsid, + Attribute::LdapAllowUnixPwBind, + Attribute::KeyActionRevoke, + Attribute::KeyActionRotate, + Attribute::Image, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_DOMAIN_ADMIN_DL9: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_domain_admin", + uuid: UUID_IDM_ACP_DOMAIN_ADMIN_V1, + description: "Builtin IDM Control for granting domain info administration locally", + receiver: BuiltinAcpReceiver::Group(vec![UUID_DOMAIN_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + Attribute::Uuid.to_string(), + STR_UUID_DOMAIN_INFO.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::DomainAllowEasterEggs, + Attribute::DomainDisplayName, + Attribute::DomainName, + Attribute::DomainLdapBasedn, + Attribute::DomainSsid, + Attribute::DomainUuid, + Attribute::KeyInternalData, + Attribute::LdapAllowUnixPwBind, + Attribute::Version, + Attribute::Image, + ], + modify_removed_attrs: vec![ + Attribute::DomainDisplayName, + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::DomainAllowEasterEggs, + Attribute::LdapAllowUnixPwBind, + Attribute::KeyActionRevoke, + Attribute::KeyActionRotate, + Attribute::Image, + ], + modify_present_attrs: vec![ + Attribute::DomainDisplayName, + Attribute::DomainLdapBasedn, + Attribute::DomainSsid, + Attribute::DomainAllowEasterEggs, + Attribute::LdapAllowUnixPwBind, + Attribute::KeyActionRevoke, + Attribute::KeyActionRotate, + Attribute::Image, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SYNC_ACCOUNT_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch, + ], + name: "idm_acp_sync_account_manage", + uuid: UUID_IDM_ACP_SYNC_ACCOUNT_MANAGE_V1, + description: "Builtin IDM Control for managing IDM synchronisation accounts / connections", + receiver: BuiltinAcpReceiver::Group(vec![UUID_DOMAIN_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + Attribute::Class.to_string(), + EntryClass::SyncAccount.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Name, + Attribute::Description, + Attribute::JwsEs256PrivateKey, + Attribute::SyncTokenSession, + Attribute::SyncCredentialPortal, + Attribute::SyncYieldAuthority, + Attribute::SyncCookie, + ], + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::JwsEs256PrivateKey, + Attribute::SyncTokenSession, + Attribute::SyncCredentialPortal, + Attribute::SyncCookie, + Attribute::SyncYieldAuthority, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::SyncTokenSession, + Attribute::SyncCredentialPortal, + Attribute::SyncYieldAuthority, + ], + create_attrs: vec![Attribute::Class, Attribute::Name, Attribute::Description,], + create_classes: vec![EntryClass::Object, EntryClass::SyncAccount,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_ENTRY_MANAGER_V1: BuiltinAcp = BuiltinAcp{ + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_entry_manager", + uuid: UUID_IDM_ACP_GROUP_ENTRY_MANAGER_V1, + description: "Builtin IDM Control for allowing EntryManager to read and modify groups", + receiver: BuiltinAcpReceiver::EntryManager, + // Any group + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::Uuid, + Attribute::Description, + Attribute::Member, + Attribute::DynMember, + Attribute::EntryManagedBy, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::Member, + ], + modify_removed_attrs: vec![ + Attribute::Description, + Attribute::Member, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_RADIUS_SERVERS_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + name: "idm_acp_radius_servers", + uuid: UUID_IDM_ACP_RADIUS_SERVERS_V1, + description: + "Builtin IDM Control for RADIUS servers to read credentials and other needed details.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_RADIUS_SERVERS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Pres(EntryClass::Class.to_string()), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::Uuid, + Attribute::RadiusSecret, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_RADIUS_SECRET_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch, + ], + name: "idm_acp_radius_secret_manage", + uuid: UUID_IDM_ACP_RADIUS_SECRET_MANAGE_V1, + description: "Builtin IDM Control allowing reads and writes to user radius secrets.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_RADIUS_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Account), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![Attribute::RadiusSecret], + modify_present_attrs: vec![Attribute::RadiusSecret], + modify_removed_attrs: vec![Attribute::RadiusSecret], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_MAIL_SERVERS_DL8: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + name: "idm_acp_mail_servers", + uuid: UUID_IDM_ACP_MAIL_SERVERS, + description: + "Builtin IDM Control for MAIL servers to read email addresses and other needed attributes.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_MAIL_SERVERS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Or(vec![ + match_class_filter!(EntryClass::Account), + match_class_filter!(EntryClass::Group), + ]), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::Uuid, + Attribute::DisplayName, + Attribute::Mail, + Attribute::Member, + Attribute::DynMember, + Attribute::MemberOf, + Attribute::GidNumber, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_PEOPLE_SELF_WRITE_MAIL_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + name: "idm_acp_people_self_write_mail", + uuid: UUID_IDM_ACP_PEOPLE_SELF_WRITE_MAIL, + description: "Builtin IDM Control for self write of mail for people accounts.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_PEOPLE_SELF_MAIL_WRITE]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person).clone(), + match_class_filter!(EntryClass::Account).clone(), + ProtoFilter::SelfUuid, + ])), + modify_removed_attrs: vec![Attribute::Mail], + modify_present_attrs: vec![Attribute::Mail], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SELF_READ_V1: BuiltinAcp = BuiltinAcp { + name: "idm_acp_self_read", + uuid: UUID_IDM_ACP_SELF_READ, + description: + "Builtin IDM Control for self read - required for whoami and many other functions", + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ALL_ACCOUNTS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::SelfUuid), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::DisplayName, + Attribute::LegalName, + Attribute::Class, + Attribute::MemberOf, + Attribute::Mail, + Attribute::RadiusSecret, + Attribute::GidNumber, + Attribute::LoginShell, + Attribute::Uuid, + Attribute::SyncParentUuid, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::PrimaryCredential, + Attribute::UserAuthTokenSession, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SELF_READ_DL8: BuiltinAcp = BuiltinAcp { + name: "idm_acp_self_read", + uuid: UUID_IDM_ACP_SELF_READ, + description: + "Builtin IDM Control for self read - required for whoami and many other functions", + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ALL_ACCOUNTS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::SelfUuid), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::DisplayName, + Attribute::LegalName, + Attribute::Class, + Attribute::MemberOf, + Attribute::Mail, + Attribute::RadiusSecret, + Attribute::GidNumber, + Attribute::LoginShell, + Attribute::Uuid, + Attribute::SyncParentUuid, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::PrimaryCredential, + Attribute::UserAuthTokenSession, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::ApplicationPassword, + Attribute::SshPublicKey, + Attribute::UnixPassword, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SELF_WRITE_V1: BuiltinAcp = BuiltinAcp{ + name: "idm_acp_self_write", + uuid: UUID_IDM_ACP_SELF_WRITE_V1, + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + description: "Builtin IDM Control for self write - required for people to update their own identities and credentials in line with best practices.", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_ALL_PERSONS] ), + target: BuiltinAcpTarget::Filter(ProtoFilter::SelfUuid), + modify_removed_attrs: vec![ + Attribute::DisplayName, + Attribute::LegalName, + Attribute::RadiusSecret, + Attribute::PrimaryCredential, + Attribute::SshPublicKey, + Attribute::UnixPassword, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::UserAuthTokenSession, + Attribute::ApplicationPassword, + ], + modify_present_attrs: vec![ + Attribute::DisplayName, + Attribute::LegalName, + Attribute::RadiusSecret, + Attribute::PrimaryCredential, + Attribute::SshPublicKey, + Attribute::UnixPassword, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::ApplicationPassword, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SELF_WRITE_DL7: BuiltinAcp = BuiltinAcp{ + name: "idm_acp_self_write", + uuid: UUID_IDM_ACP_SELF_WRITE_V1, + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + description: "Builtin IDM Control for self write - required for people to update their own credentials in line with best practices.", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_ALL_PERSONS] ), + target: BuiltinAcpTarget::Filter(ProtoFilter::SelfUuid), + modify_removed_attrs: vec![ + Attribute::RadiusSecret, + Attribute::PrimaryCredential, + Attribute::SshPublicKey, + Attribute::UnixPassword, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::UserAuthTokenSession, + ], + modify_present_attrs: vec![ + Attribute::RadiusSecret, + Attribute::PrimaryCredential, + Attribute::SshPublicKey, + Attribute::UnixPassword, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SELF_WRITE_DL8: BuiltinAcp = BuiltinAcp{ + name: "idm_acp_self_write", + uuid: UUID_IDM_ACP_SELF_WRITE_V1, + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + description: "Builtin IDM Control for self write - required for people to update their own credentials in line with best practices.", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_ALL_PERSONS] ), + target: BuiltinAcpTarget::Filter(ProtoFilter::SelfUuid), + modify_removed_attrs: vec![ + Attribute::RadiusSecret, + Attribute::PrimaryCredential, + Attribute::SshPublicKey, + Attribute::UnixPassword, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::UserAuthTokenSession, + Attribute::ApplicationPassword, + ], + modify_present_attrs: vec![ + Attribute::RadiusSecret, + Attribute::PrimaryCredential, + Attribute::SshPublicKey, + Attribute::UnixPassword, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::ApplicationPassword, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SELF_NAME_WRITE_V1: BuiltinAcp = BuiltinAcp{ + name: "idm_acp_self_name_write", + uuid: UUID_IDM_ACP_SELF_NAME_WRITE_V1, + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + description: "Builtin IDM Control for self write of name - required for people to update their own identities in line with best practices.", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_ALL_PERSONS] ), + target: BuiltinAcpTarget::Filter(ProtoFilter::SelfUuid), + modify_removed_attrs: vec![ + Attribute::Name, + ], + modify_present_attrs: vec![ + Attribute::Name, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SELF_NAME_WRITE_DL7: BuiltinAcp = BuiltinAcp{ + name: "idm_acp_self_name_write", + uuid: UUID_IDM_ACP_SELF_NAME_WRITE_V1, + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + description: "Builtin IDM Control for self write of name - required for people to update their own identities in line with best practices.", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_PEOPLE_SELF_NAME_WRITE] ), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::SelfUuid, + match_class_filter!(EntryClass::Person).clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::DisplayName, + Attribute::LegalName, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::DisplayName, + Attribute::LegalName, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_ACCOUNT_SELF_WRITE_V1: BuiltinAcp = BuiltinAcp { + name: "idm_acp_account_self_write", + uuid: UUID_IDM_ACP_ACCOUNT_SELF_WRITE_V1, + description: "Builtin IDM Control for self write - required for accounts to update their own session state.", + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify + ], + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_ALL_ACCOUNTS] ), + target: BuiltinAcpTarget::Filter(ProtoFilter::SelfUuid), + modify_removed_attrs: vec![ + Attribute::UserAuthTokenSession + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_ALL_ACCOUNTS_POSIX_READ_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + name: "idm_acp_all_accounts_posix_read", + uuid: UUID_IDM_ACP_ALL_ACCOUNTS_POSIX_READ_V1, + description: + "Builtin IDM Control for reading minimal posix attrs - applies anonymous and all authenticated accounts.", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_ALL_ACCOUNTS] ), + target: BuiltinAcpTarget::Filter( ProtoFilter::And( + vec![ + ProtoFilter::Or(vec![ + match_class_filter!(EntryClass::Account), + match_class_filter!(EntryClass::Group), + ]), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ] + )), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::DisplayName, + Attribute::Class, + Attribute::MemberOf, + Attribute::Member, + Attribute::DynMember, + Attribute::Uuid, + Attribute::GidNumber, + Attribute::LoginShell, + Attribute::SshPublicKey, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_ACCOUNT_MAIL_READ_DL6: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch + ], + name: "idm_acp_account_mail_read", + uuid: UUID_IDM_ACP_ACCOUNT_MAIL_READ_V1, + description: "Builtin IDM Control for reading account and group mail attributes.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ACCOUNT_MAIL_READ]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Or(vec![ + match_class_filter!(EntryClass::Account), + match_class_filter!(EntryClass::Group), + ]), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![Attribute::Mail], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SYSTEM_CONFIG_ACCOUNT_POLICY_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_system_config_account_policy_manage", + uuid: UUID_IDM_ACP_SYSTEM_CONFIG_ACCOUNT_POLICY_MANAGE_V1, + description: "Builtin IDM Control for granting system configuration of account policy", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ACCOUNT_POLICY_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + Attribute::Uuid.to_string(), + STR_UUID_SYSTEM_CONFIG.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Description, + Attribute::BadlistPassword, + Attribute::DeniedName, + Attribute::AuthSessionExpiry, + Attribute::PrivilegeExpiry, + Attribute::Version, + ], + modify_removed_attrs: vec![ + Attribute::BadlistPassword, + Attribute::DeniedName, + Attribute::AuthSessionExpiry, + Attribute::PrivilegeExpiry, + ], + modify_present_attrs: vec![ + Attribute::BadlistPassword, + Attribute::DeniedName, + Attribute::AuthSessionExpiry, + Attribute::PrivilegeExpiry, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_HP_GROUP_UNIX_MANAGE_V1: BuiltinAcp = BuiltinAcp{ + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_hp_group_unix_manage", + uuid: UUID_IDM_ACP_HP_GROUP_UNIX_MANAGE_V1, + description: "Builtin IDM Control for managing and extending high privilege groups with unix attributes", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_UNIX_ADMINS] ), + // HP group, not Recycled/Tombstone + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_HP.clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::DynMember, + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::Description, + Attribute::Member, + Attribute::GidNumber, + ], + modify_removed_attrs: vec![ + Attribute::GidNumber, + ], + modify_present_attrs: vec![ + Attribute::Class, + Attribute::GidNumber, + ], + modify_classes: vec![ + EntryClass::PosixGroup, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_MANAGE_DL6: BuiltinAcp = BuiltinAcp{ + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_manage", + uuid: UUID_IDM_ACP_GROUP_MANAGE_V1, + description: "Builtin IDM Control for creating and deleting groups in the directory", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_GROUP_ADMINS] ), + // group which is not in HP, Recycled, Tombstone + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::Uuid, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + Attribute::DynMember, + Attribute::EntryManagedBy, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + Attribute::EntryManagedBy, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Group, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + ], + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_MANAGE_DL9: BuiltinAcp = BuiltinAcp{ + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_manage", + uuid: UUID_IDM_ACP_GROUP_MANAGE_V1, + description: "Builtin IDM Control for creating and deleting groups in the directory", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_GROUP_ADMINS] ), + // group which is not in HP, Recycled, Tombstone + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::Uuid, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + Attribute::DynMember, + Attribute::EntryManagedBy, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + Attribute::EntryManagedBy, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Group, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + Attribute::EntryManagedBy, + ], + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::Mail, + Attribute::Member, + Attribute::EntryManagedBy, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_GROUP_UNIX_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_group_unix_manage", + uuid: UUID_IDM_ACP_GROUP_UNIX_MANAGE_V1, + description: "Builtin IDM Control for managing unix groups", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_UNIX_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Group), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + search_attrs: vec![ + Attribute::DynMember, + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::Description, + Attribute::Member, + Attribute::GidNumber, + ], + modify_removed_attrs: vec![Attribute::GidNumber,], + modify_present_attrs: vec![Attribute::Class, Attribute::GidNumber,], + modify_classes: vec![EntryClass::PosixGroup,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_ACCOUNT_UNIX_EXTEND_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_account_unix_extend", + uuid: UUID_IDM_ACP_ACCOUNT_UNIX_EXTEND_V1, + description: "Builtin IDM Control for managing and extending unix accounts", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_UNIX_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Account), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::Description, + Attribute::GidNumber, + Attribute::LoginShell, + Attribute::UnixPassword, + Attribute::SshPublicKey, + ], + modify_removed_attrs: vec![ + Attribute::GidNumber, + Attribute::LoginShell, + Attribute::UnixPassword, + Attribute::SshPublicKey, + ], + modify_present_attrs: vec![ + Attribute::Class, + Attribute::GidNumber, + Attribute::LoginShell, + Attribute::UnixPassword, + Attribute::SshPublicKey, + ], + modify_classes: vec![EntryClass::PosixAccount,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_PEOPLE_PII_READ_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + name: "idm_acp_people_pii_read", + uuid: UUID_IDM_ACP_PEOPLE_PII_READ_V1, + description: "Builtin IDM Control for reading personal and sensitive data.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_PEOPLE_ADMINS, UUID_IDM_PEOPLE_PII_READ]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person).clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Uuid, + Attribute::Spn, + Attribute::DisplayName, + Attribute::LegalName, + Attribute::Mail, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_PEOPLE_PII_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify + ], + name: "idm_acp_people_pii_manage", + uuid: UUID_IDM_ACP_PEOPLE_PII_MANAGE_V1, + description: "Builtin IDM Control for modifying peoples personal and sensitive data", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_PEOPLE_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::DisplayName, + Attribute::LegalName, + Attribute::Mail, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::DisplayName, + Attribute::LegalName, + Attribute::Mail, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_PEOPLE_CREATE_DL6: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + ], + name: "idm_acp_people_create", + uuid: UUID_IDM_ACP_PEOPLE_CREATE_V1, + description: "Builtin IDM Control for creating new persons.", + receiver: BuiltinAcpReceiver::Group(vec![ + UUID_IDM_PEOPLE_ADMINS, + UUID_IDM_PEOPLE_ON_BOARDING + ]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person).clone(), + match_class_filter!(EntryClass::Account).clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + create_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Name, + Attribute::DisplayName, + Attribute::Mail, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + ], + create_classes: vec![EntryClass::Object, EntryClass::Account, EntryClass::Person,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_PEOPLE_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + ], + name: "idm_acp_people_manage", + uuid: UUID_IDM_ACP_PEOPLE_MANAGE_V1, + description: "Builtin IDM Control for management of peoples non sensitive attributes.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_PEOPLE_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person), + match_class_filter!(EntryClass::Account), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + modify_removed_attrs: vec![Attribute::AccountExpire, Attribute::AccountValidFrom,], + modify_present_attrs: vec![Attribute::AccountExpire, Attribute::AccountValidFrom,], + ..Default::default() + }; +} + +// Person Read +lazy_static! { + pub static ref IDM_ACP_PEOPLE_READ_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlSearch, + ], + name: "idm_acp_people_read", + uuid: UUID_IDM_ACP_PEOPLE_READ_V1, + description: "Builtin IDM Control for reading non-sensitive data.", + receiver: BuiltinAcpReceiver::Group(vec![ + UUID_IDM_PEOPLE_ADMINS, + UUID_IDM_PEOPLE_PII_READ, + UUID_IDM_ACCOUNT_MAIL_READ, + UUID_IDM_SERVICE_DESK + ]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person).clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::Uuid, + Attribute::DisplayName, + Attribute::MemberOf, + Attribute::Uuid, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + ], + ..Default::default() + }; +} + +// Person Delete +lazy_static! { + pub static ref IDM_ACP_PEOPLE_DELETE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlDelete, + ], + name: "idm_acp_people_delete", + uuid: UUID_IDM_ACP_PEOPLE_DELETE_V1, + description: "Builtin IDM Control for deleting persons.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_PEOPLE_ADMINS,]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person).clone(), + match_class_filter!(EntryClass::Account).clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + ..Default::default() + }; +} + +// Person Account Credential Reset +lazy_static! { + pub static ref IDM_ACP_PEOPLE_CREDENTIAL_RESET_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_people_credential_reset", + uuid: UUID_IDM_ACP_PEOPLE_CREDENTIAL_RESET_V1, + description: "Builtin IDM Control for resetting peoples credentials ", + receiver: BuiltinAcpReceiver::Group(vec![ + UUID_IDM_PEOPLE_ADMINS, + UUID_IDM_SERVICE_DESK, + UUID_IDM_PEOPLE_ON_BOARDING, + ]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person), + match_class_filter!(EntryClass::Account), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Name, + Attribute::Spn, + Attribute::PrimaryCredential, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + modify_removed_attrs: vec![ + Attribute::PrimaryCredential, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + modify_present_attrs: vec![ + Attribute::PrimaryCredential, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + ..Default::default() + }; +} + +// HP Person Account Credential Reset +lazy_static! { + pub static ref IDM_ACP_HP_PEOPLE_CREDENTIAL_RESET_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_hp_people_credential_reset", + uuid: UUID_IDM_ACP_HP_PEOPLE_CREDENTIAL_RESET_V1, + description: "Builtin IDM Control for resetting high privilege peoples credentials ", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_PEOPLE_ADMINS,]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Person), + match_class_filter!(EntryClass::Account), + FILTER_HP.clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Name, + Attribute::Spn, + Attribute::PrimaryCredential, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + modify_removed_attrs: vec![ + Attribute::PrimaryCredential, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + modify_present_attrs: vec![ + Attribute::PrimaryCredential, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + ], + ..Default::default() + }; +} + +// Service Account Create/Manage +// needs to be able to assign to entry managed by +lazy_static! { + pub static ref IDM_ACP_SERVICE_ACCOUNT_CREATE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + ], + name: "idm_acp_service_account_create", + uuid: UUID_IDM_ACP_SERVICE_ACCOUNT_CREATE_V1, + description: "Builtin IDM Control for creating new service accounts.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_SERVICE_ACCOUNT_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::ServiceAccount).clone(), + match_class_filter!(EntryClass::Account).clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + create_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::DisplayName, + Attribute::EntryManagedBy, + Attribute::Description, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Account, + EntryClass::ServiceAccount, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SERVICE_ACCOUNT_MANAGE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify + ], + name: "idm_acp_service_account_manage", + uuid: UUID_IDM_ACP_SERVICE_ACCOUNT_MANAGE_V1, + description: "Builtin IDM Control for modifying service account data", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_SERVICE_ACCOUNT_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::ServiceAccount).clone(), + match_class_filter!(EntryClass::Account).clone(), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::DisplayName, + Attribute::Mail, + Attribute::SshPublicKey, + Attribute::UnixPassword, + Attribute::PrimaryCredential, + Attribute::ApiTokenSession, + Attribute::UserAuthTokenSession, + ], + modify_present_attrs: vec![Attribute::Name, Attribute::DisplayName, Attribute::Mail,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_SERVICE_ACCOUNT_DELETE_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlDelete, + ], + name: "idm_acp_service_account_delete", + uuid: UUID_IDM_ACP_SERVICE_ACCOUNT_DELETE_V1, + description: "Builtin IDM Control for deleting service accounts.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_SERVICE_ACCOUNT_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::ServiceAccount).clone(), + match_class_filter!(EntryClass::Account).clone(), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + ..Default::default() + }; +} + +// Service Account Credential Manage +// entry managed by? + +lazy_static! { + pub static ref IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGER_V1: BuiltinAcp = BuiltinAcp{ + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_service_account_entry_manager", + uuid: UUID_IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGER_V1, + description: "Builtin IDM Control for allowing entry managers to modify service accounts", + receiver: BuiltinAcpReceiver::EntryManager, + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Account), + match_class_filter!(EntryClass::ServiceAccount), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::Uuid, + Attribute::EntryManagedBy, + Attribute::DisplayName, + Attribute::SshPublicKey, + Attribute::GidNumber, + Attribute::LoginShell, + Attribute::UnixPassword, + Attribute::PassKeys, + Attribute::PrimaryCredential, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::ApiTokenSession, + Attribute::UserAuthTokenSession, + ], + modify_removed_attrs: vec![ + Attribute::DisplayName, + Attribute::SshPublicKey, + Attribute::PrimaryCredential, + Attribute::UnixPassword, + // For legacy upgrades we allow removing this. + Attribute::PassKeys, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::ApiTokenSession, + Attribute::UserAuthTokenSession, + ], + modify_present_attrs: vec![ + Attribute::DisplayName, + Attribute::SshPublicKey, + Attribute::PrimaryCredential, + // Should this be a thing? I think no? + // Attribute::UnixPassword, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::ApiTokenSession, + ], + ..Default::default() + }; +} + +// Service Account Access Manager +lazy_static! { + pub static ref IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_service_account_entry_managed_by_modify", + uuid: UUID_IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY, + description: + "Builtin IDM Control for allowing entry_managed_by to be set on service account entries", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_SERVICE_ACCOUNT_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::ServiceAccount).clone(), + match_class_filter!(EntryClass::Account).clone(), + FILTER_ANDNOT_HP_OR_RECYCLED_OR_TOMBSTONE.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::Uuid, + Attribute::EntryManagedBy, + ], + modify_removed_attrs: vec![Attribute::EntryManagedBy], + modify_present_attrs: vec![Attribute::EntryManagedBy], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_HP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_hp_service_account_entry_managed_by", + uuid: UUID_IDM_ACP_HP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY, + description: "Builtin IDM Control for allowing entry_managed_by to be set on high priv service account entries", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_ACCESS_CONTROL_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + match_class_filter!(EntryClass::ServiceAccount).clone(), + match_class_filter!(EntryClass::Account).clone(), + FILTER_HP.clone(), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone(), + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Name, + Attribute::Spn, + Attribute::Uuid, + Attribute::EntryManagedBy, + ], + modify_removed_attrs: vec![Attribute::EntryManagedBy], + modify_present_attrs: vec![Attribute::EntryManagedBy], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_HP_CLIENT_CERTIFICATE_MANAGER_DL7: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_hp_client_certificate_manager", + uuid: UUID_IDM_ACP_HP_CLIENT_CERTIFICATE_MANAGER, + description: "Builtin IDM Control for allowing client certificate management.", + receiver: BuiltinAcpReceiver::Group(vec![UUID_IDM_CLIENT_CERTIFICATE_ADMINS]), + target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![ + ProtoFilter::Eq( + EntryClass::Class.to_string(), + EntryClass::ClientCertificate.to_string() + ), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Certificate, + Attribute::Refers, + ], + modify_removed_attrs: vec![Attribute::Certificate, Attribute::Refers,], + modify_present_attrs: vec![Attribute::Certificate, Attribute::Refers,], + create_attrs: vec![Attribute::Class, Attribute::Certificate, Attribute::Refers,], + create_classes: vec![EntryClass::Object, EntryClass::ClientCertificate,], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_APPLICATION_MANAGE_DL8: BuiltinAcp = BuiltinAcp{ + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlCreate, + EntryClass::AccessControlDelete, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_application_manage", + uuid: UUID_IDM_ACP_APPLICATION_MANAGE, + description: "Builtin IDM Control for creating and deleting applications in the directory", + receiver: BuiltinAcpReceiver::Group ( vec![UUID_IDM_APPLICATION_ADMINS] ), + // Any application + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Application), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Name, + Attribute::Description, + Attribute::DisplayName, + Attribute::Mail, + Attribute::UnixPassword, + Attribute::ApiTokenSession, + Attribute::UserAuthTokenSession, + Attribute::LinkedGroup, + Attribute::EntryManagedBy, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Name, + Attribute::Description, + Attribute::DisplayName, + Attribute::Mail, + Attribute::LinkedGroup, + Attribute::EntryManagedBy, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Account, + EntryClass::ServiceAccount, + EntryClass::Application, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::DisplayName, + Attribute::Mail, + Attribute::UnixPassword, + Attribute::ApiTokenSession, + Attribute::LinkedGroup, + Attribute::EntryManagedBy, + ], + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::DisplayName, + Attribute::Mail, + Attribute::UnixPassword, + Attribute::ApiTokenSession, + Attribute::UserAuthTokenSession, + Attribute::LinkedGroup, + Attribute::EntryManagedBy, + ], + ..Default::default() + }; +} + +lazy_static! { + pub static ref IDM_ACP_APPLICATION_ENTRY_MANAGER_DL8: BuiltinAcp = BuiltinAcp { + classes: vec![ + EntryClass::Object, + EntryClass::AccessControlProfile, + EntryClass::AccessControlModify, + EntryClass::AccessControlSearch + ], + name: "idm_acp_application_entry_manager", + uuid: UUID_IDM_ACP_APPLICATION_ENTRY_MANAGER, + description: "Builtin IDM Control for allowing EntryManager to read and modify applications", + receiver: BuiltinAcpReceiver::EntryManager, + // Applications that belong to the Entry Manager. + target: BuiltinAcpTarget::Filter( ProtoFilter::And(vec![ + match_class_filter!(EntryClass::Application), + FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone() + ])), + search_attrs: vec![ + Attribute::Class, + Attribute::Uuid, + Attribute::Name, + Attribute::DisplayName, + Attribute::Mail, + Attribute::UnixPassword, + Attribute::ApiTokenSession, + Attribute::UserAuthTokenSession, + Attribute::Description, + Attribute::LinkedGroup, + Attribute::EntryManagedBy, + ], + modify_present_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::DisplayName, + Attribute::Mail, + Attribute::UnixPassword, + Attribute::ApiTokenSession, + Attribute::LinkedGroup, + ], + modify_removed_attrs: vec![ + Attribute::Name, + Attribute::Description, + Attribute::DisplayName, + Attribute::Mail, + Attribute::UnixPassword, + Attribute::ApiTokenSession, + Attribute::UserAuthTokenSession, + Attribute::LinkedGroup, + ], + ..Default::default() + }; +} diff --git a/server/lib/src/migration_data/dl9/accounts.rs b/server/lib/src/migration_data/dl9/accounts.rs new file mode 100644 index 000000000..f7b6a065a --- /dev/null +++ b/server/lib/src/migration_data/dl9/accounts.rs @@ -0,0 +1,35 @@ +//! Constant Entries for the IDM +use crate::constants::uuids::*; +use crate::migration_data::types::BuiltinAccount; +use kanidm_proto::v1::AccountType; + +lazy_static! { + /// Builtin System Admin account. + pub static ref BUILTIN_ACCOUNT_IDM_ADMIN: BuiltinAccount = BuiltinAccount { + account_type: AccountType::ServiceAccount, + entry_managed_by: None, + name: "idm_admin", + uuid: UUID_IDM_ADMIN, + description: "Builtin IDM Admin account.", + displayname: "IDM Administrator", + }; + + /// Builtin System Admin account. + pub static ref BUILTIN_ACCOUNT_ADMIN: BuiltinAccount = BuiltinAccount { + account_type: AccountType::ServiceAccount, + entry_managed_by: None, + name: "admin", + uuid: UUID_ADMIN, + description: "Builtin System Admin account.", + displayname: "System Administrator", + }; + + pub static ref BUILTIN_ACCOUNT_ANONYMOUS_DL6: BuiltinAccount = BuiltinAccount { + account_type: AccountType::ServiceAccount, + entry_managed_by: Some(UUID_IDM_ADMINS), + name: "anonymous", + uuid: UUID_ANONYMOUS, + description: "Anonymous access account.", + displayname: "Anonymous", + }; +} diff --git a/server/lib/src/migration_data/dl9/groups.rs b/server/lib/src/migration_data/dl9/groups.rs new file mode 100644 index 000000000..0955f9009 --- /dev/null +++ b/server/lib/src/migration_data/dl9/groups.rs @@ -0,0 +1,408 @@ +use crate::entry::EntryInitNew; +use crate::prelude::*; +use crate::value::CredentialType; + +use kanidm_proto::internal::{Filter, OperationError, UiHint}; + +#[derive(Clone, Debug, Default)] +/// Built-in group definitions +pub struct BuiltinGroup { + pub name: &'static str, + pub description: &'static str, + pub uuid: uuid::Uuid, + pub members: Vec, + pub entry_managed_by: Option, + pub dyngroup: bool, + pub dyngroup_filter: Option, + pub extra_attributes: Vec<(Attribute, Value)>, +} + +impl TryFrom for EntryInitNew { + type Error = OperationError; + + fn try_from(val: BuiltinGroup) -> Result { + 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::Description, Value::new_utf8s(val.description)); + // classes for groups + entry.set_ava( + Attribute::Class, + vec![EntryClass::Group.into(), EntryClass::Object.into()], + ); + if val.dyngroup { + if !val.members.is_empty() { + return Err(OperationError::InvalidSchemaState(format!( + "Builtin dyngroup {} has members specified, this is not allowed", + val.name + ))); + } + entry.add_ava(Attribute::Class, EntryClass::DynGroup.to_value()); + match val.dyngroup_filter { + Some(filter) => entry.add_ava(Attribute::DynGroupFilter, Value::JsonFilt(filter)), + None => { + error!( + "No filter specified for dyngroup '{}' this is going to break things!", + val.name + ); + return Err(OperationError::FilterGeneration); + } + }; + } + + if let Some(entry_manager) = val.entry_managed_by { + entry.add_ava(Attribute::EntryManagedBy, Value::Refer(entry_manager)); + } + + entry.add_ava(Attribute::Uuid, Value::Uuid(val.uuid)); + entry.set_ava( + Attribute::Member, + val.members + .into_iter() + .map(Value::Refer) + .collect::>(), + ); + // add any extra attributes + val.extra_attributes + .into_iter() + .for_each(|(attr, val)| entry.add_ava(attr, val)); + // all done! + Ok(entry) + } +} + +lazy_static! { + // There are our built in "roles". They encapsulate some higher level collections + // of roles. The intent is to allow a pretty generic and correct by default set + // of these use cases. + pub static ref BUILTIN_GROUP_SYSTEM_ADMINS_V1: BuiltinGroup = BuiltinGroup { + name: "system_admins", + description: "Builtin System Administrators Group.", + uuid: UUID_SYSTEM_ADMINS, + entry_managed_by: Some(UUID_SYSTEM_ADMINS), + members: vec![UUID_ADMIN], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_IDM_ADMINS_V1: BuiltinGroup = BuiltinGroup { + name: "idm_admins", + description: "Builtin IDM Administrators Group.", + uuid: UUID_IDM_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMIN], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_SERVICE_DESK: BuiltinGroup = BuiltinGroup { + name: "idm_service_desk", + description: "Builtin Service Desk Group.", + uuid: UUID_IDM_SERVICE_DESK, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![], + ..Default::default() + }; +} + +lazy_static! { + // These are the "finer" roles. They encapsulate different concepts in the system. + // The next section is the "system style" roles. These adjust the operation of + // kanidm and relate to it's internals and how it functions. + pub static ref BUILTIN_GROUP_RECYCLE_BIN_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_recycle_bin_admins", + description: "Builtin Recycle Bin Administrators Group.", + uuid: UUID_IDM_RECYCLE_BIN_ADMINS, + entry_managed_by: Some(UUID_SYSTEM_ADMINS), + members: vec![UUID_SYSTEM_ADMINS], + ..Default::default() + }; + + /// Builtin IDM Group for granting local domain administration rights and trust administration rights + pub static ref BUILTIN_GROUP_DOMAIN_ADMINS: BuiltinGroup = BuiltinGroup { + name: "domain_admins", + description: "Builtin IDM Group for granting local domain administration rights and trust administration rights.", + uuid: UUID_DOMAIN_ADMINS, + entry_managed_by: Some(UUID_SYSTEM_ADMINS), + members: vec![UUID_SYSTEM_ADMINS], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_SCHEMA_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_schema_admins", + description: "Builtin Schema Administration Group.", + uuid: UUID_IDM_SCHEMA_ADMINS, + entry_managed_by: Some(UUID_SYSTEM_ADMINS), + members: vec![UUID_SYSTEM_ADMINS], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_ACCESS_CONTROL_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_access_control_admins", + description: "Builtin Access Control Administration Group.", + entry_managed_by: Some(UUID_SYSTEM_ADMINS), + uuid: UUID_IDM_ACCESS_CONTROL_ADMINS, + members: vec![UUID_SYSTEM_ADMINS], + ..Default::default() + }; + + // These are the IDM roles. They concern application integration, user permissions + // and credential security management. + + /// Builtin IDM Group for managing persons and their account details + pub static ref BUILTIN_GROUP_PEOPLE_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_people_admins", + description: "Builtin People Administration Group.", + uuid: UUID_IDM_PEOPLE_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_PEOPLE_ON_BOARDING: BuiltinGroup = BuiltinGroup { + name: "idm_people_on_boarding", + description: "Builtin People On Boarding Group.", + uuid: UUID_IDM_PEOPLE_ON_BOARDING, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![], + ..Default::default() + }; + + /// Builtin IDM Group for granting elevated people (personal data) read permissions. + pub static ref BUILTIN_GROUP_PEOPLE_PII_READ: BuiltinGroup = BuiltinGroup { + name: "idm_people_pii_read", + description: "Builtin IDM Group for granting elevated people (personal data) read permissions.", + uuid: UUID_IDM_PEOPLE_PII_READ, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![], + ..Default::default() + }; + + /// Builtin IDM Group for granting people the ability to write to their own name attributes. + pub static ref BUILTIN_GROUP_PEOPLE_SELF_NAME_WRITE_DL7: BuiltinGroup = BuiltinGroup { + name: "idm_people_self_name_write", + description: "Builtin IDM Group denoting users that can write to their own name attributes.", + uuid: UUID_IDM_PEOPLE_SELF_NAME_WRITE, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![ + UUID_IDM_ALL_PERSONS + ], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_SERVICE_ACCOUNT_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_service_account_admins", + description: "Builtin Service Account Administration Group.", + uuid: UUID_IDM_SERVICE_ACCOUNT_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + /// Builtin IDM Group for managing oauth2 resource server integrations to this authentication domain. + pub static ref BUILTIN_GROUP_OAUTH2_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_oauth2_admins", + description: "Builtin Oauth2 Integration Administration Group.", + uuid: UUID_IDM_OAUTH2_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_RADIUS_SERVICE_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_radius_service_admins", + description: "Builtin Radius Administration Group.", + uuid: UUID_IDM_RADIUS_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + /// Builtin IDM Group for RADIUS server access delegation. + pub static ref BUILTIN_IDM_RADIUS_SERVERS_V1: BuiltinGroup = BuiltinGroup { + name: "idm_radius_servers", + description: "Builtin IDM Group for RADIUS server access delegation.", + uuid: UUID_IDM_RADIUS_SERVERS, + entry_managed_by: Some(UUID_IDM_RADIUS_ADMINS), + members: vec![ + ], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_MAIL_SERVICE_ADMINS_DL8: BuiltinGroup = BuiltinGroup { + name: "idm_mail_service_admins", + description: "Builtin Mail Server Administration Group.", + uuid: UUID_IDM_MAIL_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + /// Builtin IDM Group for MAIL server Access delegation. + pub static ref BUILTIN_IDM_MAIL_SERVERS_DL8: BuiltinGroup = BuiltinGroup { + name: "idm_mail_servers", + description: "Builtin IDM Group for MAIL server access delegation.", + uuid: UUID_IDM_MAIL_SERVERS, + entry_managed_by: Some(UUID_IDM_MAIL_ADMINS), + members: vec![ + ], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_ACCOUNT_POLICY_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_account_policy_admins", + description: "Builtin Account Policy Administration Group.", + uuid: UUID_IDM_ACCOUNT_POLICY_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + /// Builtin IDM Group for managing posix/unix attributes on groups and users. + pub static ref BUILTIN_GROUP_UNIX_ADMINS: BuiltinGroup = BuiltinGroup { + name: "idm_unix_admins", + description: "Builtin Unix Administration Group.", + uuid: UUID_IDM_UNIX_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + /// Builtin IDM Group for managing client authentication certificates. + pub static ref BUILTIN_GROUP_CLIENT_CERTIFICATE_ADMINS_DL7: BuiltinGroup = BuiltinGroup { + name: "idm_client_certificate_admins", + description: "Builtin Client Certificate Administration Group.", + uuid: UUID_IDM_CLIENT_CERTIFICATE_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + /// Builtin IDM Group for granting elevated group write and lifecycle permissions. + pub static ref IDM_GROUP_ADMINS_V1: BuiltinGroup = BuiltinGroup { + name: "idm_group_admins", + description: "Builtin IDM Group for granting elevated group write and lifecycle permissions.", + uuid: UUID_IDM_GROUP_ADMINS, + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; + + /// Self-write of mail + pub static ref IDM_PEOPLE_SELF_MAIL_WRITE_DL7: BuiltinGroup = BuiltinGroup { + name: "idm_people_self_mail_write", + description: "Builtin IDM Group for people accounts to update their own mail.", + uuid: UUID_IDM_PEOPLE_SELF_MAIL_WRITE, + members: Vec::with_capacity(0), + ..Default::default() + }; +} + +// at some point vs code just gives up on syntax highlighting inside lazy_static... +lazy_static! { + pub static ref IDM_ALL_PERSONS: BuiltinGroup = BuiltinGroup { + name: "idm_all_persons", + description: "Builtin IDM dynamic group containing all persons.", + uuid: UUID_IDM_ALL_PERSONS, + members: Vec::with_capacity(0), + dyngroup: true, + dyngroup_filter: Some( + Filter::And(vec![ + Filter::Eq(Attribute::Class.to_string(), EntryClass::Person.to_string()), + Filter::Eq(Attribute::Class.to_string(), EntryClass::Account.to_string()), + ]) + ), + extra_attributes: vec![ + // Enable account policy by default + (Attribute::Class, EntryClass::AccountPolicy.to_value()), + // Enforce this is a system protected object + (Attribute::Class, EntryClass::System.to_value()), + // MFA By Default + (Attribute::CredentialTypeMinimum, CredentialType::Mfa.into()), + ], + ..Default::default() + }; + + pub static ref IDM_ALL_ACCOUNTS: BuiltinGroup = BuiltinGroup { + name: "idm_all_accounts", + description: "Builtin IDM dynamic group containing all entries that can authenticate.", + uuid: UUID_IDM_ALL_ACCOUNTS, + members: Vec::with_capacity(0), + dyngroup: true, + dyngroup_filter: Some( + Filter::Eq(Attribute::Class.to_string(), EntryClass::Account.to_string()), + ), + extra_attributes: vec![ + // Enable account policy by default + (Attribute::Class, EntryClass::AccountPolicy.to_value()), + // Enforce this is a system protected object + (Attribute::Class, EntryClass::System.to_value()), + ], + ..Default::default() + }; + + + pub static ref IDM_UI_ENABLE_EXPERIMENTAL_FEATURES: BuiltinGroup = BuiltinGroup { + name: "idm_ui_enable_experimental_features", + description: "Members of this group will have access to experimental web UI features.", + uuid: UUID_IDM_UI_ENABLE_EXPERIMENTAL_FEATURES, + entry_managed_by: Some(UUID_IDM_ADMINS), + extra_attributes: vec![ + (Attribute::GrantUiHint, Value::UiHint(UiHint::ExperimentalFeatures)) + ], + ..Default::default() + }; + + /// Members of this group will have access to read the mail attribute of all persons and service accounts. + pub static ref IDM_ACCOUNT_MAIL_READ: BuiltinGroup = BuiltinGroup { + name: "idm_account_mail_read", + description: "Members of this group will have access to read the mail attribute of all persons and service accounts.", + entry_managed_by: Some(UUID_IDM_ACCESS_CONTROL_ADMINS), + uuid: UUID_IDM_ACCOUNT_MAIL_READ, + ..Default::default() + }; + + /// This must be the last group to init to include the UUID of the other high priv groups. + pub static ref IDM_HIGH_PRIVILEGE_DL8: BuiltinGroup = BuiltinGroup { + name: "idm_high_privilege", + uuid: UUID_IDM_HIGH_PRIVILEGE, + entry_managed_by: Some(UUID_IDM_ACCESS_CONTROL_ADMINS), + description: "Builtin IDM provided groups with high levels of access that should be audited and limited in modification.", + members: vec![ + UUID_SYSTEM_ADMINS, + UUID_IDM_ADMINS, + UUID_DOMAIN_ADMINS, + UUID_IDM_SERVICE_DESK, + UUID_IDM_RECYCLE_BIN_ADMINS, + UUID_IDM_SCHEMA_ADMINS, + UUID_IDM_ACCESS_CONTROL_ADMINS, + UUID_IDM_OAUTH2_ADMINS, + UUID_IDM_RADIUS_ADMINS, + UUID_IDM_ACCOUNT_POLICY_ADMINS, + UUID_IDM_RADIUS_SERVERS, + UUID_IDM_GROUP_ADMINS, + UUID_IDM_UNIX_ADMINS, + UUID_IDM_PEOPLE_PII_READ, + UUID_IDM_PEOPLE_ADMINS, + UUID_IDM_PEOPLE_ON_BOARDING, + UUID_IDM_SERVICE_ACCOUNT_ADMINS, + UUID_IDM_CLIENT_CERTIFICATE_ADMINS, + UUID_IDM_APPLICATION_ADMINS, + UUID_IDM_MAIL_ADMINS, + UUID_IDM_HIGH_PRIVILEGE, + ], + ..Default::default() + }; + + pub static ref BUILTIN_GROUP_APPLICATION_ADMINS_DL8: BuiltinGroup = BuiltinGroup { + name: "idm_application_admins", + uuid: UUID_IDM_APPLICATION_ADMINS, + description: "Builtin Application Administration Group.", + entry_managed_by: Some(UUID_IDM_ADMINS), + members: vec![UUID_IDM_ADMINS], + ..Default::default() + }; +} diff --git a/server/lib/src/migration_data/dl9/key_providers.rs b/server/lib/src/migration_data/dl9/key_providers.rs new file mode 100644 index 000000000..f6cd2b3cf --- /dev/null +++ b/server/lib/src/migration_data/dl9/key_providers.rs @@ -0,0 +1,18 @@ +use crate::constants::entries::{Attribute, EntryClass}; +use crate::constants::uuids::UUID_KEY_PROVIDER_INTERNAL; +use crate::entry::{Entry, EntryInit, EntryInitNew, EntryNew}; +use crate::value::Value; + +lazy_static! { + pub static ref E_KEY_PROVIDER_INTERNAL_DL6: EntryInitNew = entry_init!( + (Attribute::Class, EntryClass::Object.to_value()), + (Attribute::Class, EntryClass::KeyProvider.to_value()), + (Attribute::Class, EntryClass::KeyProviderInternal.to_value()), + (Attribute::Uuid, Value::Uuid(UUID_KEY_PROVIDER_INTERNAL)), + (Attribute::Name, Value::new_iname("key_provider_internal")), + ( + Attribute::Description, + Value::new_utf8s("The default database internal cryptographic key provider.") + ) + ); +} diff --git a/server/lib/src/migration_data/dl9/mod.rs b/server/lib/src/migration_data/dl9/mod.rs new file mode 100644 index 000000000..78154d8b2 --- /dev/null +++ b/server/lib/src/migration_data/dl9/mod.rs @@ -0,0 +1,264 @@ +mod access; +mod accounts; +mod groups; +mod key_providers; +mod schema; +mod system_config; + +use self::access::*; +use self::accounts::*; +use self::groups::*; +use self::key_providers::*; +use self::schema::*; +use self::system_config::*; + +use crate::prelude::EntryInitNew; +use kanidm_proto::internal::OperationError; + +pub fn phase_1_schema_attrs() -> Vec { + vec![ + SCHEMA_ATTR_SYNC_CREDENTIAL_PORTAL.clone().into(), + SCHEMA_ATTR_SYNC_YIELD_AUTHORITY.clone().into(), + SCHEMA_ATTR_ACCOUNT_EXPIRE.clone().into(), + SCHEMA_ATTR_ACCOUNT_VALID_FROM.clone().into(), + SCHEMA_ATTR_API_TOKEN_SESSION.clone().into(), + SCHEMA_ATTR_AUTH_SESSION_EXPIRY.clone().into(), + SCHEMA_ATTR_AUTH_PRIVILEGE_EXPIRY.clone().into(), + SCHEMA_ATTR_AUTH_PASSWORD_MINIMUM_LENGTH.clone().into(), + SCHEMA_ATTR_BADLIST_PASSWORD.clone().into(), + SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN.clone().into(), + SCHEMA_ATTR_ATTESTED_PASSKEYS.clone().into(), + SCHEMA_ATTR_DOMAIN_DISPLAY_NAME.clone().into(), + SCHEMA_ATTR_DOMAIN_LDAP_BASEDN.clone().into(), + SCHEMA_ATTR_DOMAIN_NAME.clone().into(), + SCHEMA_ATTR_LDAP_ALLOW_UNIX_PW_BIND.clone().into(), + SCHEMA_ATTR_DOMAIN_SSID.clone().into(), + SCHEMA_ATTR_DOMAIN_TOKEN_KEY.clone().into(), + SCHEMA_ATTR_DOMAIN_UUID.clone().into(), + SCHEMA_ATTR_DYNGROUP_FILTER.clone().into(), + SCHEMA_ATTR_EC_KEY_PRIVATE.clone().into(), + SCHEMA_ATTR_ES256_PRIVATE_KEY_DER.clone().into(), + SCHEMA_ATTR_FERNET_PRIVATE_KEY_STR.clone().into(), + SCHEMA_ATTR_GIDNUMBER.clone().into(), + SCHEMA_ATTR_GRANT_UI_HINT.clone().into(), + SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY.clone().into(), + SCHEMA_ATTR_LOGINSHELL.clone().into(), + SCHEMA_ATTR_NAME_HISTORY.clone().into(), + SCHEMA_ATTR_NSUNIQUEID.clone().into(), + SCHEMA_ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE + .clone() + .into(), + SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP.clone().into(), + SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE.clone().into(), + SCHEMA_ATTR_OAUTH2_PREFER_SHORT_USERNAME.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_BASIC_SECRET.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_IMPLICIT_SCOPES.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_NAME.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_ORIGIN_LANDING.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_TOKEN_KEY.clone().into(), + SCHEMA_ATTR_OAUTH2_SESSION.clone().into(), + SCHEMA_ATTR_PASSKEYS.clone().into(), + SCHEMA_ATTR_PRIMARY_CREDENTIAL.clone().into(), + SCHEMA_ATTR_PRIVATE_COOKIE_KEY.clone().into(), + SCHEMA_ATTR_RADIUS_SECRET.clone().into(), + SCHEMA_ATTR_RS256_PRIVATE_KEY_DER.clone().into(), + SCHEMA_ATTR_SSH_PUBLICKEY.clone().into(), + SCHEMA_ATTR_SYNC_COOKIE.clone().into(), + SCHEMA_ATTR_SYNC_TOKEN_SESSION.clone().into(), + SCHEMA_ATTR_UNIX_PASSWORD.clone().into(), + SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION.clone().into(), + SCHEMA_ATTR_DENIED_NAME.clone().into(), + SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM.clone().into(), + SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST.clone().into(), + // DL4 + SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP_DL4.clone().into(), + SCHEMA_ATTR_OAUTH2_ALLOW_LOCALHOST_REDIRECT_DL4 + .clone() + .into(), + // DL5 + // DL6 + SCHEMA_ATTR_LIMIT_SEARCH_MAX_RESULTS_DL6.clone().into(), + SCHEMA_ATTR_LIMIT_SEARCH_MAX_FILTER_TEST_DL6.clone().into(), + SCHEMA_ATTR_KEY_INTERNAL_DATA_DL6.clone().into(), + SCHEMA_ATTR_KEY_PROVIDER_DL6.clone().into(), + SCHEMA_ATTR_KEY_ACTION_ROTATE_DL6.clone().into(), + SCHEMA_ATTR_KEY_ACTION_REVOKE_DL6.clone().into(), + SCHEMA_ATTR_KEY_ACTION_IMPORT_JWS_ES256_DL6.clone().into(), + // DL7 + SCHEMA_ATTR_PATCH_LEVEL_DL7.clone().into(), + SCHEMA_ATTR_DOMAIN_DEVELOPMENT_TAINT_DL7.clone().into(), + SCHEMA_ATTR_REFERS_DL7.clone().into(), + SCHEMA_ATTR_CERTIFICATE_DL7.clone().into(), + SCHEMA_ATTR_OAUTH2_RS_ORIGIN_DL7.clone().into(), + SCHEMA_ATTR_OAUTH2_STRICT_REDIRECT_URI_DL7.clone().into(), + SCHEMA_ATTR_MAIL_DL7.clone().into(), + SCHEMA_ATTR_LEGALNAME_DL7.clone().into(), + SCHEMA_ATTR_DISPLAYNAME_DL7.clone().into(), + // DL8 + SCHEMA_ATTR_LINKED_GROUP_DL8.clone().into(), + SCHEMA_ATTR_APPLICATION_PASSWORD_DL8.clone().into(), + SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK_DL8.clone().into(), + // DL9 + SCHEMA_ATTR_OAUTH2_DEVICE_FLOW_ENABLE_DL9.clone().into(), + SCHEMA_ATTR_DOMAIN_ALLOW_EASTER_EGGS_DL9.clone().into(), + ] +} + +pub fn phase_2_schema_classes() -> Vec { + vec![ + SCHEMA_CLASS_DYNGROUP.clone().into(), + SCHEMA_CLASS_ORGPERSON.clone().into(), + SCHEMA_CLASS_POSIXACCOUNT.clone().into(), + SCHEMA_CLASS_POSIXGROUP.clone().into(), + SCHEMA_CLASS_SYSTEM_CONFIG.clone().into(), + // DL4 + SCHEMA_CLASS_OAUTH2_RS_PUBLIC_DL4.clone().into(), + // DL5 + SCHEMA_CLASS_ACCOUNT_DL5.clone().into(), + SCHEMA_CLASS_OAUTH2_RS_BASIC_DL5.clone().into(), + // DL6 + SCHEMA_CLASS_GROUP_DL6.clone().into(), + SCHEMA_CLASS_KEY_PROVIDER_DL6.clone().into(), + SCHEMA_CLASS_KEY_PROVIDER_INTERNAL_DL6.clone().into(), + SCHEMA_CLASS_KEY_OBJECT_DL6.clone().into(), + SCHEMA_CLASS_KEY_OBJECT_JWT_ES256_DL6.clone().into(), + SCHEMA_CLASS_KEY_OBJECT_JWE_A128GCM_DL6.clone().into(), + SCHEMA_CLASS_KEY_OBJECT_INTERNAL_DL6.clone().into(), + // DL7 + SCHEMA_CLASS_SERVICE_ACCOUNT_DL7.clone().into(), + SCHEMA_CLASS_SYNC_ACCOUNT_DL7.clone().into(), + SCHEMA_CLASS_CLIENT_CERTIFICATE_DL7.clone().into(), + // DL8 + SCHEMA_CLASS_ACCOUNT_POLICY_DL8.clone().into(), + SCHEMA_CLASS_APPLICATION_DL8.clone().into(), + SCHEMA_CLASS_PERSON_DL8.clone().into(), + // DL9 + SCHEMA_CLASS_OAUTH2_RS_DL9.clone().into(), + SCHEMA_CLASS_DOMAIN_INFO_DL9.clone().into(), + ] +} + +pub fn phase_3_key_provider() -> Vec { + vec![E_KEY_PROVIDER_INTERNAL_DL6.clone()] +} + +pub fn phase_4_system_entries() -> Vec { + vec![ + E_SYSTEM_INFO_V1.clone(), + E_DOMAIN_INFO_DL6.clone(), + E_SYSTEM_CONFIG_V1.clone(), + ] +} + +pub fn phase_5_builtin_admin_entries() -> Result, OperationError> { + Ok(vec![ + BUILTIN_ACCOUNT_ADMIN.clone().into(), + BUILTIN_ACCOUNT_IDM_ADMIN.clone().into(), + BUILTIN_GROUP_SYSTEM_ADMINS_V1.clone().try_into()?, + BUILTIN_GROUP_IDM_ADMINS_V1.clone().try_into()?, + // We need to push anonymous *after* groups due to entry-managed-by + BUILTIN_ACCOUNT_ANONYMOUS_DL6.clone().into(), + ]) +} + +pub fn phase_6_builtin_non_admin_entries() -> Result, OperationError> { + Ok(vec![ + BUILTIN_GROUP_DOMAIN_ADMINS.clone().try_into()?, + BUILTIN_GROUP_SCHEMA_ADMINS.clone().try_into()?, + BUILTIN_GROUP_ACCESS_CONTROL_ADMINS.clone().try_into()?, + BUILTIN_GROUP_UNIX_ADMINS.clone().try_into()?, + BUILTIN_GROUP_RECYCLE_BIN_ADMINS.clone().try_into()?, + BUILTIN_GROUP_SERVICE_DESK.clone().try_into()?, + BUILTIN_GROUP_OAUTH2_ADMINS.clone().try_into()?, + BUILTIN_GROUP_RADIUS_SERVICE_ADMINS.clone().try_into()?, + BUILTIN_GROUP_ACCOUNT_POLICY_ADMINS.clone().try_into()?, + BUILTIN_GROUP_PEOPLE_ADMINS.clone().try_into()?, + BUILTIN_GROUP_PEOPLE_PII_READ.clone().try_into()?, + BUILTIN_GROUP_PEOPLE_ON_BOARDING.clone().try_into()?, + BUILTIN_GROUP_SERVICE_ACCOUNT_ADMINS.clone().try_into()?, + BUILTIN_GROUP_MAIL_SERVICE_ADMINS_DL8.clone().try_into()?, + IDM_GROUP_ADMINS_V1.clone().try_into()?, + IDM_ALL_PERSONS.clone().try_into()?, + IDM_ALL_ACCOUNTS.clone().try_into()?, + BUILTIN_IDM_RADIUS_SERVERS_V1.clone().try_into()?, + BUILTIN_IDM_MAIL_SERVERS_DL8.clone().try_into()?, + BUILTIN_GROUP_PEOPLE_SELF_NAME_WRITE_DL7 + .clone() + .try_into()?, + IDM_PEOPLE_SELF_MAIL_WRITE_DL7.clone().try_into()?, + BUILTIN_GROUP_CLIENT_CERTIFICATE_ADMINS_DL7 + .clone() + .try_into()?, + BUILTIN_GROUP_APPLICATION_ADMINS_DL8.clone().try_into()?, + // Write deps on read.clone().try_into()?, so write must be added first. + // All members must exist before we write HP + IDM_HIGH_PRIVILEGE_DL8.clone().try_into()?, + // other things + IDM_UI_ENABLE_EXPERIMENTAL_FEATURES.clone().try_into()?, + IDM_ACCOUNT_MAIL_READ.clone().try_into()?, + ]) +} + +pub fn phase_7_builtin_access_control_profiles() -> Vec { + vec![ + // Built in access controls. + IDM_ACP_RECYCLE_BIN_SEARCH_V1.clone().into(), + IDM_ACP_RECYCLE_BIN_REVIVE_V1.clone().into(), + IDM_ACP_SCHEMA_WRITE_ATTRS_V1.clone().into(), + IDM_ACP_SCHEMA_WRITE_CLASSES_V1.clone().into(), + IDM_ACP_ACP_MANAGE_V1.clone().into(), + IDM_ACP_GROUP_ENTRY_MANAGED_BY_MODIFY_V1.clone().into(), + IDM_ACP_GROUP_ENTRY_MANAGER_V1.clone().into(), + IDM_ACP_SYNC_ACCOUNT_MANAGE_V1.clone().into(), + IDM_ACP_RADIUS_SERVERS_V1.clone().into(), + IDM_ACP_RADIUS_SECRET_MANAGE_V1.clone().into(), + IDM_ACP_PEOPLE_SELF_WRITE_MAIL_V1.clone().into(), + IDM_ACP_ACCOUNT_SELF_WRITE_V1.clone().into(), + IDM_ACP_ALL_ACCOUNTS_POSIX_READ_V1.clone().into(), + IDM_ACP_SYSTEM_CONFIG_ACCOUNT_POLICY_MANAGE_V1 + .clone() + .into(), + IDM_ACP_GROUP_UNIX_MANAGE_V1.clone().into(), + IDM_ACP_HP_GROUP_UNIX_MANAGE_V1.clone().into(), + IDM_ACP_GROUP_READ_V1.clone().into(), + IDM_ACP_ACCOUNT_UNIX_EXTEND_V1.clone().into(), + IDM_ACP_PEOPLE_PII_READ_V1.clone().into(), + IDM_ACP_PEOPLE_PII_MANAGE_V1.clone().into(), + IDM_ACP_PEOPLE_READ_V1.clone().into(), + IDM_ACP_PEOPLE_MANAGE_V1.clone().into(), + IDM_ACP_PEOPLE_DELETE_V1.clone().into(), + IDM_ACP_PEOPLE_CREDENTIAL_RESET_V1.clone().into(), + IDM_ACP_HP_PEOPLE_CREDENTIAL_RESET_V1.clone().into(), + IDM_ACP_SERVICE_ACCOUNT_CREATE_V1.clone().into(), + IDM_ACP_SERVICE_ACCOUNT_DELETE_V1.clone().into(), + IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGER_V1.clone().into(), + IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1 + .clone() + .into(), + IDM_ACP_HP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1 + .clone() + .into(), + IDM_ACP_SERVICE_ACCOUNT_MANAGE_V1.clone().into(), + // DL4 + // DL5 + // DL6 + IDM_ACP_PEOPLE_CREATE_DL6.clone().into(), + IDM_ACP_ACCOUNT_MAIL_READ_DL6.clone().into(), + // DL7 + IDM_ACP_SELF_NAME_WRITE_DL7.clone().into(), + IDM_ACP_HP_CLIENT_CERTIFICATE_MANAGER_DL7.clone().into(), + // DL8 + IDM_ACP_SELF_READ_DL8.clone().into(), + IDM_ACP_SELF_WRITE_DL8.clone().into(), + IDM_ACP_APPLICATION_MANAGE_DL8.clone().into(), + IDM_ACP_APPLICATION_ENTRY_MANAGER_DL8.clone().into(), + IDM_ACP_MAIL_SERVERS_DL8.clone().into(), + IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE_DL8.clone().into(), + // DL9 + IDM_ACP_OAUTH2_MANAGE_DL9.clone().into(), + IDM_ACP_GROUP_MANAGE_DL9.clone().into(), + IDM_ACP_DOMAIN_ADMIN_DL9.clone().into(), + ] +} diff --git a/server/lib/src/migration_data/dl9/schema.rs b/server/lib/src/migration_data/dl9/schema.rs new file mode 100644 index 000000000..1a3ebbca9 --- /dev/null +++ b/server/lib/src/migration_data/dl9/schema.rs @@ -0,0 +1,1506 @@ +//! Schema Entries +use crate::constants::entries::{Attribute, EntryClass}; +use crate::constants::uuids::*; +use crate::schema::{SchemaAttribute, SchemaClass}; +use crate::value::IndexType; +use crate::value::SyntaxType; + +lazy_static!( + +pub static ref SCHEMA_ATTR_DISPLAYNAME: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DISPLAYNAME, + name: Attribute::DisplayName, + description: "The publicly visible display name of this person".to_string(), + + index: vec![IndexType::Equality], + sync_allowed: true, + syntax: SyntaxType::Utf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DISPLAYNAME_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DISPLAYNAME, + name: Attribute::DisplayName, + description: "The publicly visible display name of this person".to_string(), + + index: vec![IndexType::Equality, IndexType::SubString], + sync_allowed: true, + syntax: SyntaxType::Utf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_MAIL: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_MAIL, + name: Attribute::Mail, + description: "Mail addresses of the object".to_string(), + + index: vec![IndexType::Equality], + unique: true, + multivalue: true, + sync_allowed: true, + syntax: SyntaxType::EmailAddress, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_MAIL_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_MAIL, + name: Attribute::Mail, + description: "Mail addresses of the object".to_string(), + + index: vec![IndexType::Equality, IndexType::SubString], + unique: true, + multivalue: true, + sync_allowed: true, + syntax: SyntaxType::EmailAddress, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_EC_KEY_PRIVATE: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_EC_KEY_PRIVATE, + name: Attribute::IdVerificationEcKey, + description: "Account verification private key".to_string(), + + index: vec![IndexType::Presence], + unique: false, + sync_allowed: false, + syntax: SyntaxType::EcKeyPrivate, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_SSH_PUBLICKEY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_SSH_PUBLICKEY, + name: Attribute::SshPublicKey, + description: "SSH public keys of the object".to_string(), + + multivalue: true, + sync_allowed: true, + syntax: SyntaxType::SshKey, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_PRIMARY_CREDENTIAL: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_PRIMARY_CREDENTIAL, + name: Attribute::PrimaryCredential, + description: "Primary credential material of the account for authentication interactively".to_string(), + + index: vec![IndexType::Presence], + sync_allowed: true, + syntax: SyntaxType::Credential, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_LEGALNAME: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_LEGALNAME, + name: Attribute::LegalName, + description: "The private and sensitive legal name of this person".to_string(), + + index: vec![IndexType::Equality], + sync_allowed: true, + syntax: SyntaxType::Utf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_LEGALNAME_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_LEGALNAME, + name: Attribute::LegalName, + description: "The private and sensitive legal name of this person".to_string(), + + index: vec![IndexType::Equality, IndexType::SubString], + sync_allowed: true, + syntax: SyntaxType::Utf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_NAME_HISTORY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_NAME_HISTORY, + name: Attribute::NameHistory, + description: "The history of names that a person has had".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + sync_allowed: true, + syntax: SyntaxType::AuditLogString, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_RADIUS_SECRET: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_RADIUS_SECRET, + name: Attribute::RadiusSecret, + description: "The accounts generated radius secret for device network authentication".to_string(), + + sync_allowed: true, + syntax: SyntaxType::SecretUtf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_NAME: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_NAME, + name: Attribute::DomainName, + description: "The domain's DNS name for webauthn and SPN generation purposes".to_string(), + + index: vec![IndexType::Equality, IndexType::Presence], + unique: true, + syntax: SyntaxType::Utf8StringIname, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_LDAP_ALLOW_UNIX_PW_BIND: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_LDAP_ALLOW_UNIX_PW_BIND, + name: Attribute::LdapAllowUnixPwBind, + description: "Configuration to enable binds to LDAP objects using their UNIX password".to_string(), + + unique: false, + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_LDAP_BASEDN: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_LDAP_BASEDN, + name: Attribute::DomainLdapBasedn, + description: "The domain's optional ldap basedn. If unset defaults to domain components of domain name".to_string(), + + unique: true, + syntax: SyntaxType::Utf8StringInsensitive, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_DISPLAY_NAME: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_DISPLAY_NAME, + name: Attribute::DomainDisplayName, + description: "The user-facing display name of the Kanidm domain".to_string(), + + index: vec![IndexType::Equality], + syntax: SyntaxType::Utf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_UUID: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_UUID, + name: Attribute::DomainUuid, + description: "The domain's uuid, used in CSN and trust relationships".to_string(), + + index: vec![IndexType::Equality], + unique: true, + syntax: SyntaxType::Uuid, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_SSID: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_SSID, + name: Attribute::DomainSsid, + description: "The domains site-wide SSID for device autoconfiguration of wireless".to_string(), + + index: vec![IndexType::Equality], + unique: true, + syntax: SyntaxType::Utf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DENIED_NAME: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DENIED_NAME, + name: Attribute::DeniedName, + description: "Iname values that are not allowed to be used in 'name'.".to_string(), + + syntax: SyntaxType::Utf8StringIname, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DENIED_NAME_DL10: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DENIED_NAME, + name: Attribute::DeniedName, + description: "Iname values that are not allowed to be used in 'name'.".to_string(), + + syntax: SyntaxType::Utf8StringIname, + multivalue: true, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_TOKEN_KEY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_TOKEN_KEY, + name: Attribute::DomainTokenKey, + description: "The domain token encryption private key (NOT USED)".to_string(), + + syntax: SyntaxType::SecretUtf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_FERNET_PRIVATE_KEY_STR: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_FERNET_PRIVATE_KEY_STR, + name: Attribute::FernetPrivateKeyStr, + description: "The token encryption private key".to_string(), + + syntax: SyntaxType::SecretUtf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_GIDNUMBER: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_GIDNUMBER, + name: Attribute::GidNumber, + description: "The groupid (uid) number of a group or account.to_string(). This is the same value as the UID number on posix accounts for security reasons".to_string(), + + index: vec![IndexType::Equality], + unique: true, + sync_allowed: true, + syntax: SyntaxType::Uint32, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_BADLIST_PASSWORD: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_BADLIST_PASSWORD, + name: Attribute::BadlistPassword, + description: "A password that is badlisted meaning that it can not be set as a valid password by any user account".to_string(), + + multivalue: true, + syntax: SyntaxType::Utf8StringInsensitive, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_AUTH_SESSION_EXPIRY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_AUTH_SESSION_EXPIRY, + name: Attribute::AuthSessionExpiry, + description: "An expiration time for an authentication session".to_string(), + + syntax: SyntaxType::Uint32, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_AUTH_PRIVILEGE_EXPIRY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_AUTH_PRIVILEGE_EXPIRY, + name: Attribute::PrivilegeExpiry, + description: "An expiration time for a privileged authentication session".to_string(), + + syntax: SyntaxType::Uint32, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_AUTH_PASSWORD_MINIMUM_LENGTH: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_AUTH_PASSWORD_MINIMUM_LENGTH, + name: Attribute::AuthPasswordMinimumLength, + description: "Minimum length of passwords".to_string(), + + syntax: SyntaxType::Uint32, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_LOGINSHELL: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_LOGINSHELL, + name: Attribute::LoginShell, + description: "A POSIX user's UNIX login shell".to_string(), + + sync_allowed: true, + syntax: SyntaxType::Utf8StringInsensitive, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_UNIX_PASSWORD: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_UNIX_PASSWORD, + name: Attribute::UnixPassword, + description: "A POSIX user's UNIX login password".to_string(), + + index: vec![IndexType::Presence], + syntax: SyntaxType::Credential, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_NSUNIQUEID: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_NSUNIQUEID, + name: Attribute::NsUniqueId, + description: "A unique id compatibility for 389-ds/dsee".to_string(), + + index: vec![IndexType::Equality], + unique: true, + sync_allowed: true, + syntax: SyntaxType::NsUniqueId, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_ACCOUNT_EXPIRE: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_ACCOUNT_EXPIRE, + name: Attribute::AccountExpire, + description: "The datetime after which this account no longer may authenticate".to_string(), + + sync_allowed: true, + syntax: SyntaxType::DateTime, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_ACCOUNT_VALID_FROM: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_ACCOUNT_VALID_FROM, + name: Attribute::AccountValidFrom, + description: "The datetime after which this account may commence authenticating".to_string(), + + sync_allowed: true, + syntax: SyntaxType::DateTime, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST, + name: Attribute::WebauthnAttestationCaList, + description: "A set of CA's that limit devices that can be used with webauthn".to_string(), + + syntax: SyntaxType::WebauthnAttestationCaList, + multivalue: true, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_NAME: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_NAME, + name: Attribute::OAuth2RsName, + description: "The unique name of an external Oauth2 resource".to_string(), + + index: vec![IndexType::Equality], + unique: true, + syntax: SyntaxType::Utf8StringIname, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_ORIGIN: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_ORIGIN, + name: Attribute::OAuth2RsOrigin, + description: "The origin domain of an oauth2 resource server".to_string(), + + syntax: SyntaxType::Url, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_ORIGIN_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_ORIGIN, + name: Attribute::OAuth2RsOrigin, + description: "The origin domain of an OAuth2 client".to_string(), + + syntax: SyntaxType::Url, + multivalue: true, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_ORIGIN_LANDING: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_ORIGIN_LANDING, + name: Attribute::OAuth2RsOriginLanding, + description: "The landing page of an RS, that will automatically trigger the auth process".to_string(), + + syntax: SyntaxType::Url, + ..Default::default() +}; + +// Introduced in DomainLevel4 +pub static ref SCHEMA_ATTR_OAUTH2_ALLOW_LOCALHOST_REDIRECT_DL4: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_ALLOW_LOCALHOST_REDIRECT, + name: Attribute::OAuth2AllowLocalhostRedirect, + description: "Allow public clients associated to this RS to redirect to localhost".to_string(), + + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP_DL4: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP, + name: Attribute::OAuth2RsClaimMap, + description: "A set of custom claims mapped to group memberships of accounts".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + // CHANGE ME + syntax: SyntaxType::OauthClaimMap, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP, + name: Attribute::OAuth2RsScopeMap, + description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + syntax: SyntaxType::OauthScopeMap, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP, + name: Attribute::OAuth2RsSupScopeMap, + description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + syntax: SyntaxType::OauthScopeMap, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_BASIC_SECRET: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_BASIC_SECRET, + name: Attribute::OAuth2RsBasicSecret, + description: "When using oauth2 basic authentication, the secret string of the resource server".to_string(), + + syntax: SyntaxType::SecretUtf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_TOKEN_KEY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_TOKEN_KEY, + name: Attribute::OAuth2RsTokenKey, + description: "An oauth2 resource servers unique token signing key".to_string(), + + syntax: SyntaxType::SecretUtf8String, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_RS_IMPLICIT_SCOPES: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_IMPLICIT_SCOPES, + name: Attribute::OAuth2RsImplicitScopes, + description: "An oauth2 resource servers scopes that are implicitly granted to all users".to_string(), + + multivalue: true, + syntax: SyntaxType::OauthScope, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP, + name: Attribute::OAuth2ConsentScopeMap, + description: "A set of scopes mapped from a relying server to a user, where the user has previously consented to the following. If changed or deleted, consent will be re-sought".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + syntax: SyntaxType::OauthScopeMap, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_STRICT_REDIRECT_URI_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_STRICT_REDIRECT_URI, + name: Attribute::OAuth2StrictRedirectUri, + description: "Represents if strict redirect uri enforcement is enabled.".to_string(), + + syntax: SyntaxType::Boolean, + ..Default::default() +}; + + +pub static ref SCHEMA_ATTR_OAUTH2_DEVICE_FLOW_ENABLE_DL9: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_DEVICE_FLOW_ENABLE, + name: Attribute::OAuth2DeviceFlowEnable, + description: "Represents if OAuth2 Device Flow is permitted on this client.".to_string(), + + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_ES256_PRIVATE_KEY_DER: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_ES256_PRIVATE_KEY_DER, + name: Attribute::Es256PrivateKeyDer, + description: "An es256 private key".to_string(), + + syntax: SyntaxType::PrivateBinary, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_RS256_PRIVATE_KEY_DER: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_RS256_PRIVATE_KEY_DER, + name: Attribute::Rs256PrivateKeyDer, + description: "An rs256 private key".to_string(), + + syntax: SyntaxType::PrivateBinary, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY, + name: Attribute::JwsEs256PrivateKey, + description: "An es256 private key for jws".to_string(), + + index: vec![IndexType::Equality], + unique: true, + syntax: SyntaxType::JwsKeyEs256, + ..Default::default() +}; + +// TO BE REMOVED IN A FUTURE RELEASE +pub static ref SCHEMA_ATTR_PRIVATE_COOKIE_KEY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_PRIVATE_COOKIE_KEY, + name: Attribute::PrivateCookieKey, + description: "An private cookie hmac key".to_string(), + + syntax: SyntaxType::PrivateBinary, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE, + name: Attribute::OAuth2AllowInsecureClientDisablePkce, + description: "Allows disabling of PKCE for insecure OAuth2 clients".to_string(), + + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE, + name: Attribute::OAuth2JwtLegacyCryptoEnable, + description: "Allows enabling legacy JWT cryptograhpy for clients".to_string(), + + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN, + name: Attribute::CredentialUpdateIntentToken, + description: "The status of a credential update intent token".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + syntax: SyntaxType::IntentToken, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_PASSKEYS: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_PASSKEYS, + name: Attribute::PassKeys, + description: "A set of registered passkeys".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + sync_allowed: true, + syntax: SyntaxType::Passkey, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_ATTESTED_PASSKEYS: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_ATTESTED_PASSKEYS, + name: Attribute::AttestedPasskeys, + description: "A set of registered device keys".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + sync_allowed: true, + syntax: SyntaxType::AttestedPasskey, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DYNGROUP_FILTER: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DYNGROUP_FILTER, + name: Attribute::DynGroupFilter, + description: "A filter describing the set of entries to add to a dynamic group".to_string(), + + syntax: SyntaxType::JsonFilter, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_PREFER_SHORT_USERNAME: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_PREFER_SHORT_USERNAME, + name: Attribute::OAuth2PreferShortUsername, + description: "Use 'name' instead of 'spn' in the preferred_username claim".to_string(), + + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_API_TOKEN_SESSION: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_API_TOKEN_SESSION, + name: Attribute::ApiTokenSession, + description: "A session entry related to an issued API token".to_string(), + + index: vec![IndexType::Equality], + unique: true, + multivalue: true, + syntax: SyntaxType::ApiToken, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION, + name: Attribute::UserAuthTokenSession, + description: "A session entry related to an issued user auth token".to_string(), + + index: vec![IndexType::Equality], + unique: true, + multivalue: true, + syntax: SyntaxType::Session, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_OAUTH2_SESSION: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_OAUTH2_SESSION, + name: Attribute::OAuth2Session, + description: "A session entry to an active oauth2 session, bound to a parent user auth token".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + syntax: SyntaxType::Oauth2Session, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_SYNC_TOKEN_SESSION: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_SYNC_TOKEN_SESSION, + name: Attribute::SyncTokenSession, + description: "A session entry related to an issued sync token".to_string(), + + index: vec![IndexType::Equality], + unique: true, + syntax: SyntaxType::ApiToken, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_SYNC_COOKIE: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_SYNC_COOKIE, + name: Attribute::SyncCookie, + description: "A private sync cookie for a remote IDM source".to_string(), + + syntax: SyntaxType::PrivateBinary, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_GRANT_UI_HINT: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_GRANT_UI_HINT, + name: Attribute::GrantUiHint, + description: "A UI hint that is granted via membership to a group".to_string(), + + index: vec![IndexType::Equality], + multivalue: true, + syntax: SyntaxType::UiHint, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_SYNC_CREDENTIAL_PORTAL: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_SYNC_CREDENTIAL_PORTAL, + name: Attribute::SyncCredentialPortal, + description: "The url of an external credential portal for synced accounts to visit to update their credentials".to_string(), + + syntax: SyntaxType::Url, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_SYNC_YIELD_AUTHORITY: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_SYNC_YIELD_AUTHORITY, + name: Attribute::SyncYieldAuthority, + description: "A set of attributes that have their authority yielded to Kanidm in a sync agreement".to_string(), + + multivalue: true, + syntax: SyntaxType::Utf8StringInsensitive, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM, + name: Attribute::CredentialTypeMinimum, + description: "The minimum level of credential type that can satisfy this policy".to_string(), + + multivalue: false, + syntax: SyntaxType::CredentialType, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_LIMIT_SEARCH_MAX_RESULTS_DL6: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_LIMIT_SEARCH_MAX_RESULTS, + name: Attribute::LimitSearchMaxResults, + description: "The maximum number of query results that may be returned in a single operation".to_string(), + + multivalue: false, + syntax: SyntaxType::Uint32, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_LIMIT_SEARCH_MAX_FILTER_TEST_DL6: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_LIMIT_SEARCH_MAX_FILTER_TEST, + name: Attribute::LimitSearchMaxFilterTest, + description: "The maximum number of entries that may be examined in a partially indexed query".to_string(), + + multivalue: false, + syntax: SyntaxType::Uint32, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_KEY_INTERNAL_DATA_DL6: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_KEY_INTERNAL_DATA, + name: Attribute::KeyInternalData, + description: "".to_string(), + multivalue: true, + syntax: SyntaxType::KeyInternal, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_KEY_PROVIDER_DL6: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_KEY_PROVIDER, + name: Attribute::KeyProvider, + description: "".to_string(), + multivalue: false, + syntax: SyntaxType::ReferenceUuid, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_KEY_ACTION_ROTATE_DL6: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_KEY_ACTION_ROTATE, + name: Attribute::KeyActionRotate, + description: "".to_string(), + multivalue: false, + // Ephemeral action. + phantom: true, + syntax: SyntaxType::DateTime, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_KEY_ACTION_REVOKE_DL6: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_KEY_ACTION_REVOKE, + name: Attribute::KeyActionRevoke, + description: "".to_string(), + multivalue: true, + // Ephemeral action. + phantom: true, + syntax: SyntaxType::HexString, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_KEY_ACTION_IMPORT_JWS_ES256_DL6: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_KEY_ACTION_IMPORT_JWS_ES256, + name: Attribute::KeyActionImportJwsEs256, + description: "".to_string(), + multivalue: true, + // Ephemeral action. + phantom: true, + syntax: SyntaxType::PrivateBinary, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_PATCH_LEVEL_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_PATCH_LEVEL, + name: Attribute::PatchLevel, + description: "".to_string(), + syntax: SyntaxType::Uint32, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_DEVELOPMENT_TAINT_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_DEVELOPMENT_TAINT, + name: Attribute::DomainDevelopmentTaint, + description: "A flag to show that the domain has been run on a development build, and will need additional work to upgrade/migrate.".to_string(), + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_DOMAIN_ALLOW_EASTER_EGGS_DL9: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_DOMAIN_ALLOW_EASTER_EGGS, + name: Attribute::DomainAllowEasterEggs, + description: "A flag to enable easter eggs in the server that may not always be wanted by all users/deployments.".to_string(), + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_REFERS_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_REFERS, + name: Attribute::Refers, + description: "A reference to linked object".to_string(), + multivalue: false, + syntax: SyntaxType::ReferenceUuid, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_LINKED_GROUP_DL8: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_LINKED_GROUP, + name: Attribute::LinkedGroup, + description: "A reference linking a group to an entry".to_string(), + + multivalue: false, + syntax: SyntaxType::ReferenceUuid, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK_DL8: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK, + name: Attribute::AllowPrimaryCredFallback, + description: "Allow fallback to primary password if no POSIX password exists".to_string(), + + multivalue: false, + syntax: SyntaxType::Boolean, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_CERTIFICATE_DL7: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_CERTIFICATE, + name: Attribute::Certificate, + description: "An x509 Certificate".to_string(), + multivalue: false, + syntax: SyntaxType::Certificate, + ..Default::default() +}; + +pub static ref SCHEMA_ATTR_APPLICATION_PASSWORD_DL8: SchemaAttribute = SchemaAttribute { + uuid: UUID_SCHEMA_ATTR_APPLICATION_PASSWORD, + name: Attribute::ApplicationPassword, + description: "A set of application passwords".to_string(), + + multivalue: true, + syntax: SyntaxType::ApplicationPassword, + ..Default::default() +}; + +// === classes === + +pub static ref SCHEMA_CLASS_PERSON: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_PERSON, + name: EntryClass::Person.into(), + description: "Object representation of a person".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::Mail, + Attribute::LegalName, + ], + systemmust: vec![ + Attribute::DisplayName, + Attribute::Name, + Attribute::IdVerificationEcKey], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_PERSON_DL5: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_PERSON, + name: EntryClass::Person.into(), + description: "Object representation of a person".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::PrimaryCredential, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::CredentialUpdateIntentToken, + Attribute::SshPublicKey, + Attribute::RadiusSecret, + Attribute::OAuth2ConsentScopeMap, + Attribute::UserAuthTokenSession, + Attribute::OAuth2Session, + Attribute::Mail, + Attribute::LegalName, + ], + systemmust: vec![ + Attribute::IdVerificationEcKey + ], + systemexcludes: vec![EntryClass::ServiceAccount.into(), EntryClass::Application.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_PERSON_DL8: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_PERSON, + name: EntryClass::Person.into(), + description: "Object representation of a person".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::PrimaryCredential, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::CredentialUpdateIntentToken, + Attribute::SshPublicKey, + Attribute::RadiusSecret, + Attribute::OAuth2ConsentScopeMap, + Attribute::UserAuthTokenSession, + Attribute::OAuth2Session, + Attribute::Mail, + Attribute::LegalName, + Attribute::ApplicationPassword, + ], + systemmust: vec![ + Attribute::IdVerificationEcKey + ], + systemexcludes: vec![EntryClass::ServiceAccount.into(), EntryClass::Application.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_ORGPERSON: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_ORGPERSON, + name: EntryClass::OrgPerson.into(), + description: "Object representation of an org person".to_string(), + + systemmay: vec![ + Attribute::LegalName + ], + systemmust: vec![ + Attribute::Mail, + Attribute::DisplayName, + Attribute::Name + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_GROUP_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_GROUP, + name: EntryClass::Group.into(), + description: "Object representation of a group".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::Member, + Attribute::GrantUiHint, + Attribute::Description, + Attribute::Mail, + ], + systemmust: vec![ + Attribute::Name, + Attribute::Spn], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_DYNGROUP: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_DYNGROUP, + name: EntryClass::DynGroup.into(), + description: "Object representation of a dynamic group".to_string(), + + systemmust: vec![Attribute::DynGroupFilter], + systemmay: vec![Attribute::DynMember], + systemsupplements: vec![Attribute::Group.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_ACCOUNT_POLICY_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_ACCOUNT_POLICY, + name: EntryClass::AccountPolicy.into(), + description: "Policies applied to accounts that are members of a group".to_string(), + + systemmay: vec![ + Attribute::AuthSessionExpiry, + Attribute::PrivilegeExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + ], + systemsupplements: vec![Attribute::Group.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_ACCOUNT_POLICY_DL8: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_ACCOUNT_POLICY, + name: EntryClass::AccountPolicy.into(), + description: "Policies applied to accounts that are members of a group".to_string(), + + systemmay: vec![ + Attribute::AuthSessionExpiry, + Attribute::PrivilegeExpiry, + Attribute::AuthPasswordMinimumLength, + Attribute::CredentialTypeMinimum, + Attribute::WebauthnAttestationCaList, + Attribute::LimitSearchMaxResults, + Attribute::LimitSearchMaxFilterTest, + Attribute::AllowPrimaryCredFallback, + ], + systemsupplements: vec![Attribute::Group.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_ACCOUNT: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_ACCOUNT, + name: EntryClass::Account.into(), + description: "Object representation of an account".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::PrimaryCredential, + Attribute::PassKeys, + Attribute::AttestedPasskeys, + Attribute::CredentialUpdateIntentToken, + Attribute::SshPublicKey, + Attribute::RadiusSecret, + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::Mail, + Attribute::OAuth2ConsentScopeMap, + Attribute::UserAuthTokenSession, + Attribute::OAuth2Session, + Attribute::Description, + Attribute::NameHistory, + ], + systemmust: vec![ + Attribute::DisplayName, + Attribute::Name, + Attribute::Spn + ], + systemsupplements: vec![ + EntryClass::Person.into(), + EntryClass::ServiceAccount.into(), + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_ACCOUNT_DL5: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_ACCOUNT, + name: EntryClass::Account.into(), + description: "Object representation of an account".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::AccountExpire, + Attribute::AccountValidFrom, + Attribute::NameHistory, + ], + systemmust: vec![ + Attribute::DisplayName, + Attribute::Name, + Attribute::Spn + ], + systemsupplements: vec![ + EntryClass::Person.into(), + EntryClass::ServiceAccount.into(), + EntryClass::OAuth2ResourceServer.into(), + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_SERVICE_ACCOUNT_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_SERVICE_ACCOUNT, + name: EntryClass::ServiceAccount.into(), + description: "Object representation of service account".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::SshPublicKey, + Attribute::UserAuthTokenSession, + Attribute::OAuth2Session, + Attribute::OAuth2ConsentScopeMap, + Attribute::Description, + + Attribute::Mail, + Attribute::PrimaryCredential, + Attribute::ApiTokenSession, + + Attribute::JwsEs256PrivateKey, + ], + systemexcludes: vec![EntryClass::Person.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_SERVICE_ACCOUNT_DL7: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_SERVICE_ACCOUNT, + name: EntryClass::ServiceAccount.into(), + description: "Object representation of service account".to_string(), + + sync_allowed: true, + systemmay: vec![ + Attribute::SshPublicKey, + Attribute::UserAuthTokenSession, + Attribute::OAuth2Session, + Attribute::OAuth2ConsentScopeMap, + Attribute::Description, + + Attribute::Mail, + Attribute::PrimaryCredential, + Attribute::ApiTokenSession, + ], + systemexcludes: vec![EntryClass::Person.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_SYNC_ACCOUNT_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_SYNC_ACCOUNT, + name: EntryClass::SyncAccount.into(), + description: "Object representation of sync account".to_string(), + + systemmust: vec![Attribute::Name], + systemmay: vec![ + Attribute::SyncTokenSession, + Attribute::SyncCookie, + Attribute::SyncCredentialPortal, + Attribute::SyncYieldAuthority, + Attribute::JwsEs256PrivateKey, + ], + systemexcludes: vec![EntryClass::Account.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_SYNC_ACCOUNT_DL7: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_SYNC_ACCOUNT, + name: EntryClass::SyncAccount.into(), + description: "Object representation of sync account".to_string(), + + systemmust: vec![Attribute::Name], + systemmay: vec![ + Attribute::SyncTokenSession, + Attribute::SyncCookie, + Attribute::SyncCredentialPortal, + Attribute::SyncYieldAuthority, + ], + systemexcludes: vec![EntryClass::Account.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO, + name: EntryClass::DomainInfo.into(), + description: "Local domain information and configuration".to_string(), + + systemmay: vec![ + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::LdapAllowUnixPwBind, + Attribute::PrivateCookieKey, + Attribute::FernetPrivateKeyStr, + Attribute::Es256PrivateKeyDer, + Attribute::PatchLevel, + Attribute::DomainDevelopmentTaint, + ], + systemmust: vec![ + Attribute::Name, + Attribute::DomainUuid, + Attribute::DomainName, + Attribute::DomainDisplayName, + Attribute::Version, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL7: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO, + name: EntryClass::DomainInfo.into(), + description: "Local domain information and configuration".to_string(), + + systemmay: vec![ + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::LdapAllowUnixPwBind, + Attribute::PatchLevel, + Attribute::DomainDevelopmentTaint, + ], + systemmust: vec![ + Attribute::Name, + Attribute::DomainUuid, + Attribute::DomainName, + Attribute::DomainDisplayName, + Attribute::Version, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL8: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO, + name: EntryClass::DomainInfo.into(), + description: "Local domain information and configuration".to_string(), + + systemmay: vec![ + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::LdapAllowUnixPwBind, + Attribute::Image, + Attribute::PatchLevel, + Attribute::DomainDevelopmentTaint, + ], + systemmust: vec![ + Attribute::Name, + Attribute::DomainUuid, + Attribute::DomainName, + Attribute::DomainDisplayName, + Attribute::Version, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL9: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO, + name: EntryClass::DomainInfo.into(), + description: "Local domain information and configuration".to_string(), + + systemmay: vec![ + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::LdapAllowUnixPwBind, + Attribute::Image, + Attribute::PatchLevel, + Attribute::DomainDevelopmentTaint, + Attribute::DomainAllowEasterEggs, + ], + systemmust: vec![ + Attribute::Name, + Attribute::DomainUuid, + Attribute::DomainName, + Attribute::DomainDisplayName, + Attribute::Version, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL10: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO, + name: EntryClass::DomainInfo.into(), + description: "Local domain information and configuration".to_string(), + + systemmay: vec![ + Attribute::DomainSsid, + Attribute::DomainLdapBasedn, + Attribute::LdapAllowUnixPwBind, + Attribute::Image, + Attribute::PatchLevel, + Attribute::DomainDevelopmentTaint, + Attribute::DomainAllowEasterEggs, + Attribute::DomainDisplayName, + ], + systemmust: vec![ + Attribute::Name, + Attribute::DomainUuid, + Attribute::DomainName, + Attribute::Version, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_POSIXGROUP: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_POSIXGROUP, + name: EntryClass::PosixGroup.into(), + description: "Object representation of a posix group, requires group".to_string(), + + sync_allowed: true, + systemmust: vec![Attribute::GidNumber], + systemsupplements: vec![Attribute::Group.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_POSIXACCOUNT: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_POSIXACCOUNT, + name: EntryClass::PosixAccount.into(), + description: "Object representation of a posix account, requires account".to_string(), + + sync_allowed: true, + systemmay: vec![Attribute::LoginShell, Attribute::UnixPassword], + systemmust: vec![Attribute::GidNumber], + systemsupplements: vec![Attribute::Account.into()], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_SYSTEM_CONFIG: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_SYSTEM_CONFIG, + name: EntryClass::SystemConfig.into(), + description: "The class representing a system (topologies) configuration options".to_string(), + + systemmay: vec![ + Attribute::Description, + Attribute::BadlistPassword, + Attribute::AuthSessionExpiry, + Attribute::PrivilegeExpiry, + Attribute::DeniedName + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_OAUTH2_RS_DL4: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_OAUTH2_RS, + name: EntryClass::OAuth2ResourceServer.into(), + description: "The class representing a configured Oauth2 Resource Server".to_string(), + + systemmay: vec![ + Attribute::Description, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2RsOriginLanding, + Attribute::Image, + Attribute::OAuth2RsClaimMap, + ], + systemmust: vec![ + Attribute::OAuth2RsName, + Attribute::DisplayName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_OAUTH2_RS_DL5: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_OAUTH2_RS, + name: EntryClass::OAuth2ResourceServer.into(), + description: "The class representing a configured Oauth2 Resource Server".to_string(), + + systemmay: vec![ + Attribute::Description, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2RsOriginLanding, + Attribute::Image, + Attribute::OAuth2RsClaimMap, + Attribute::OAuth2Session, + ], + systemmust: vec![ + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_OAUTH2_RS_DL7: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_OAUTH2_RS, + name: EntryClass::OAuth2ResourceServer.into(), + description: "The class representing a configured OAuth2 Client".to_string(), + + systemmay: vec![ + Attribute::Description, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::Image, + Attribute::OAuth2RsClaimMap, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2StrictRedirectUri, + ], + systemmust: vec![ + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_OAUTH2_RS_DL9: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_OAUTH2_RS, + name: EntryClass::OAuth2ResourceServer.into(), + description: "The class representing a configured OAuth2 Client".to_string(), + + systemmay: vec![ + Attribute::Description, + Attribute::OAuth2RsScopeMap, + Attribute::OAuth2RsSupScopeMap, + Attribute::Rs256PrivateKeyDer, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::Image, + Attribute::OAuth2RsClaimMap, + Attribute::OAuth2Session, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2StrictRedirectUri, + Attribute::OAuth2DeviceFlowEnable, + ], + systemmust: vec![ + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsTokenKey, + Attribute::Es256PrivateKeyDer, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_OAUTH2_RS_BASIC_DL5: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_OAUTH2_RS_BASIC, + name: EntryClass::OAuth2ResourceServerBasic.into(), + description: "The class representing a configured OAuth2 client authenticated with HTTP basic authentication".to_string(), + + systemmay: vec![ + Attribute::OAuth2AllowInsecureClientDisablePkce, + ], + systemmust: vec![ Attribute::OAuth2RsBasicSecret], + systemexcludes: vec![ EntryClass::OAuth2ResourceServerPublic.into()], + ..Default::default() +}; + +// Introduced in DomainLevel4 +pub static ref SCHEMA_CLASS_OAUTH2_RS_PUBLIC_DL4: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_OAUTH2_RS_PUBLIC, + name: EntryClass::OAuth2ResourceServerPublic.into(), + description: "The class representing a configured Public OAuth2 Client with PKCE verification".to_string(), + + systemmay: vec![Attribute::OAuth2AllowLocalhostRedirect], + systemexcludes: vec![EntryClass::OAuth2ResourceServerBasic.into()], + ..Default::default() +}; + +// ========================================= +// KeyProviders + +pub static ref SCHEMA_CLASS_KEY_PROVIDER_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_KEY_PROVIDER, + name: EntryClass::KeyProvider.into(), + description: "A provider for cryptographic key storage and operations".to_string(), + systemmay: vec![ + Attribute::Description, + ], + systemmust: vec![ + Attribute::Name, + ], + systemsupplements: vec![ + EntryClass::KeyProviderInternal.into(), + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_KEY_PROVIDER_INTERNAL_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_KEY_PROVIDER_INTERNAL, + name: EntryClass::KeyProviderInternal.into(), + description: "The Kanidm internal cryptographic key provider".to_string(), + ..Default::default() +}; + +// ========================================= +// KeyObjects + +pub static ref SCHEMA_CLASS_KEY_OBJECT_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_KEY_OBJECT, + name: EntryClass::KeyObject.into(), + description: "A cryptographic key object that can be used by a provider".to_string(), + systemmust: vec![ + Attribute::KeyProvider, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_KEY_OBJECT_JWT_ES256_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_KEY_OBJECT_JWT_ES256, + name: EntryClass::KeyObjectJwtEs256.into(), + description: "A marker class indicating that this keyobject must provide jwt es256 capability.".to_string(), + systemsupplements: vec![ + EntryClass::KeyObject.into(), + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_KEY_OBJECT_JWE_A128GCM_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_KEY_OBJECT_JWE_A128GCM, + name: EntryClass::KeyObjectJweA128GCM.into(), + description: "A marker class indicating that this keyobject must provide jwe aes-256-gcm capability.".to_string(), + systemsupplements: vec![ + EntryClass::KeyObject.into(), + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_KEY_OBJECT_INTERNAL_DL6: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_KEY_OBJECT_INTERNAL, + name: EntryClass::KeyObjectInternal.into(), + description: "A cryptographic key object that can be used by the internal provider".to_string(), + systemmay: vec![ + Attribute::KeyInternalData, + ], + systemsupplements: vec![ + EntryClass::KeyObject.into(), + ], + ..Default::default() +}; + +// ========================================= + +pub static ref SCHEMA_CLASS_CLIENT_CERTIFICATE_DL7: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_CLIENT_CERTIFICATE, + name: EntryClass::ClientCertificate.into(), + description: "A client authentication certificate".to_string(), + systemmay: vec![], + systemmust: vec![ + Attribute::Certificate, + Attribute::Refers, + ], + ..Default::default() +}; + +pub static ref SCHEMA_CLASS_APPLICATION_DL8: SchemaClass = SchemaClass { + uuid: UUID_SCHEMA_CLASS_APPLICATION, + name: EntryClass::Application.into(), + + description: "The class representing an application".to_string(), + systemmust: vec![Attribute::Name, Attribute::LinkedGroup], + systemmay: vec![Attribute::Description], + systemsupplements: vec![EntryClass::ServiceAccount.into()], + ..Default::default() +}; + +); diff --git a/server/lib/src/migration_data/dl9/system_config.rs b/server/lib/src/migration_data/dl9/system_config.rs new file mode 100644 index 000000000..107bd8bbe --- /dev/null +++ b/server/lib/src/migration_data/dl9/system_config.rs @@ -0,0 +1,1073 @@ +use crate::constants::uuids::*; + +use crate::entry::{Entry, EntryInit, EntryInitNew, EntryNew}; +use crate::prelude::{Attribute, EntryClass}; +use crate::value::Value; + +// Default entries for system_config +// This is separated because the password badlist section may become very long + +lazy_static! { + pub static ref E_SYSTEM_INFO_V1: EntryInitNew = entry_init!( + (Attribute::Class, EntryClass::Object.to_value()), + (Attribute::Class, EntryClass::SystemInfo.to_value()), + (Attribute::Class, EntryClass::System.to_value()), + (Attribute::Uuid, Value::Uuid(UUID_SYSTEM_INFO)), + ( + Attribute::Description, + Value::new_utf8s("System (local) info and metadata object.") + ), + (Attribute::Version, Value::Uint32(20)) + ); + pub static ref E_DOMAIN_INFO_DL6: EntryInitNew = entry_init!( + (Attribute::Class, EntryClass::Object.to_value()), + (Attribute::Class, EntryClass::DomainInfo.to_value()), + (Attribute::Class, EntryClass::System.to_value()), + (Attribute::Class, EntryClass::KeyObject.to_value()), + (Attribute::Class, EntryClass::KeyObjectJwtEs256.to_value()), + (Attribute::Class, EntryClass::KeyObjectJweA128GCM.to_value()), + (Attribute::Name, Value::new_iname("domain_local")), + (Attribute::Uuid, Value::Uuid(UUID_DOMAIN_INFO)), + ( + Attribute::Description, + Value::new_utf8s("This local domain's info and metadata object.") + ) + ); + pub static ref E_SYSTEM_CONFIG_V1: EntryInitNew = entry_init!( + (Attribute::Class, EntryClass::Object.to_value()), + (Attribute::Class, EntryClass::SystemConfig.to_value()), + (Attribute::Class, EntryClass::System.to_value()), + (Attribute::Uuid, Value::Uuid(UUID_SYSTEM_CONFIG)), + ( + Attribute::Description, + Value::new_utf8s("System (replicated) configuration options.") + ), + ( + Attribute::BadlistPassword, + Value::new_iutf8("bad@no3IBTyqHu$list") + ), + ( + Attribute::BadlistPassword, + Value::new_iutf8( + "demo_badlist_shohfie3aeci2oobur0aru9uushah6EiPi2woh4hohngoighaiRuepieN3ongoo1" + ) + ), + ( + Attribute::BadlistPassword, + Value::new_iutf8("100preteamare") + ), + (Attribute::BadlistPassword, Value::new_iutf8("14defebrero")), + (Attribute::BadlistPassword, Value::new_iutf8("1life1love")), + (Attribute::BadlistPassword, Value::new_iutf8("1life2live")), + (Attribute::BadlistPassword, Value::new_iutf8("1love1life")), + (Attribute::BadlistPassword, Value::new_iutf8("1love4life")), + (Attribute::BadlistPassword, Value::new_iutf8("212224236248")), + (Attribute::BadlistPassword, Value::new_iutf8("2813308004")), + ( + Attribute::BadlistPassword, + Value::new_iutf8("2fast2furious") + ), + (Attribute::BadlistPassword, Value::new_iutf8("2gether4ever")), + (Attribute::BadlistPassword, Value::new_iutf8("2pacshakur")), + ( + Attribute::BadlistPassword, + Value::new_iutf8("30secondstomars") + ), + (Attribute::BadlistPassword, Value::new_iutf8("3doorsdown")), + (Attribute::BadlistPassword, Value::new_iutf8("6cyclemind")), + ( + Attribute::BadlistPassword, + Value::new_iutf8("
, + pub name: &'static str, + pub uuid: Uuid, + pub description: &'static str, + pub displayname: &'static str, +} + +#[cfg(test)] +impl Default for BuiltinAccount { + fn default() -> Self { + BuiltinAccount { + account_type: AccountType::ServiceAccount, + entry_managed_by: None, + name: "", + uuid: Uuid::new_v4(), + description: "", + displayname: "", + } + } +} + +#[cfg(test)] +impl From for crate::idm::account::Account { + fn from(value: BuiltinAccount) -> Self { + Self { + name: value.name.to_string(), + uuid: value.uuid, + displayname: value.displayname.to_string(), + spn: format!("{}@example.com", value.name), + mail_primary: None, + mail: Vec::with_capacity(0), + ..Default::default() + } + } +} + +impl From for EntryInitNew { + fn from(value: BuiltinAccount) -> Self { + let mut entry = EntryInitNew::new(); + 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::Description, Value::new_utf8s(value.description)); + entry.add_ava(Attribute::DisplayName, Value::new_utf8s(value.displayname)); + + if let Some(entry_manager) = value.entry_managed_by { + entry.add_ava(Attribute::EntryManagedBy, Value::Refer(entry_manager)); + } + + entry.set_ava( + Attribute::Class, + vec![ + EntryClass::Account.to_value(), + EntryClass::MemberOf.to_value(), + EntryClass::Object.to_value(), + ], + ); + match value.account_type { + AccountType::Person => entry.add_ava(Attribute::Class, EntryClass::Person.to_value()), + AccountType::ServiceAccount => { + entry.add_ava(Attribute::Class, EntryClass::ServiceAccount.to_value()) + } + } + entry + } +} diff --git a/server/lib/src/server/access/mod.rs b/server/lib/src/server/access/mod.rs index 4847bfa37..956bcb512 100644 --- a/server/lib/src/server/access/mod.rs +++ b/server/lib/src/server/access/mod.rs @@ -1159,6 +1159,7 @@ mod tests { }, Access, AccessClass, AccessControls, AccessControlsTransaction, AccessEffectivePermission, }; + use crate::migration_data::BUILTIN_ACCOUNT_ANONYMOUS; use crate::prelude::*; use crate::valueset::ValueSetIname; @@ -2511,6 +2512,7 @@ mod tests { #[test] fn test_access_enforce_scope_delete() { + sketching::test_init(); let ev1 = E_TESTPERSON_1.clone().into_sealed_committed(); let r_set = vec![Arc::new(ev1)]; @@ -3052,7 +3054,7 @@ mod tests { test_acp_search_reduce!(&se_a, vec![], r_set.clone(), ex_a_reduced); // Check that anonymous is denied even though it's a member of the group. - let anon: EntryInitNew = BUILTIN_ACCOUNT_ANONYMOUS_DL6.clone().into(); + let anon: EntryInitNew = BUILTIN_ACCOUNT_ANONYMOUS.clone().into(); let mut anon = anon.into_invalid_new(); anon.set_ava_set(&Attribute::MemberOf, ValueSetRefer::new(UUID_TEST_GROUP_1)); @@ -3352,7 +3354,7 @@ mod tests { #[test] fn test_access_delete_protect_system_ranges() { - let ev1: EntryInitNew = BUILTIN_ACCOUNT_ANONYMOUS_DL6.clone().into(); + let ev1: EntryInitNew = BUILTIN_ACCOUNT_ANONYMOUS.clone().into(); let ev1 = ev1.into_sealed_committed(); let r_set = vec![Arc::new(ev1)]; diff --git a/server/lib/src/server/migrations.rs b/server/lib/src/server/migrations.rs index a1535d483..b53afa579 100644 --- a/server/lib/src/server/migrations.rs +++ b/server/lib/src/server/migrations.rs @@ -1,5 +1,6 @@ use crate::prelude::*; +use crate::migration_data; use kanidm_proto::internal::{ DomainUpgradeCheckItem as ProtoDomainUpgradeCheckItem, DomainUpgradeCheckReport as ProtoDomainUpgradeCheckReport, @@ -48,17 +49,24 @@ impl QueryServer { debug!(?db_domain_version, "Before setting internal domain info"); if db_domain_version == 0 { - // No domain info was present, so neither was the rest of the IDM. We need to bootstrap - // the base-schema here. - write_txn.initialise_schema_idm()?; + // This is here to catch when we increase domain levels but didn't create the migration + // hooks. If this fails it probably means you need to add another migration hook + // in the above. + debug_assert!(domain_target_level <= DOMAIN_MAX_LEVEL); - write_txn.reload()?; - - // Since we just loaded in a ton of schema, lets reindex it to make - // sure that some base IDM operations are fast. Since this is still - // very early in the bootstrap process, and very few entries exist, - // reindexing is very fast here. - write_txn.reindex(false)?; + // No domain info was present, so neither was the rest of the IDM. Bring up the + // full IDM here. + match domain_target_level { + DOMAIN_LEVEL_8 => write_txn.migrate_domain_7_to_8()?, + DOMAIN_LEVEL_9 => write_txn.migrate_domain_8_to_9()?, + DOMAIN_LEVEL_10 => write_txn.migrate_domain_9_to_10()?, + DOMAIN_LEVEL_11 => write_txn.migrate_domain_10_to_11()?, + _ => { + error!("Invalid requested domain target level for server bootstrap"); + debug_assert!(false); + return Err(OperationError::MG0009InvalidTargetLevelForBootstrap); + } + } } else { // Domain info was present, so we need to reflect that in our server // domain structures. If we don't do this, the in memory domain level @@ -71,23 +79,11 @@ impl QueryServer { write_txn.force_domain_reload(); write_txn.reload()?; - } - // Indicate the schema is now ready, which allows dyngroups to work when they - // are created in the next phase of migrations. - write_txn.set_phase(ServerPhase::SchemaReady); + // Indicate the schema is now ready, which allows dyngroups to work when they + // are created in the next phase of migrations. + write_txn.set_phase(ServerPhase::SchemaReady); - // No domain info was present, so neither was the rest of the IDM. We need to bootstrap - // the base entries here. - if db_domain_version == 0 { - // Init idm will now set the system config version and minimum domain - // level if none was present - write_txn.initialise_domain_info()?; - - // In this path because we create the dyn groups they are immediately added to the - // dyngroup cache and begin to operate. - write_txn.initialise_idm()?; - } else { // #2756 - if we *aren't* creating the base IDM entries, then we // need to force dyn groups to reload since we're now at schema // ready. This is done indirectly by ... reloading the schema again. @@ -97,13 +93,13 @@ impl QueryServer { // itself or a change to schema reloading. Since we aren't changing the // dyngroup here, we have to go via the schema reload path. write_txn.force_schema_reload(); - }; - // Reload as init idm affects access controls. - write_txn.reload()?; + // Reload as init idm affects access controls. + write_txn.reload()?; - // Domain info is now ready and reloaded, we can proceed. - write_txn.set_phase(ServerPhase::DomainInfoReady); + // Domain info is now ready and reloaded, we can proceed. + write_txn.set_phase(ServerPhase::DomainInfoReady); + } // This is the start of domain info related migrations which we will need in future // to handle replication. Due to the access control rework, and the addition of "managed by" @@ -126,20 +122,18 @@ impl QueryServer { // If the database domain info is a lower version than our target level, we reload. if domain_info_version < domain_target_level { write_txn - .internal_modify_uuid( - UUID_DOMAIN_INFO, - &ModifyList::new_purge_and_set( - Attribute::Version, - Value::new_uint32(domain_target_level), - ), - ) + .internal_apply_domain_migration(domain_target_level) .map(|()| { warn!("Domain level has been raised to {}", domain_target_level); })?; - // Reload if anything in migrations requires it - this triggers the domain migrations - // which in turn can trigger schema reloads etc. - reload_required = true; + // which in turn can trigger schema reloads etc. If the server was just brought up + // then we don't need the extra reload since we are already at the correct + // version of the server, and this call to set the target level is just for persistance + // of the value. + if domain_info_version != 0 { + reload_required = true; + } } else if domain_development_taint { // This forces pre-release versions to re-migrate each start up. This solves // the domain-version-sprawl issue so that during a development cycle we can @@ -182,9 +176,6 @@ impl QueryServer { // we would have skipped the patch level fix which needs to have occurred *first*. if reload_required { write_txn.reload()?; - // We are not yet at the schema phase where reindexes will auto-trigger - // so if one was required, do it now. - write_txn.reindex(false)?; } // Now set the db/domain devel taint flag to match our current release status @@ -206,7 +197,8 @@ impl QueryServer { // We are ready to run write_txn.set_phase(ServerPhase::Running); - // Commit all changes, this also triggers the reload. + // Commit all changes, this also triggers the final reload, this should be a no-op + // since we already did all the needed loads above. write_txn.commit()?; debug!("Database version check and migrations success! ☀️ "); @@ -217,7 +209,6 @@ impl QueryServer { impl QueryServerWriteTransaction<'_> { /// Apply a domain migration `to_level`. Panics if `to_level` is not greater than the active /// level. - #[cfg(test)] pub(crate) fn internal_apply_domain_migration( &mut self, to_level: u32, @@ -230,6 +221,23 @@ impl QueryServerWriteTransaction<'_> { .and_then(|()| self.reload()) } + fn internal_migrate_or_create_batch( + &mut self, + msg: &str, + entries: Vec, + ) -> Result<(), OperationError> { + let r: Result<(), _> = entries + .into_iter() + .try_for_each(|entry| self.internal_migrate_or_create(entry)); + + if let Err(err) = r { + error!(?err, msg); + debug_assert!(false); + } + + Ok(()) + } + #[instrument(level = "debug", skip_all)] /// - If the thing exists: /// - Ensure the set of attributes match and are present @@ -240,7 +248,7 @@ impl QueryServerWriteTransaction<'_> { /// This will extra classes an attributes alone! /// /// NOTE: `gen_modlist*` IS schema aware and will handle multivalue correctly! - pub fn internal_migrate_or_create( + fn internal_migrate_or_create( &mut self, e: Entry, ) -> Result<(), OperationError> { @@ -251,7 +259,7 @@ impl QueryServerWriteTransaction<'_> { /// list of attributes, so that if an admin has modified those values then we don't /// stomp them. #[instrument(level = "trace", skip_all)] - pub fn internal_migrate_or_create_ignore_attrs( + fn internal_migrate_or_create_ignore_attrs( &mut self, mut e: Entry, attrs: &[Attribute], @@ -294,6 +302,75 @@ impl QueryServerWriteTransaction<'_> { } } + /// Migration domain level 7 to 8 (1.4.0) + #[instrument(level = "info", skip_all)] + pub(crate) fn migrate_domain_7_to_8(&mut self) -> Result<(), OperationError> { + if !cfg!(test) && DOMAIN_TGT_LEVEL < DOMAIN_LEVEL_9 { + error!("Unable to raise domain level from 8 to 9."); + return Err(OperationError::MG0004DomainLevelInDevelopment); + } + + // =========== Apply changes ============== + self.internal_migrate_or_create_batch( + "phase 1 - schema attrs", + migration_data::dl8::phase_1_schema_attrs(), + )?; + + self.internal_migrate_or_create_batch( + "phase 2 - schema classes", + migration_data::dl8::phase_2_schema_classes(), + )?; + + // Reload for the new schema. + self.reload()?; + + // Reindex? + self.reindex(false)?; + + // Set Phase + self.set_phase(ServerPhase::SchemaReady); + + self.internal_migrate_or_create_batch( + "phase 3 - key provider", + migration_data::dl8::phase_3_key_provider(), + )?; + + // Reload for the new key providers + self.reload()?; + + self.internal_migrate_or_create_batch( + "phase 4 - system entries", + migration_data::dl8::phase_4_system_entries(), + )?; + + // Reload for the new system entries + self.reload()?; + + // Domain info is now ready and reloaded, we can proceed. + self.set_phase(ServerPhase::DomainInfoReady); + + // Bring up the IDM entries. + self.internal_migrate_or_create_batch( + "phase 5 - builtin admin entries", + migration_data::dl8::phase_5_builtin_admin_entries()?, + )?; + + self.internal_migrate_or_create_batch( + "phase 6 - builtin not admin entries", + migration_data::dl8::phase_6_builtin_non_admin_entries()?, + )?; + + self.internal_migrate_or_create_batch( + "phase 7 - builtin access control profiles", + migration_data::dl8::phase_7_builtin_access_control_profiles(), + )?; + + // Reload for all new access controls. + self.reload()?; + + Ok(()) + } + /// Migration domain level 8 to 9 (1.5.0) #[instrument(level = "info", skip_all)] pub(crate) fn migrate_domain_8_to_9(&mut self) -> Result<(), OperationError> { @@ -303,39 +380,61 @@ impl QueryServerWriteTransaction<'_> { } // =========== Apply changes ============== + self.internal_migrate_or_create_batch( + "phase 1 - schema attrs", + migration_data::dl9::phase_1_schema_attrs(), + )?; - // Now update schema - let idm_schema_changes = [ - SCHEMA_ATTR_OAUTH2_DEVICE_FLOW_ENABLE_DL9.clone().into(), - SCHEMA_ATTR_DOMAIN_ALLOW_EASTER_EGGS_DL9.clone().into(), - SCHEMA_CLASS_OAUTH2_RS_DL9.clone().into(), - SCHEMA_CLASS_DOMAIN_INFO_DL9.clone().into(), - ]; - - idm_schema_changes - .into_iter() - .try_for_each(|entry| self.internal_migrate_or_create(entry)) - .map_err(|err| { - error!(?err, "migrate_domain_8_to_9 -> Error"); - err - })?; + self.internal_migrate_or_create_batch( + "phase 2 - schema classes", + migration_data::dl9::phase_2_schema_classes(), + )?; + // Reload for the new schema. self.reload()?; - let idm_data = [ - IDM_ACP_OAUTH2_MANAGE_DL9.clone().into(), - IDM_ACP_GROUP_MANAGE_DL9.clone().into(), - IDM_ACP_DOMAIN_ADMIN_DL9.clone().into(), - ]; + // Reindex? + self.reindex(false)?; - idm_data - .into_iter() - .try_for_each(|entry| self.internal_migrate_or_create(entry)) - .map_err(|err| { - error!(?err, "migrate_domain_8_to_9 -> Error"); - err - })?; + // Set Phase + self.set_phase(ServerPhase::SchemaReady); + self.internal_migrate_or_create_batch( + "phase 3 - key provider", + migration_data::dl9::phase_3_key_provider(), + )?; + + // Reload for the new key providers + self.reload()?; + + self.internal_migrate_or_create_batch( + "phase 4 - system entries", + migration_data::dl9::phase_4_system_entries(), + )?; + + // Reload for the new system entries + self.reload()?; + + // Domain info is now ready and reloaded, we can proceed. + self.set_phase(ServerPhase::DomainInfoReady); + + // Bring up the IDM entries. + self.internal_migrate_or_create_batch( + "phase 5 - builtin admin entries", + migration_data::dl9::phase_5_builtin_admin_entries()?, + )?; + + self.internal_migrate_or_create_batch( + "phase 6 - builtin not admin entries", + migration_data::dl9::phase_6_builtin_non_admin_entries()?, + )?; + + self.internal_migrate_or_create_batch( + "phase 7 - builtin access control profiles", + migration_data::dl9::phase_7_builtin_access_control_profiles(), + )?; + + // Reload for all new access controls. self.reload()?; Ok(()) @@ -350,58 +449,7 @@ impl QueryServerWriteTransaction<'_> { debug_assert!(*self.phase >= ServerPhase::SchemaReady); - let idm_data = [ - IDM_ACP_ACCOUNT_MAIL_READ_DL6.clone().into(), - IDM_ACP_ACCOUNT_SELF_WRITE_V1.clone().into(), - IDM_ACP_ACCOUNT_UNIX_EXTEND_V1.clone().into(), - IDM_ACP_ACP_MANAGE_V1.clone().into(), - IDM_ACP_ALL_ACCOUNTS_POSIX_READ_V1.clone().into(), - IDM_ACP_APPLICATION_ENTRY_MANAGER_DL8.clone().into(), - IDM_ACP_APPLICATION_MANAGE_DL8.clone().into(), - IDM_ACP_DOMAIN_ADMIN_DL8.clone().into(), - IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE_DL8.clone().into(), - IDM_ACP_GROUP_ENTRY_MANAGED_BY_MODIFY_V1.clone().into(), - IDM_ACP_GROUP_ENTRY_MANAGER_V1.clone().into(), - IDM_ACP_GROUP_MANAGE_DL6.clone().into(), - IDM_ACP_GROUP_READ_V1.clone().into(), - IDM_ACP_GROUP_UNIX_MANAGE_V1.clone().into(), - IDM_ACP_HP_CLIENT_CERTIFICATE_MANAGER_DL7.clone().into(), - IDM_ACP_HP_GROUP_UNIX_MANAGE_V1.clone().into(), - IDM_ACP_HP_PEOPLE_CREDENTIAL_RESET_V1.clone().into(), - IDM_ACP_HP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1 - .clone() - .into(), - IDM_ACP_MAIL_SERVERS_DL8.clone().into(), - IDM_ACP_OAUTH2_MANAGE_DL7.clone().into(), - IDM_ACP_PEOPLE_CREATE_DL6.clone().into(), - IDM_ACP_PEOPLE_CREDENTIAL_RESET_V1.clone().into(), - IDM_ACP_PEOPLE_DELETE_V1.clone().into(), - IDM_ACP_PEOPLE_MANAGE_V1.clone().into(), - IDM_ACP_PEOPLE_PII_MANAGE_V1.clone().into(), - IDM_ACP_PEOPLE_PII_READ_V1.clone().into(), - IDM_ACP_PEOPLE_READ_V1.clone().into(), - IDM_ACP_PEOPLE_SELF_WRITE_MAIL_V1.clone().into(), - IDM_ACP_RADIUS_SECRET_MANAGE_V1.clone().into(), - IDM_ACP_RADIUS_SERVERS_V1.clone().into(), - IDM_ACP_RECYCLE_BIN_REVIVE_V1.clone().into(), - IDM_ACP_RECYCLE_BIN_SEARCH_V1.clone().into(), - IDM_ACP_SCHEMA_WRITE_ATTRS_V1.clone().into(), - IDM_ACP_SCHEMA_WRITE_CLASSES_V1.clone().into(), - IDM_ACP_SELF_NAME_WRITE_DL7.clone().into(), - IDM_ACP_SELF_READ_DL8.clone().into(), - IDM_ACP_SELF_WRITE_DL8.clone().into(), - IDM_ACP_SERVICE_ACCOUNT_CREATE_V1.clone().into(), - IDM_ACP_SERVICE_ACCOUNT_DELETE_V1.clone().into(), - IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1 - .clone() - .into(), - IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGER_V1.clone().into(), - IDM_ACP_SERVICE_ACCOUNT_MANAGE_V1.clone().into(), - IDM_ACP_SYNC_ACCOUNT_MANAGE_V1.clone().into(), - IDM_ACP_SYSTEM_CONFIG_ACCOUNT_POLICY_MANAGE_V1 - .clone() - .into(), - ]; + let idm_data = migration_data::dl9::phase_7_builtin_access_control_profiles(); idm_data .into_iter() @@ -425,21 +473,62 @@ impl QueryServerWriteTransaction<'_> { } // =========== Apply changes ============== + self.internal_migrate_or_create_batch( + "phase 1 - schema attrs", + migration_data::dl10::phase_1_schema_attrs(), + )?; - // Now update schema - let idm_schema_changes = [ - SCHEMA_ATTR_DENIED_NAME_DL10.clone().into(), - SCHEMA_CLASS_DOMAIN_INFO_DL10.clone().into(), - SCHEMA_ATTR_LDAP_MAXIMUM_QUERYABLE_ATTRIBUTES.clone().into(), - ]; + self.internal_migrate_or_create_batch( + "phase 2 - schema classes", + migration_data::dl10::phase_2_schema_classes(), + )?; - idm_schema_changes - .into_iter() - .try_for_each(|entry| self.internal_migrate_or_create(entry)) - .map_err(|err| { - error!(?err, "migrate_domain_9_to_10 -> Error"); - err - })?; + // Reload for the new schema. + self.reload()?; + + // Since we just loaded in a ton of schema, lets reindex it incase we added + // new indexes, or this is a bootstrap and we have no indexes yet. + self.reindex(false)?; + + // Set Phase + // Indicate the schema is now ready, which allows dyngroups to work when they + // are created in the next phase of migrations. + self.set_phase(ServerPhase::SchemaReady); + + self.internal_migrate_or_create_batch( + "phase 3 - key provider", + migration_data::dl10::phase_3_key_provider(), + )?; + + // Reload for the new key providers + self.reload()?; + + self.internal_migrate_or_create_batch( + "phase 4 - system entries", + migration_data::dl10::phase_4_system_entries(), + )?; + + // Reload for the new system entries + self.reload()?; + + // Domain info is now ready and reloaded, we can proceed. + self.set_phase(ServerPhase::DomainInfoReady); + + // Bring up the IDM entries. + self.internal_migrate_or_create_batch( + "phase 5 - builtin admin entries", + migration_data::dl10::phase_5_builtin_admin_entries()?, + )?; + + self.internal_migrate_or_create_batch( + "phase 6 - builtin not admin entries", + migration_data::dl10::phase_6_builtin_non_admin_entries()?, + )?; + + self.internal_migrate_or_create_batch( + "phase 7 - builtin access control profiles", + migration_data::dl10::phase_7_builtin_access_control_profiles(), + )?; self.reload()?; @@ -458,7 +547,7 @@ impl QueryServerWriteTransaction<'_> { } #[instrument(level = "info", skip_all)] - pub fn initialise_schema_core(&mut self) -> Result<(), OperationError> { + pub(crate) fn initialise_schema_core(&mut self) -> Result<(), OperationError> { admin_debug!("initialise_schema_core -> start ..."); // Load in all the "core" schema, that we already have in "memory". let entries = self.schema.to_entries(); @@ -479,320 +568,6 @@ impl QueryServerWriteTransaction<'_> { debug_assert!(r.is_ok()); r } - - #[instrument(level = "info", skip_all)] - pub fn initialise_schema_idm(&mut self) -> Result<(), OperationError> { - 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 = [ - SCHEMA_ATTR_SYNC_CREDENTIAL_PORTAL.clone().into(), - SCHEMA_ATTR_SYNC_YIELD_AUTHORITY.clone().into(), - ]; - - let r: Result<(), _> = idm_schema_attrs - .into_iter() - .try_for_each(|entry| self.internal_migrate_or_create(entry)); - - if r.is_err() { - error!(res = ?r, "initialise_schema_idm -> Error"); - } - debug_assert!(r.is_ok()); - - // ⚠️ DOMAIN LEVEL 1 SCHEMA ATTRIBUTES ⚠️ - // Future schema classes need to be added via migrations. - // - // DO NOT MODIFY THIS DEFINITION - let idm_schema: Vec = vec![ - // SCHEMA_ATTR_MAIL.clone().into(), - SCHEMA_ATTR_ACCOUNT_EXPIRE.clone().into(), - SCHEMA_ATTR_ACCOUNT_VALID_FROM.clone().into(), - SCHEMA_ATTR_API_TOKEN_SESSION.clone().into(), - SCHEMA_ATTR_AUTH_SESSION_EXPIRY.clone().into(), - SCHEMA_ATTR_AUTH_PRIVILEGE_EXPIRY.clone().into(), - SCHEMA_ATTR_AUTH_PASSWORD_MINIMUM_LENGTH.clone().into(), - SCHEMA_ATTR_BADLIST_PASSWORD.clone().into(), - SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN.clone().into(), - SCHEMA_ATTR_ATTESTED_PASSKEYS.clone().into(), - // SCHEMA_ATTR_DISPLAYNAME.clone().into(), - SCHEMA_ATTR_DOMAIN_DISPLAY_NAME.clone().into(), - SCHEMA_ATTR_DOMAIN_LDAP_BASEDN.clone().into(), - SCHEMA_ATTR_DOMAIN_NAME.clone().into(), - SCHEMA_ATTR_LDAP_ALLOW_UNIX_PW_BIND.clone().into(), - SCHEMA_ATTR_DOMAIN_SSID.clone().into(), - SCHEMA_ATTR_DOMAIN_TOKEN_KEY.clone().into(), - SCHEMA_ATTR_DOMAIN_UUID.clone().into(), - SCHEMA_ATTR_DYNGROUP_FILTER.clone().into(), - SCHEMA_ATTR_EC_KEY_PRIVATE.clone().into(), - SCHEMA_ATTR_ES256_PRIVATE_KEY_DER.clone().into(), - SCHEMA_ATTR_FERNET_PRIVATE_KEY_STR.clone().into(), - SCHEMA_ATTR_GIDNUMBER.clone().into(), - SCHEMA_ATTR_GRANT_UI_HINT.clone().into(), - SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY.clone().into(), - // SCHEMA_ATTR_LEGALNAME.clone().into(), - SCHEMA_ATTR_LOGINSHELL.clone().into(), - SCHEMA_ATTR_NAME_HISTORY.clone().into(), - SCHEMA_ATTR_NSUNIQUEID.clone().into(), - SCHEMA_ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE - .clone() - .into(), - SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP.clone().into(), - SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE.clone().into(), - SCHEMA_ATTR_OAUTH2_PREFER_SHORT_USERNAME.clone().into(), - SCHEMA_ATTR_OAUTH2_RS_BASIC_SECRET.clone().into(), - SCHEMA_ATTR_OAUTH2_RS_IMPLICIT_SCOPES.clone().into(), - SCHEMA_ATTR_OAUTH2_RS_NAME.clone().into(), - SCHEMA_ATTR_OAUTH2_RS_ORIGIN_LANDING.clone().into(), - // SCHEMA_ATTR_OAUTH2_RS_ORIGIN.clone().into(), - SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP.clone().into(), - SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP.clone().into(), - SCHEMA_ATTR_OAUTH2_RS_TOKEN_KEY.clone().into(), - SCHEMA_ATTR_OAUTH2_SESSION.clone().into(), - SCHEMA_ATTR_PASSKEYS.clone().into(), - SCHEMA_ATTR_PRIMARY_CREDENTIAL.clone().into(), - SCHEMA_ATTR_PRIVATE_COOKIE_KEY.clone().into(), - SCHEMA_ATTR_RADIUS_SECRET.clone().into(), - SCHEMA_ATTR_RS256_PRIVATE_KEY_DER.clone().into(), - SCHEMA_ATTR_SSH_PUBLICKEY.clone().into(), - SCHEMA_ATTR_SYNC_COOKIE.clone().into(), - SCHEMA_ATTR_SYNC_TOKEN_SESSION.clone().into(), - SCHEMA_ATTR_UNIX_PASSWORD.clone().into(), - SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION.clone().into(), - SCHEMA_ATTR_DENIED_NAME.clone().into(), - SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM.clone().into(), - SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST.clone().into(), - // DL4 - SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP_DL4.clone().into(), - SCHEMA_ATTR_OAUTH2_ALLOW_LOCALHOST_REDIRECT_DL4 - .clone() - .into(), - // DL5 - // DL6 - SCHEMA_ATTR_LIMIT_SEARCH_MAX_RESULTS_DL6.clone().into(), - SCHEMA_ATTR_LIMIT_SEARCH_MAX_FILTER_TEST_DL6.clone().into(), - SCHEMA_ATTR_KEY_INTERNAL_DATA_DL6.clone().into(), - SCHEMA_ATTR_KEY_PROVIDER_DL6.clone().into(), - SCHEMA_ATTR_KEY_ACTION_ROTATE_DL6.clone().into(), - SCHEMA_ATTR_KEY_ACTION_REVOKE_DL6.clone().into(), - SCHEMA_ATTR_KEY_ACTION_IMPORT_JWS_ES256_DL6.clone().into(), - // DL7 - SCHEMA_ATTR_PATCH_LEVEL_DL7.clone().into(), - SCHEMA_ATTR_DOMAIN_DEVELOPMENT_TAINT_DL7.clone().into(), - SCHEMA_ATTR_REFERS_DL7.clone().into(), - SCHEMA_ATTR_CERTIFICATE_DL7.clone().into(), - SCHEMA_ATTR_OAUTH2_RS_ORIGIN_DL7.clone().into(), - SCHEMA_ATTR_OAUTH2_STRICT_REDIRECT_URI_DL7.clone().into(), - SCHEMA_ATTR_MAIL_DL7.clone().into(), - SCHEMA_ATTR_LEGALNAME_DL7.clone().into(), - SCHEMA_ATTR_DISPLAYNAME_DL7.clone().into(), - // DL8 - SCHEMA_ATTR_LINKED_GROUP_DL8.clone().into(), - SCHEMA_ATTR_APPLICATION_PASSWORD_DL8.clone().into(), - SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK_DL8.clone().into(), - ]; - - let r = idm_schema - .into_iter() - // Each item individually logs it's result - .try_for_each(|entry| self.internal_migrate_or_create(entry)); - - if r.is_err() { - error!(res = ?r, "initialise_schema_idm -> Error"); - } - - debug_assert!(r.is_ok()); - - // ⚠️ 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 = vec![ - SCHEMA_CLASS_DYNGROUP.clone().into(), - SCHEMA_CLASS_ORGPERSON.clone().into(), - SCHEMA_CLASS_POSIXACCOUNT.clone().into(), - SCHEMA_CLASS_POSIXGROUP.clone().into(), - SCHEMA_CLASS_SYSTEM_CONFIG.clone().into(), - // DL4 - SCHEMA_CLASS_OAUTH2_RS_PUBLIC_DL4.clone().into(), - // DL5 - // SCHEMA_CLASS_PERSON_DL5.clone().into(), - SCHEMA_CLASS_ACCOUNT_DL5.clone().into(), - // SCHEMA_CLASS_OAUTH2_RS_DL5.clone().into(), - SCHEMA_CLASS_OAUTH2_RS_BASIC_DL5.clone().into(), - // DL6 - // SCHEMA_CLASS_ACCOUNT_POLICY_DL6.clone().into(), - // SCHEMA_CLASS_SERVICE_ACCOUNT_DL6.clone().into(), - // SCHEMA_CLASS_SYNC_ACCOUNT_DL6.clone().into(), - SCHEMA_CLASS_GROUP_DL6.clone().into(), - SCHEMA_CLASS_KEY_PROVIDER_DL6.clone().into(), - SCHEMA_CLASS_KEY_PROVIDER_INTERNAL_DL6.clone().into(), - SCHEMA_CLASS_KEY_OBJECT_DL6.clone().into(), - SCHEMA_CLASS_KEY_OBJECT_JWT_ES256_DL6.clone().into(), - SCHEMA_CLASS_KEY_OBJECT_JWE_A128GCM_DL6.clone().into(), - SCHEMA_CLASS_KEY_OBJECT_INTERNAL_DL6.clone().into(), - // SCHEMA_CLASS_DOMAIN_INFO_DL6.clone().into(), - // DL7 - // SCHEMA_CLASS_DOMAIN_INFO_DL7.clone().into(), - SCHEMA_CLASS_SERVICE_ACCOUNT_DL7.clone().into(), - SCHEMA_CLASS_SYNC_ACCOUNT_DL7.clone().into(), - SCHEMA_CLASS_CLIENT_CERTIFICATE_DL7.clone().into(), - SCHEMA_CLASS_OAUTH2_RS_DL7.clone().into(), - // DL8 - SCHEMA_CLASS_ACCOUNT_POLICY_DL8.clone().into(), - SCHEMA_CLASS_APPLICATION_DL8.clone().into(), - SCHEMA_CLASS_PERSON_DL8.clone().into(), - SCHEMA_CLASS_DOMAIN_INFO_DL8.clone().into(), - ]; - - let r: Result<(), _> = idm_schema_classes_dl1 - .into_iter() - .try_for_each(|entry| self.internal_migrate_or_create(entry)); - - if r.is_err() { - error!(res = ?r, "initialise_schema_idm -> Error"); - } - debug_assert!(r.is_ok()); - - debug!("initialise_schema_idm -> Ok!"); - - r - } - - #[instrument(level = "info", skip_all)] - /// This function is idempotent, runs all the startup functionality and checks - pub fn initialise_domain_info(&mut self) -> Result<(), OperationError> { - // Configure the default key provider. This needs to exist *before* the - // domain info! - self.internal_migrate_or_create(E_KEY_PROVIDER_INTERNAL_DL6.clone()) - .and_then(|_| self.reload()) - .map_err(|err| { - error!(?err, "initialise_domain_info::E_KEY_PROVIDER_INTERNAL_DL6"); - debug_assert!(false); - err - })?; - - self.internal_migrate_or_create(E_SYSTEM_INFO_V1.clone()) - .and_then(|_| self.internal_migrate_or_create(E_DOMAIN_INFO_DL6.clone())) - .and_then(|_| self.internal_migrate_or_create(E_SYSTEM_CONFIG_V1.clone())) - .map_err(|err| { - error!(?err, "initialise_domain_info"); - debug_assert!(false); - err - }) - } - - #[instrument(level = "info", skip_all)] - /// This function is idempotent, runs all the startup functionality and checks - pub fn initialise_idm(&mut self) -> Result<(), OperationError> { - // The domain info now exists, we should be able to do these migrations as they will - // cause SPN regenerations to occur - - // Delete entries that no longer need to exist. - // TODO: Shouldn't this be a migration? - // Check the admin object exists (migrations). - // Create the default idm_admin group. - let admin_entries: Vec = idm_builtin_admin_entries()?; - let res: Result<(), _> = admin_entries - .into_iter() - // Each item individually logs it's result - .try_for_each(|ent| self.internal_migrate_or_create(ent)); - if res.is_ok() { - debug!("initialise_idm p1 -> result Ok!"); - } else { - error!(?res, "initialise_idm p1 -> result"); - } - debug_assert!(res.is_ok()); - res?; - - let res: Result<(), _> = idm_builtin_non_admin_groups() - .into_iter() - .try_for_each(|e| self.internal_migrate_or_create(e.clone().try_into()?)); - if res.is_ok() { - debug!("initialise_idm p2 -> result Ok!"); - } else { - error!(?res, "initialise_idm p2 -> result"); - } - debug_assert!(res.is_ok()); - res?; - - // ⚠️ DOMAIN LEVEL 1 ENTRIES ⚠️ - // Future entries need to be added via migrations. - // - // DO NOT MODIFY THIS DEFINITION - let idm_entries: Vec = vec![ - // Built in access controls. - IDM_ACP_RECYCLE_BIN_SEARCH_V1.clone(), - IDM_ACP_RECYCLE_BIN_REVIVE_V1.clone(), - IDM_ACP_SCHEMA_WRITE_ATTRS_V1.clone(), - IDM_ACP_SCHEMA_WRITE_CLASSES_V1.clone(), - IDM_ACP_ACP_MANAGE_V1.clone(), - IDM_ACP_GROUP_ENTRY_MANAGED_BY_MODIFY_V1.clone(), - IDM_ACP_GROUP_ENTRY_MANAGER_V1.clone(), - IDM_ACP_SYNC_ACCOUNT_MANAGE_V1.clone(), - IDM_ACP_RADIUS_SERVERS_V1.clone(), - IDM_ACP_RADIUS_SECRET_MANAGE_V1.clone(), - IDM_ACP_PEOPLE_SELF_WRITE_MAIL_V1.clone(), - // IDM_ACP_SELF_READ_V1.clone(), - // IDM_ACP_SELF_WRITE_V1.clone(), - IDM_ACP_ACCOUNT_SELF_WRITE_V1.clone(), - // IDM_ACP_SELF_NAME_WRITE_V1.clone(), - IDM_ACP_ALL_ACCOUNTS_POSIX_READ_V1.clone(), - IDM_ACP_SYSTEM_CONFIG_ACCOUNT_POLICY_MANAGE_V1.clone(), - IDM_ACP_GROUP_UNIX_MANAGE_V1.clone(), - IDM_ACP_HP_GROUP_UNIX_MANAGE_V1.clone(), - IDM_ACP_GROUP_READ_V1.clone(), - IDM_ACP_ACCOUNT_UNIX_EXTEND_V1.clone(), - IDM_ACP_PEOPLE_PII_READ_V1.clone(), - IDM_ACP_PEOPLE_PII_MANAGE_V1.clone(), - IDM_ACP_PEOPLE_READ_V1.clone(), - IDM_ACP_PEOPLE_MANAGE_V1.clone(), - IDM_ACP_PEOPLE_DELETE_V1.clone(), - IDM_ACP_PEOPLE_CREDENTIAL_RESET_V1.clone(), - IDM_ACP_HP_PEOPLE_CREDENTIAL_RESET_V1.clone(), - IDM_ACP_SERVICE_ACCOUNT_CREATE_V1.clone(), - IDM_ACP_SERVICE_ACCOUNT_DELETE_V1.clone(), - IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGER_V1.clone(), - IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1.clone(), - IDM_ACP_HP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1.clone(), - IDM_ACP_SERVICE_ACCOUNT_MANAGE_V1.clone(), - // DL4 - // DL5 - // IDM_ACP_OAUTH2_MANAGE_DL5.clone(), - // DL6 - // IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE_DL6.clone(), - IDM_ACP_PEOPLE_CREATE_DL6.clone(), - IDM_ACP_GROUP_MANAGE_DL6.clone(), - IDM_ACP_ACCOUNT_MAIL_READ_DL6.clone(), - // IDM_ACP_DOMAIN_ADMIN_DL6.clone(), - // DL7 - // IDM_ACP_SELF_WRITE_DL7.clone(), - IDM_ACP_SELF_NAME_WRITE_DL7.clone(), - IDM_ACP_HP_CLIENT_CERTIFICATE_MANAGER_DL7.clone(), - IDM_ACP_OAUTH2_MANAGE_DL7.clone(), - // DL8 - IDM_ACP_SELF_READ_DL8.clone(), - IDM_ACP_SELF_WRITE_DL8.clone(), - IDM_ACP_APPLICATION_MANAGE_DL8.clone(), - IDM_ACP_APPLICATION_ENTRY_MANAGER_DL8.clone(), - IDM_ACP_MAIL_SERVERS_DL8.clone(), - IDM_ACP_DOMAIN_ADMIN_DL8.clone(), - IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE_DL8.clone(), - ]; - - let res: Result<(), _> = idm_entries - .into_iter() - .try_for_each(|entry| self.internal_migrate_or_create(entry.into())); - if res.is_ok() { - admin_debug!("initialise_idm p3 -> result Ok!"); - } else { - admin_error!(?res, "initialise_idm p3 -> result"); - } - debug_assert!(res.is_ok()); - res - } } impl QueryServerReadTransaction<'_> { diff --git a/server/lib/src/server/mod.rs b/server/lib/src/server/mod.rs index 11f914ca6..8c6f605be 100644 --- a/server/lib/src/server/mod.rs +++ b/server/lib/src/server/mod.rs @@ -2420,8 +2420,17 @@ impl<'a> QueryServerWriteTransaction<'a> { debug!(domain_previous_version = ?previous_version, domain_target_version = ?domain_info_version); debug!(domain_previous_patch_level = ?previous_patch_level, domain_target_patch_level = ?domain_info_patch_level); - // We have to check for DL0 since that's the initialisation level. - if previous_version < DOMAIN_MIN_REMIGRATION_LEVEL && previous_version != DOMAIN_LEVEL_0 { + // We have to check for DL0 since that's the initialisation level. If we are at DL0 then + // the server was just brought up and there are no other actions to take since we are + // now at TGT level. + if previous_version == DOMAIN_LEVEL_0 { + debug!( + "Server was just brought up, skipping migrations as we are already at target level" + ); + return Ok(()); + } + + if previous_version < DOMAIN_MIN_REMIGRATION_LEVEL { error!("UNABLE TO PROCEED. You are attempting a Skip update which is NOT SUPPORTED. You must upgrade one-version of Kanidm at a time."); error!("For more see: https://kanidm.github.io/kanidm/stable/support.html#upgrade-policy and https://kanidm.github.io/kanidm/stable/server_updates.html"); error!(domain_previous_version = ?previous_version, domain_target_version = ?domain_info_version); @@ -2434,7 +2443,10 @@ impl<'a> QueryServerWriteTransaction<'a> { self.migrate_domain_8_to_9()?; } - if previous_patch_level < PATCH_LEVEL_2 && domain_info_patch_level >= PATCH_LEVEL_2 { + if previous_patch_level < PATCH_LEVEL_2 + && domain_info_patch_level >= PATCH_LEVEL_2 + && domain_info_version == DOMAIN_LEVEL_9 + { self.migrate_domain_patch_level_2()?; } @@ -2573,7 +2585,10 @@ impl<'a> QueryServerWriteTransaction<'a> { } fn set_phase(&mut self, phase: ServerPhase) { - *self.phase = phase + // Phase changes are one way + if phase > *self.phase { + *self.phase = phase + } } pub(crate) fn get_phase(&mut self) -> ServerPhase { diff --git a/server/lib/src/server/modify.rs b/server/lib/src/server/modify.rs index 092884828..561fb951d 100644 --- a/server/lib/src/server/modify.rs +++ b/server/lib/src/server/modify.rs @@ -615,9 +615,11 @@ mod tests { Err(OperationError::EmptyRequest) ); + let idm_admin = server_txn.internal_search_uuid(UUID_IDM_ADMIN).unwrap(); + // Mod changes no objects - let me_nochg = ModifyEvent::new_impersonate_entry_ser( - BUILTIN_ACCOUNT_IDM_ADMIN.clone(), + let me_nochg = ModifyEvent::new_impersonate_entry( + idm_admin, filter!(f_eq( Attribute::Name, PartialValue::new_iname("flarbalgarble") diff --git a/server/testkit/examples/enumerating_access.rs b/server/testkit/defunct_examples/enumerating_access.rs similarity index 94% rename from server/testkit/examples/enumerating_access.rs rename to server/testkit/defunct_examples/enumerating_access.rs index 56c4dce68..5a3bf6691 100644 --- a/server/testkit/examples/enumerating_access.rs +++ b/server/testkit/defunct_examples/enumerating_access.rs @@ -4,7 +4,9 @@ //! use kanidmd_lib::constants::entries::Attribute; -use kanidmd_lib::constants::groups::{idm_builtin_admin_groups, idm_builtin_non_admin_groups}; +use kanidmd_lib::migration_data::current::{ + phase_5_builtin_admin_entries, phase_6_builtin_non_admin_entries +}; use kanidmd_lib::prelude::{builtin_accounts, EntryInitNew}; use petgraph::graphmap::{AllEdges, GraphMap, NodeTrait}; use petgraph::Directed; @@ -106,8 +108,8 @@ async fn enumerate_default_groups(/*_client: KanidmClient*/) { graph.add_node(account.uuid); }); - let mut groups = idm_builtin_admin_groups(); - groups.extend(idm_builtin_non_admin_groups()); + let mut groups = phase_5_builtin_admin_entries(); + groups.extend(phase_6_builtin_non_admin_entries()); groups.into_iter().for_each(|group| { uuidmap.insert(group.uuid, group.clone().try_into().unwrap()); diff --git a/server/testkit/src/lib.rs b/server/testkit/src/lib.rs index 56bca39b4..c9bf0453c 100644 --- a/server/testkit/src/lib.rs +++ b/server/testkit/src/lib.rs @@ -18,7 +18,7 @@ use kanidm_client::{KanidmClient, KanidmClientBuilder}; use kanidm_proto::internal::{Filter, Modify, ModifyList}; use kanidmd_core::config::{Configuration, IntegrationTestConfig}; use kanidmd_core::{create_server_core, CoreHandle}; -use kanidmd_lib::prelude::{Attribute, BUILTIN_GROUP_IDM_ADMINS_V1}; +use kanidmd_lib::prelude::Attribute; use tokio::task; pub const ADMIN_TEST_USER: &str = "admin"; @@ -385,7 +385,7 @@ pub async fn login_put_admin_idm_admins(rsclient: &KanidmClient) { #[allow(clippy::expect_used)] rsclient - .idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &[ADMIN_TEST_USER]) + .idm_group_add_members("system_admins", &[ADMIN_TEST_USER]) .await .expect("Failed to add admin user to idm_admins") } diff --git a/server/testkit/tests/oauth2_device_flow.rs b/server/testkit/tests/oauth2_device_flow.rs index d9e035d52..22feee9cd 100644 --- a/server/testkit/tests/oauth2_device_flow.rs +++ b/server/testkit/tests/oauth2_device_flow.rs @@ -12,10 +12,9 @@ use kanidm_proto::oauth2::{ AccessTokenRequest, AccessTokenResponse, AuthorisationResponse, GrantTypeReq, }; +use kanidmd_lib::constants::NAME_IDM_ALL_ACCOUNTS; use kanidmd_lib::prelude::uri::{OAUTH2_AUTHORISE_DEVICE, OAUTH2_TOKEN_ENDPOINT}; -use kanidmd_lib::prelude::{ - Attribute, IDM_ALL_ACCOUNTS, OAUTH2_SCOPE_EMAIL, OAUTH2_SCOPE_OPENID, OAUTH2_SCOPE_READ, -}; +use kanidmd_lib::prelude::{Attribute, OAUTH2_SCOPE_EMAIL, OAUTH2_SCOPE_OPENID, OAUTH2_SCOPE_READ}; use kanidmd_testkit::{ assert_no_cache, ADMIN_TEST_PASSWORD, ADMIN_TEST_USER, IDM_ADMIN_TEST_PASSWORD, IDM_ADMIN_TEST_USER, NOT_ADMIN_TEST_EMAIL, NOT_ADMIN_TEST_PASSWORD, NOT_ADMIN_TEST_USERNAME, @@ -159,7 +158,7 @@ async fn oauth2_device_flow(rsclient: KanidmClient) { rsclient .idm_oauth2_rs_update_scope_map( TEST_INTEGRATION_RS_ID, - IDM_ALL_ACCOUNTS.name, + NAME_IDM_ALL_ACCOUNTS, vec![OAUTH2_SCOPE_READ, OAUTH2_SCOPE_EMAIL, OAUTH2_SCOPE_OPENID], ) .await @@ -168,7 +167,7 @@ async fn oauth2_device_flow(rsclient: KanidmClient) { rsclient .idm_oauth2_rs_update_sup_scope_map( TEST_INTEGRATION_RS_ID, - IDM_ALL_ACCOUNTS.name, + NAME_IDM_ALL_ACCOUNTS, vec![ADMIN_TEST_USER], ) .await @@ -179,7 +178,7 @@ async fn oauth2_device_flow(rsclient: KanidmClient) { .idm_oauth2_rs_update_claim_map( TEST_INTEGRATION_RS_ID, "test_claim", - IDM_ALL_ACCOUNTS.name, + NAME_IDM_ALL_ACCOUNTS, &["claim_a".to_string(), "claim_b".to_string()], ) .await diff --git a/server/testkit/tests/oauth2_test.rs b/server/testkit/tests/oauth2_test.rs index faab08575..500745567 100644 --- a/server/testkit/tests/oauth2_test.rs +++ b/server/testkit/tests/oauth2_test.rs @@ -12,7 +12,8 @@ use kanidm_proto::oauth2::{ AccessTokenResponse, AccessTokenType, AuthorisationResponse, GrantTypeReq, OidcDiscoveryResponse, }; -use kanidmd_lib::prelude::{Attribute, IDM_ALL_ACCOUNTS}; +use kanidmd_lib::constants::NAME_IDM_ALL_ACCOUNTS; +use kanidmd_lib::prelude::Attribute; use oauth2_ext::PkceCodeChallenge; use reqwest::header::{HeaderValue, CONTENT_TYPE}; use reqwest::StatusCode; @@ -98,7 +99,7 @@ async fn test_oauth2_openid_basic_flow_impl( rsclient .idm_oauth2_rs_update_scope_map( TEST_INTEGRATION_RS_ID, - IDM_ALL_ACCOUNTS.name, + NAME_IDM_ALL_ACCOUNTS, vec![OAUTH2_SCOPE_READ, OAUTH2_SCOPE_EMAIL, OAUTH2_SCOPE_OPENID], ) .await @@ -107,7 +108,7 @@ async fn test_oauth2_openid_basic_flow_impl( rsclient .idm_oauth2_rs_update_sup_scope_map( TEST_INTEGRATION_RS_ID, - IDM_ALL_ACCOUNTS.name, + NAME_IDM_ALL_ACCOUNTS, vec![ADMIN_TEST_USER], ) .await @@ -627,7 +628,7 @@ async fn test_oauth2_openid_public_flow_impl( rsclient .idm_oauth2_rs_update_scope_map( TEST_INTEGRATION_RS_ID, - IDM_ALL_ACCOUNTS.name, + NAME_IDM_ALL_ACCOUNTS, vec![OAUTH2_SCOPE_READ, OAUTH2_SCOPE_EMAIL, OAUTH2_SCOPE_OPENID], ) .await @@ -636,7 +637,7 @@ async fn test_oauth2_openid_public_flow_impl( rsclient .idm_oauth2_rs_update_sup_scope_map( TEST_INTEGRATION_RS_ID, - IDM_ALL_ACCOUNTS.name, + NAME_IDM_ALL_ACCOUNTS, vec![ADMIN_TEST_USER], ) .await @@ -647,7 +648,7 @@ async fn test_oauth2_openid_public_flow_impl( .idm_oauth2_rs_update_claim_map( TEST_INTEGRATION_RS_ID, "test_claim", - IDM_ALL_ACCOUNTS.name, + NAME_IDM_ALL_ACCOUNTS, &["claim_a".to_string(), "claim_b".to_string()], ) .await diff --git a/server/testkit/tests/proto_v1_test.rs b/server/testkit/tests/proto_v1_test.rs index a07061bcb..577d14d30 100644 --- a/server/testkit/tests/proto_v1_test.rs +++ b/server/testkit/tests/proto_v1_test.rs @@ -3,6 +3,7 @@ use std::path::Path; use std::time::SystemTime; use kanidm_proto::constants::{ATTR_GIDNUMBER, KSESSIONID}; + use kanidm_proto::internal::{ ApiToken, CURegState, Filter, ImageValue, Modify, ModifyList, UatPurpose, UserAuthToken, }; @@ -10,10 +11,10 @@ use kanidm_proto::v1::{ AuthCredential, AuthIssueSession, AuthMech, AuthRequest, AuthResponse, AuthState, AuthStep, Entry, }; +use kanidmd_lib::constants::{NAME_IDM_ADMINS, NAME_SYSTEM_ADMINS}; use kanidmd_lib::credential::totp::Totp; -use kanidmd_lib::prelude::{ - Attribute, BUILTIN_GROUP_IDM_ADMINS_V1, BUILTIN_GROUP_SYSTEM_ADMINS_V1, -}; + +use kanidmd_lib::prelude::Attribute; use tracing::{debug, trace}; use std::str::FromStr; @@ -144,10 +145,7 @@ async fn test_server_rest_group_read(rsclient: KanidmClient) { let g_list = rsclient.idm_group_list().await.unwrap(); assert!(!g_list.is_empty()); - let g = rsclient - .idm_group_get(BUILTIN_GROUP_IDM_ADMINS_V1.name) - .await - .unwrap(); + let g = rsclient.idm_group_get(NAME_IDM_ADMINS).await.unwrap(); assert!(g.is_some()); println!("{:?}", g); } @@ -165,7 +163,7 @@ async fn test_server_rest_group_lifecycle(rsclient: KanidmClient) { // Create a new group rsclient - .idm_group_create("demo_group", Some(BUILTIN_GROUP_IDM_ADMINS_V1.name)) + .idm_group_create("demo_group", Some(NAME_IDM_ADMINS)) .await .unwrap(); @@ -245,16 +243,13 @@ async fn test_server_rest_group_lifecycle(rsclient: KanidmClient) { assert_eq!(g_list_3.len(), g_list.len()); // Check we can get an exact group - let g = rsclient - .idm_group_get(BUILTIN_GROUP_IDM_ADMINS_V1.name) - .await - .unwrap(); + let g = rsclient.idm_group_get(NAME_IDM_ADMINS).await.unwrap(); assert!(g.is_some()); println!("{:?}", g); // They should have members let members = rsclient - .idm_group_get_members(BUILTIN_GROUP_IDM_ADMINS_V1.name) + .idm_group_get_members(NAME_IDM_ADMINS) .await .unwrap(); println!("{:?}", members); @@ -326,7 +321,7 @@ async fn test_server_radius_credential_lifecycle(rsclient: KanidmClient) { // All admin to create persons. rsclient - .idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"]) + .idm_group_add_members(NAME_IDM_ADMINS, &["admin"]) .await .unwrap(); @@ -397,7 +392,7 @@ async fn test_server_rest_person_account_lifecycle(rsclient: KanidmClient) { // To enable the admin to actually make some of these changes, we have // to make them a people admin. NOT recommended in production! rsclient - .idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"]) + .idm_group_add_members(NAME_IDM_ADMINS, &["admin"]) .await .unwrap(); @@ -551,7 +546,7 @@ async fn test_server_rest_posix_lifecycle(rsclient: KanidmClient) { assert!(res.is_ok()); // Not recommended in production! rsclient - .idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"]) + .idm_group_add_members(NAME_IDM_ADMINS, &["admin"]) .await .unwrap(); @@ -571,7 +566,7 @@ async fn test_server_rest_posix_lifecycle(rsclient: KanidmClient) { // Extend the group with posix attrs rsclient - .idm_group_create("posix_group", Some(BUILTIN_GROUP_IDM_ADMINS_V1.name)) + .idm_group_create("posix_group", Some(NAME_IDM_ADMINS)) .await .unwrap(); rsclient @@ -676,7 +671,7 @@ async fn test_server_rest_posix_auth_lifecycle(rsclient: KanidmClient) { // Not recommended in production! rsclient - .idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"]) + .idm_group_add_members(NAME_IDM_ADMINS, &["admin"]) .await .unwrap(); @@ -773,7 +768,7 @@ async fn test_server_rest_recycle_lifecycle(rsclient: KanidmClient) { // Not recommended in production! rsclient - .idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"]) + .idm_group_add_members(NAME_IDM_ADMINS, &["admin"]) .await .unwrap(); @@ -826,7 +821,7 @@ async fn test_server_rest_oauth2_basic_lifecycle(rsclient: KanidmClient) { assert!(res.is_ok()); rsclient - .idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"]) + .idm_group_add_members(NAME_IDM_ADMINS, &["admin"]) .await .unwrap(); @@ -902,11 +897,7 @@ async fn test_server_rest_oauth2_basic_lifecycle(rsclient: KanidmClient) { // Check that we can add scope maps and delete them. rsclient - .idm_oauth2_rs_update_scope_map( - "test_integration", - BUILTIN_GROUP_SYSTEM_ADMINS_V1.name, - vec!["a", "b"], - ) + .idm_oauth2_rs_update_scope_map("test_integration", NAME_SYSTEM_ADMINS, vec!["a", "b"]) .await .expect("Failed to create scope map"); @@ -921,11 +912,7 @@ async fn test_server_rest_oauth2_basic_lifecycle(rsclient: KanidmClient) { // Check we can update a scope map rsclient - .idm_oauth2_rs_update_scope_map( - "test_integration", - BUILTIN_GROUP_SYSTEM_ADMINS_V1.name, - vec!["a", "b", "c"], - ) + .idm_oauth2_rs_update_scope_map("test_integration", NAME_SYSTEM_ADMINS, vec!["a", "b", "c"]) .await .expect("Failed to create scope map"); @@ -1009,7 +996,7 @@ async fn test_server_rest_oauth2_basic_lifecycle(rsclient: KanidmClient) { // Check we can delete a scope map. rsclient - .idm_oauth2_rs_delete_scope_map("test_integration", BUILTIN_GROUP_SYSTEM_ADMINS_V1.name) + .idm_oauth2_rs_delete_scope_map("test_integration", NAME_SYSTEM_ADMINS) .await .expect("Failed to delete scope map"); @@ -1049,7 +1036,7 @@ async fn test_server_credential_update_session_pw(rsclient: KanidmClient) { // Not recommended in production! rsclient - .idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"]) + .idm_group_add_members(NAME_IDM_ADMINS, &["admin"]) .await .unwrap(); @@ -1124,7 +1111,7 @@ async fn test_server_credential_update_session_totp_pw(rsclient: KanidmClient) { // Not recommended in production! rsclient - .idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"]) + .idm_group_add_members(NAME_IDM_ADMINS, &["admin"]) .await .unwrap(); @@ -1253,7 +1240,7 @@ async fn setup_demo_account_passkey(rsclient: &KanidmClient) -> WebauthnAuthenti // Not recommended in production! rsclient - .idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"]) + .idm_group_add_members(NAME_IDM_ADMINS, &["admin"]) .await .unwrap(); @@ -1409,7 +1396,7 @@ async fn test_server_api_token_lifecycle(rsclient: KanidmClient) { .idm_service_account_create( test_service_account_username, "Test Service", - BUILTIN_GROUP_IDM_ADMINS_V1.name, + NAME_IDM_ADMINS, ) .await .expect("Failed to create service account"); diff --git a/server/testkit/tests/scim_test.rs b/server/testkit/tests/scim_test.rs index b760406eb..674e546b5 100644 --- a/server/testkit/tests/scim_test.rs +++ b/server/testkit/tests/scim_test.rs @@ -2,7 +2,8 @@ use compact_jwt::{traits::JwsVerifiable, JwsCompact, JwsEs256Verifier, JwsVerifi use kanidm_client::KanidmClient; use kanidm_proto::internal::ScimSyncToken; use kanidm_proto::scim_v1::ScimEntryGetQuery; -use kanidmd_lib::prelude::{Attribute, BUILTIN_GROUP_IDM_ADMINS_V1}; +use kanidmd_lib::constants::NAME_IDM_ADMINS; +use kanidmd_lib::prelude::Attribute; use kanidmd_testkit::{ADMIN_TEST_PASSWORD, ADMIN_TEST_USER}; use reqwest::header::HeaderValue; use std::str::FromStr; @@ -170,7 +171,7 @@ async fn test_scim_sync_entry_get(rsclient: KanidmClient) { // All admin to create persons. rsclient - .idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"]) + .idm_group_add_members(NAME_IDM_ADMINS, &["admin"]) .await .unwrap(); diff --git a/server/testkit/tests/unix.rs b/server/testkit/tests/unix.rs index 8381b4e69..f3ea98c6d 100644 --- a/server/testkit/tests/unix.rs +++ b/server/testkit/tests/unix.rs @@ -1,5 +1,5 @@ use kanidm_client::KanidmClient; -use kanidmd_lib::prelude::BUILTIN_GROUP_IDM_ADMINS_V1; +use kanidmd_lib::constants::NAME_IDM_ADMINS; use kanidmd_testkit::*; #[kanidmd_testkit::test] @@ -8,12 +8,7 @@ async fn account_id_unix_token(rsclient: KanidmClient) { create_user(&rsclient, "group_manager", "idm_group_manage_priv").await; // create test user without creating new groups - create_user( - &rsclient, - NOT_ADMIN_TEST_USERNAME, - BUILTIN_GROUP_IDM_ADMINS_V1.name, - ) - .await; + create_user(&rsclient, NOT_ADMIN_TEST_USERNAME, NAME_IDM_ADMINS).await; login_account(&rsclient, "group_manager").await; let response = rsclient