mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 12:37:00 +01:00
Major refactor of migrations to improve durability.
Migrations and server bootstrap are very interconnected processes and in this we'll be addressing and improving both. Server bootstrap was performed by creating base entries in phases, eventually bringing up enough of the *oldest* supported server minimum remigration level, to then allow triggering of migrations. Migrations then applied "patches" effectively ontop of this minimum level to update entries to what they should be in newer versions of the server. This scheme has it's pros and cons, but the major con was that to remove a migration meant squashing it's content back into the minimum remigration level, and this was a human process that was quite error prone and difficult to automate. As well, this scheme also led to cases where the patch migrations would sometimes *not* reflect all the needed changes or content, or in one case was actually undone by a patchlevel fix up that was required to address a bug. Invariably this led to issues, and cases where a new server may have different content to a migrated one - not exactly what we want! This is a new migration scheme that addresses this fragility. However what it trades is verbosity of the content. Rather than having a base set of entries and patching/updating small sections ontop, we have migration data folders that contain the full set of entries as they should appear at that migration level. This makes the bootstrap process easier as we can just apply the migration level as a whole, and targetted to what precise version we want. This also makes migrations more durable as the content is explicitly copied and all entries fully applied, so there is no risk that a migration or data change can be forgotten or applied incorrectly. We are expressing the full state of what our builtin and provided entries should be. Finally this rips out a number of places where migration data was being used as test case data. Not all of these have been replaced (notably in authsession with Account), but the majority have and have been replaced with clearer use of constants rather than building whole entries just to access the name and throw them away for example.
This commit is contained in:
parent
857dcf5087
commit
cb287eeb61
|
@ -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()),
|
||||
|
|
|
@ -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<uuid::Uuid>,
|
||||
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: "<set description>",
|
||||
displayname: "<set displayname>",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BuiltinAccount> 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<BuiltinAccount> 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<Vec<EntryInitNew>, OperationError> {
|
||||
let mut res: Vec<EntryInitNew> = 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)
|
||||
}
|
||||
|
|
|
@ -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::*;
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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<FilterInvalid>,
|
||||
modlist: ModifyList<ModifyInvalid>,
|
||||
) -> 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)]
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
35
server/lib/src/migration_data/dl10/accounts.rs
Normal file
35
server/lib/src/migration_data/dl10/accounts.rs
Normal file
|
@ -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",
|
||||
};
|
||||
}
|
408
server/lib/src/migration_data/dl10/groups.rs
Normal file
408
server/lib/src/migration_data/dl10/groups.rs
Normal file
|
@ -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<uuid::Uuid>,
|
||||
pub entry_managed_by: Option<uuid::Uuid>,
|
||||
pub dyngroup: bool,
|
||||
pub dyngroup_filter: Option<Filter>,
|
||||
pub extra_attributes: Vec<(Attribute, Value)>,
|
||||
}
|
||||
|
||||
impl TryFrom<BuiltinGroup> for EntryInitNew {
|
||||
type Error = OperationError;
|
||||
|
||||
fn try_from(val: BuiltinGroup) -> Result<Self, OperationError> {
|
||||
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::<Vec<Value>>(),
|
||||
);
|
||||
// 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()
|
||||
};
|
||||
}
|
268
server/lib/src/migration_data/dl10/mod.rs
Normal file
268
server/lib/src/migration_data/dl10/mod.rs
Normal file
|
@ -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<EntryInitNew> {
|
||||
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<EntryInitNew> {
|
||||
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<EntryInitNew> {
|
||||
vec![E_KEY_PROVIDER_INTERNAL_DL6.clone()]
|
||||
}
|
||||
|
||||
pub fn phase_4_system_entries() -> Vec<EntryInitNew> {
|
||||
vec![
|
||||
E_SYSTEM_INFO_V1.clone(),
|
||||
E_DOMAIN_INFO_DL6.clone(),
|
||||
E_SYSTEM_CONFIG_V1.clone(),
|
||||
]
|
||||
}
|
||||
|
||||
pub fn phase_5_builtin_admin_entries() -> Result<Vec<EntryInitNew>, 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<Vec<EntryInitNew>, 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<EntryInitNew> {
|
||||
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(),
|
||||
]
|
||||
}
|
|
@ -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};
|
|
@ -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()),
|
2637
server/lib/src/migration_data/dl8/access.rs
Normal file
2637
server/lib/src/migration_data/dl8/access.rs
Normal file
File diff suppressed because it is too large
Load diff
35
server/lib/src/migration_data/dl8/accounts.rs
Normal file
35
server/lib/src/migration_data/dl8/accounts.rs
Normal file
|
@ -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",
|
||||
};
|
||||
}
|
|
@ -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,
|
||||
]
|
||||
}
|
18
server/lib/src/migration_data/dl8/key_providers.rs
Normal file
18
server/lib/src/migration_data/dl8/key_providers.rs
Normal file
|
@ -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.")
|
||||
)
|
||||
);
|
||||
}
|
273
server/lib/src/migration_data/dl8/mod.rs
Normal file
273
server/lib/src/migration_data/dl8/mod.rs
Normal file
|
@ -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<EntryInitNew> {
|
||||
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<EntryInitNew> {
|
||||
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<EntryInitNew> {
|
||||
vec![E_KEY_PROVIDER_INTERNAL_DL6.clone()]
|
||||
}
|
||||
|
||||
pub fn phase_4_system_entries() -> Vec<EntryInitNew> {
|
||||
vec![
|
||||
E_SYSTEM_INFO_V1.clone(),
|
||||
E_DOMAIN_INFO_DL6.clone(),
|
||||
E_SYSTEM_CONFIG_V1.clone(),
|
||||
]
|
||||
}
|
||||
|
||||
pub fn phase_5_builtin_admin_entries() -> Result<Vec<EntryInitNew>, 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<Vec<EntryInitNew>, 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<EntryInitNew> {
|
||||
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(),
|
||||
]
|
||||
}
|
1506
server/lib/src/migration_data/dl8/schema.rs
Normal file
1506
server/lib/src/migration_data/dl8/schema.rs
Normal file
File diff suppressed because it is too large
Load diff
1073
server/lib/src/migration_data/dl8/system_config.rs
Normal file
1073
server/lib/src/migration_data/dl8/system_config.rs
Normal file
File diff suppressed because it is too large
Load diff
2637
server/lib/src/migration_data/dl9/access.rs
Normal file
2637
server/lib/src/migration_data/dl9/access.rs
Normal file
File diff suppressed because it is too large
Load diff
35
server/lib/src/migration_data/dl9/accounts.rs
Normal file
35
server/lib/src/migration_data/dl9/accounts.rs
Normal file
|
@ -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",
|
||||
};
|
||||
}
|
408
server/lib/src/migration_data/dl9/groups.rs
Normal file
408
server/lib/src/migration_data/dl9/groups.rs
Normal file
|
@ -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<uuid::Uuid>,
|
||||
pub entry_managed_by: Option<uuid::Uuid>,
|
||||
pub dyngroup: bool,
|
||||
pub dyngroup_filter: Option<Filter>,
|
||||
pub extra_attributes: Vec<(Attribute, Value)>,
|
||||
}
|
||||
|
||||
impl TryFrom<BuiltinGroup> for EntryInitNew {
|
||||
type Error = OperationError;
|
||||
|
||||
fn try_from(val: BuiltinGroup) -> Result<Self, OperationError> {
|
||||
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::<Vec<Value>>(),
|
||||
);
|
||||
// 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()
|
||||
};
|
||||
}
|
18
server/lib/src/migration_data/dl9/key_providers.rs
Normal file
18
server/lib/src/migration_data/dl9/key_providers.rs
Normal file
|
@ -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.")
|
||||
)
|
||||
);
|
||||
}
|
264
server/lib/src/migration_data/dl9/mod.rs
Normal file
264
server/lib/src/migration_data/dl9/mod.rs
Normal file
|
@ -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<EntryInitNew> {
|
||||
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<EntryInitNew> {
|
||||
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<EntryInitNew> {
|
||||
vec![E_KEY_PROVIDER_INTERNAL_DL6.clone()]
|
||||
}
|
||||
|
||||
pub fn phase_4_system_entries() -> Vec<EntryInitNew> {
|
||||
vec![
|
||||
E_SYSTEM_INFO_V1.clone(),
|
||||
E_DOMAIN_INFO_DL6.clone(),
|
||||
E_SYSTEM_CONFIG_V1.clone(),
|
||||
]
|
||||
}
|
||||
|
||||
pub fn phase_5_builtin_admin_entries() -> Result<Vec<EntryInitNew>, 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<Vec<EntryInitNew>, 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<EntryInitNew> {
|
||||
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(),
|
||||
]
|
||||
}
|
1506
server/lib/src/migration_data/dl9/schema.rs
Normal file
1506
server/lib/src/migration_data/dl9/schema.rs
Normal file
File diff suppressed because it is too large
Load diff
1073
server/lib/src/migration_data/dl9/system_config.rs
Normal file
1073
server/lib/src/migration_data/dl9/system_config.rs
Normal file
File diff suppressed because it is too large
Load diff
24
server/lib/src/migration_data/mod.rs
Normal file
24
server/lib/src/migration_data/mod.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
pub(crate) mod dl10;
|
||||
pub(crate) mod dl8;
|
||||
pub(crate) mod dl9;
|
||||
|
||||
mod types;
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) use dl10::accounts::BUILTIN_ACCOUNT_ANONYMOUS_DL6 as BUILTIN_ACCOUNT_ANONYMOUS;
|
||||
|
||||
#[cfg(test)]
|
||||
use self::types::BuiltinAccount;
|
||||
|
||||
#[cfg(test)]
|
||||
lazy_static! {
|
||||
/// Builtin System Admin account.
|
||||
pub static ref BUILTIN_ACCOUNT_TEST_PERSON: BuiltinAccount = BuiltinAccount {
|
||||
account_type: kanidm_proto::v1::AccountType::Person,
|
||||
entry_managed_by: None,
|
||||
name: "test_person",
|
||||
uuid: crate::constants::uuids::UUID_TESTPERSON_1,
|
||||
description: "Test Person",
|
||||
displayname: "Test Person",
|
||||
};
|
||||
}
|
83
server/lib/src/migration_data/types.rs
Normal file
83
server/lib/src/migration_data/types.rs
Normal file
|
@ -0,0 +1,83 @@
|
|||
//! Constant Entries for the IDM
|
||||
use crate::constants::uuids::*;
|
||||
use crate::entry::EntryInitNew;
|
||||
use crate::prelude::EntryClass;
|
||||
use crate::value::Value;
|
||||
pub use kanidm_proto::attribute::Attribute;
|
||||
use kanidm_proto::v1::AccountType;
|
||||
|
||||
use uuid::Uuid;
|
||||
|
||||
#[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<uuid::Uuid>,
|
||||
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: "<set description>",
|
||||
displayname: "<set displayname>",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl From<BuiltinAccount> 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<BuiltinAccount> 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
|
||||
}
|
||||
}
|
|
@ -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)];
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
// 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()?;
|
||||
|
||||
// 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.
|
||||
// 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<EntryInitNew>,
|
||||
) -> 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<EntryInit, EntryNew>,
|
||||
) -> 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<EntryInit, EntryNew>,
|
||||
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<EntryInitNew> = 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<EntryInitNew> = 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<EntryInitNew> = 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<BuiltinAcp> = 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<'_> {
|
||||
|
|
|
@ -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,8 +2585,11 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
}
|
||||
|
||||
fn set_phase(&mut self, phase: ServerPhase) {
|
||||
// Phase changes are one way
|
||||
if phase > *self.phase {
|
||||
*self.phase = phase
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_phase(&mut self) -> ServerPhase {
|
||||
*self.phase
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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());
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue