mirror of
https://github.com/kanidm/kanidm.git
synced 2025-05-19 23:43:56 +02:00
Merge 7065a9423b
into 266dc77536
This commit is contained in:
commit
d30ccdfb0a
|
@ -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);
|
||||
// Indicate the schema is now ready, which allows dyngroups to work when they
|
||||
// are created in the next phase of migrations.
|
||||
write_txn.set_phase(ServerPhase::SchemaReady);
|
||||
|
||||
// No domain info was present, so neither was the rest of the IDM. We need to bootstrap
|
||||
// the base entries here.
|
||||
if db_domain_version == 0 {
|
||||
// Init idm will now set the system config version and minimum domain
|
||||
// level if none was present
|
||||
write_txn.initialise_domain_info()?;
|
||||
|
||||
// In this path because we create the dyn groups they are immediately added to the
|
||||
// dyngroup cache and begin to operate.
|
||||
write_txn.initialise_idm()?;
|
||||
} else {
|
||||
// #2756 - if we *aren't* creating the base IDM entries, then we
|
||||
// need to force dyn groups to reload since we're now at schema
|
||||
// ready. This is done indirectly by ... reloading the schema again.
|
||||
|
@ -97,13 +93,13 @@ impl QueryServer {
|
|||
// itself or a change to schema reloading. Since we aren't changing the
|
||||
// dyngroup here, we have to go via the schema reload path.
|
||||
write_txn.force_schema_reload();
|
||||
};
|
||||
|
||||
// Reload as init idm affects access controls.
|
||||
write_txn.reload()?;
|
||||
// Reload as init idm affects access controls.
|
||||
write_txn.reload()?;
|
||||
|
||||
// Domain info is now ready and reloaded, we can proceed.
|
||||
write_txn.set_phase(ServerPhase::DomainInfoReady);
|
||||
// Domain info is now ready and reloaded, we can proceed.
|
||||
write_txn.set_phase(ServerPhase::DomainInfoReady);
|
||||
}
|
||||
|
||||
// This is the start of domain info related migrations which we will need in future
|
||||
// to handle replication. Due to the access control rework, and the addition of "managed by"
|
||||
|
@ -126,20 +122,18 @@ impl QueryServer {
|
|||
// If the database domain info is a lower version than our target level, we reload.
|
||||
if domain_info_version < domain_target_level {
|
||||
write_txn
|
||||
.internal_modify_uuid(
|
||||
UUID_DOMAIN_INFO,
|
||||
&ModifyList::new_purge_and_set(
|
||||
Attribute::Version,
|
||||
Value::new_uint32(domain_target_level),
|
||||
),
|
||||
)
|
||||
.internal_apply_domain_migration(domain_target_level)
|
||||
.map(|()| {
|
||||
warn!("Domain level has been raised to {}", domain_target_level);
|
||||
})?;
|
||||
|
||||
// Reload if anything in migrations requires it - this triggers the domain migrations
|
||||
// which in turn can trigger schema reloads etc.
|
||||
reload_required = true;
|
||||
// which in turn can trigger schema reloads etc. If the server was just brought up
|
||||
// then we don't need the extra reload since we are already at the correct
|
||||
// version of the server, and this call to set the target level is just for persistance
|
||||
// of the value.
|
||||
if domain_info_version != 0 {
|
||||
reload_required = true;
|
||||
}
|
||||
} else if domain_development_taint {
|
||||
// This forces pre-release versions to re-migrate each start up. This solves
|
||||
// the domain-version-sprawl issue so that during a development cycle we can
|
||||
|
@ -182,9 +176,6 @@ impl QueryServer {
|
|||
// we would have skipped the patch level fix which needs to have occurred *first*.
|
||||
if reload_required {
|
||||
write_txn.reload()?;
|
||||
// We are not yet at the schema phase where reindexes will auto-trigger
|
||||
// so if one was required, do it now.
|
||||
write_txn.reindex(false)?;
|
||||
}
|
||||
|
||||
// Now set the db/domain devel taint flag to match our current release status
|
||||
|
@ -206,7 +197,8 @@ impl QueryServer {
|
|||
// We are ready to run
|
||||
write_txn.set_phase(ServerPhase::Running);
|
||||
|
||||
// Commit all changes, this also triggers the reload.
|
||||
// Commit all changes, this also triggers the final reload, this should be a no-op
|
||||
// since we already did all the needed loads above.
|
||||
write_txn.commit()?;
|
||||
|
||||
debug!("Database version check and migrations success! ☀️ ");
|
||||
|
@ -217,7 +209,6 @@ impl QueryServer {
|
|||
impl QueryServerWriteTransaction<'_> {
|
||||
/// Apply a domain migration `to_level`. Panics if `to_level` is not greater than the active
|
||||
/// level.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn internal_apply_domain_migration(
|
||||
&mut self,
|
||||
to_level: u32,
|
||||
|
@ -230,6 +221,23 @@ impl QueryServerWriteTransaction<'_> {
|
|||
.and_then(|()| self.reload())
|
||||
}
|
||||
|
||||
fn internal_migrate_or_create_batch(
|
||||
&mut self,
|
||||
msg: &str,
|
||||
entries: Vec<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,7 +2585,10 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
}
|
||||
|
||||
fn set_phase(&mut self, phase: ServerPhase) {
|
||||
*self.phase = phase
|
||||
// Phase changes are one way
|
||||
if phase > *self.phase {
|
||||
*self.phase = phase
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_phase(&mut self) -> ServerPhase {
|
||||
|
|
|
@ -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