mirror of
https://github.com/kanidm/kanidm.git
synced 2025-05-19 07:23:55 +02:00
Migrations and server bootstrap are very interconnected processes and in this we'll be addressing and improving both. Server bootstrap was performed by creating base entries in phases, eventually bringing up enough of the *oldest* supported server minimum remigration level, to then allow triggering of migrations. Migrations then applied "patches" effectively ontop of this minimum level to update entries to what they should be in newer versions of the server. This scheme has it's pros and cons, but the major con was that to remove a migration meant squashing it's content back into the minimum remigration level, and this was a human process that was quite error prone and difficult to automate. As well, this scheme also led to cases where the patch migrations would sometimes *not* reflect all the needed changes or content, or in one case was actually undone by a patchlevel fix up that was required to address a bug. Invariably this led to issues, and cases where a new server may have different content to a migrated one - not exactly what we want! This is a new migration scheme that addresses this fragility. However what it trades is verbosity of the content. Rather than having a base set of entries and patching/updating small sections ontop, we have migration data folders that contain the full set of entries as they should appear at that migration level. This makes the bootstrap process easier as we can just apply the migration level as a whole, and targetted to what precise version we want. This also makes migrations more durable as the content is explicitly copied and all entries fully applied, so there is no risk that a migration or data change can be forgotten or applied incorrectly. We are expressing the full state of what our builtin and provided entries should be. Finally this rips out a number of places where migration data was being used as test case data. Not all of these have been replaced (notably in authsession with Account), but the majority have and have been replaced with clearer use of constants rather than building whole entries just to access the name and throw them away for example.
265 lines
11 KiB
Rust
265 lines
11 KiB
Rust
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(),
|
|
]
|
|
}
|