mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 04:27:02 +01:00
Allow opt-in of easter eggs (#3308)
So that we can start to add some more easter eggs to the server, we also need to respect user preferences that may not want them. This adds a configuration setting to the domain allowing a release build to opt-in to easter eggs, and development builds to opt-out of them.
This commit is contained in:
parent
1fbbf323fa
commit
50a7d9d700
|
@ -1,4 +1,5 @@
|
|||
use crate::{ClientError, KanidmClient};
|
||||
use kanidm_proto::constants::ATTR_DOMAIN_ALLOW_EASTER_EGGS;
|
||||
use kanidm_proto::internal::ImageValue;
|
||||
use reqwest::multipart;
|
||||
|
||||
|
@ -8,6 +9,14 @@ impl KanidmClient {
|
|||
self.perform_delete_request("/v1/domain/_image").await
|
||||
}
|
||||
|
||||
pub async fn idm_set_domain_allow_easter_eggs(&self, enable: bool) -> Result<(), ClientError> {
|
||||
self.perform_put_request(
|
||||
&format!("{}{}", "/v1/domain/_attr/", ATTR_DOMAIN_ALLOW_EASTER_EGGS),
|
||||
vec![enable.to_string()],
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Add or update the domain logo/image
|
||||
pub async fn idm_domain_update_image(&self, image: ImageValue) -> Result<(), ClientError> {
|
||||
let file_content_type = image.filetype.as_content_type_str();
|
||||
|
|
|
@ -53,6 +53,7 @@ pub enum Attribute {
|
|||
DisplayName,
|
||||
Dn,
|
||||
Domain,
|
||||
DomainAllowEasterEggs,
|
||||
DomainDevelopmentTaint,
|
||||
DomainDisplayName,
|
||||
DomainLdapBasedn,
|
||||
|
@ -282,6 +283,7 @@ impl Attribute {
|
|||
Attribute::DisplayName => ATTR_DISPLAYNAME,
|
||||
Attribute::Dn => ATTR_DN,
|
||||
Attribute::Domain => ATTR_DOMAIN,
|
||||
Attribute::DomainAllowEasterEggs => ATTR_DOMAIN_ALLOW_EASTER_EGGS,
|
||||
Attribute::DomainDevelopmentTaint => ATTR_DOMAIN_DEVELOPMENT_TAINT,
|
||||
Attribute::DomainDisplayName => ATTR_DOMAIN_DISPLAY_NAME,
|
||||
Attribute::DomainLdapBasedn => ATTR_DOMAIN_LDAP_BASEDN,
|
||||
|
@ -464,6 +466,7 @@ impl Attribute {
|
|||
ATTR_DISPLAYNAME => Attribute::DisplayName,
|
||||
ATTR_DN => Attribute::Dn,
|
||||
ATTR_DOMAIN => Attribute::Domain,
|
||||
ATTR_DOMAIN_ALLOW_EASTER_EGGS => Attribute::DomainAllowEasterEggs,
|
||||
ATTR_DOMAIN_DISPLAY_NAME => Attribute::DomainDisplayName,
|
||||
ATTR_DOMAIN_DEVELOPMENT_TAINT => Attribute::DomainDevelopmentTaint,
|
||||
ATTR_DOMAIN_LDAP_BASEDN => Attribute::DomainLdapBasedn,
|
||||
|
|
|
@ -89,6 +89,7 @@ pub const ATTR_DESCRIPTION: &str = "description";
|
|||
pub const ATTR_DIRECTMEMBEROF: &str = "directmemberof";
|
||||
pub const ATTR_DISPLAYNAME: &str = "displayname";
|
||||
pub const ATTR_DN: &str = "dn";
|
||||
pub const ATTR_DOMAIN_ALLOW_EASTER_EGGS: &str = "domain_allow_easter_eggs";
|
||||
pub const ATTR_DOMAIN_DEVELOPMENT_TAINT: &str = "domain_development_taint";
|
||||
pub const ATTR_DOMAIN_DISPLAY_NAME: &str = "domain_display_name";
|
||||
pub const ATTR_DOMAIN_LDAP_BASEDN: &str = "domain_ldap_basedn";
|
||||
|
|
|
@ -1129,6 +1129,64 @@ lazy_static! {
|
|||
};
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref IDM_ACP_DOMAIN_ADMIN_DL9: BuiltinAcp = BuiltinAcp {
|
||||
classes: vec![
|
||||
EntryClass::Object,
|
||||
EntryClass::AccessControlProfile,
|
||||
EntryClass::AccessControlModify,
|
||||
EntryClass::AccessControlSearch
|
||||
],
|
||||
name: "idm_acp_domain_admin",
|
||||
uuid: UUID_IDM_ACP_DOMAIN_ADMIN_V1,
|
||||
description: "Builtin IDM Control for granting domain info administration locally",
|
||||
receiver: BuiltinAcpReceiver::Group(vec![UUID_DOMAIN_ADMINS]),
|
||||
target: BuiltinAcpTarget::Filter(ProtoFilter::And(vec![
|
||||
ProtoFilter::Eq(
|
||||
Attribute::Uuid.to_string(),
|
||||
STR_UUID_DOMAIN_INFO.to_string()
|
||||
),
|
||||
FILTER_ANDNOT_TOMBSTONE_OR_RECYCLED.clone()
|
||||
])),
|
||||
search_attrs: vec![
|
||||
Attribute::Class,
|
||||
Attribute::Name,
|
||||
Attribute::Uuid,
|
||||
Attribute::DomainAllowEasterEggs,
|
||||
Attribute::DomainDisplayName,
|
||||
Attribute::DomainName,
|
||||
Attribute::DomainLdapBasedn,
|
||||
Attribute::DomainSsid,
|
||||
Attribute::DomainUuid,
|
||||
Attribute::KeyInternalData,
|
||||
Attribute::LdapAllowUnixPwBind,
|
||||
Attribute::Version,
|
||||
Attribute::Image,
|
||||
],
|
||||
modify_removed_attrs: vec![
|
||||
Attribute::DomainDisplayName,
|
||||
Attribute::DomainSsid,
|
||||
Attribute::DomainLdapBasedn,
|
||||
Attribute::DomainAllowEasterEggs,
|
||||
Attribute::LdapAllowUnixPwBind,
|
||||
Attribute::KeyActionRevoke,
|
||||
Attribute::KeyActionRotate,
|
||||
Attribute::Image,
|
||||
],
|
||||
modify_present_attrs: vec![
|
||||
Attribute::DomainDisplayName,
|
||||
Attribute::DomainLdapBasedn,
|
||||
Attribute::DomainSsid,
|
||||
Attribute::DomainAllowEasterEggs,
|
||||
Attribute::LdapAllowUnixPwBind,
|
||||
Attribute::KeyActionRevoke,
|
||||
Attribute::KeyActionRotate,
|
||||
Attribute::Image,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref IDM_ACP_SYNC_ACCOUNT_MANAGE_V1: BuiltinAcp = BuiltinAcp {
|
||||
classes: vec![
|
||||
|
|
|
@ -770,6 +770,14 @@ pub static ref SCHEMA_ATTR_DOMAIN_DEVELOPMENT_TAINT_DL7: SchemaAttribute = Schem
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
pub static ref SCHEMA_ATTR_DOMAIN_ALLOW_EASTER_EGGS_DL9: SchemaAttribute = SchemaAttribute {
|
||||
uuid: UUID_SCHEMA_ATTR_DOMAIN_ALLOW_EASTER_EGGS,
|
||||
name: Attribute::DomainAllowEasterEggs,
|
||||
description: "A flag to enable easter eggs in the server that may not always be wanted by all users/deployments.".to_string(),
|
||||
syntax: SyntaxType::Boolean,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
pub static ref SCHEMA_ATTR_REFERS_DL7: SchemaAttribute = SchemaAttribute {
|
||||
uuid: UUID_SCHEMA_ATTR_REFERS,
|
||||
name: Attribute::Refers,
|
||||
|
@ -1177,6 +1185,30 @@ pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL8: SchemaClass = SchemaClass {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL9: SchemaClass = SchemaClass {
|
||||
uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO,
|
||||
name: EntryClass::DomainInfo.into(),
|
||||
description: "Local domain information and configuration".to_string(),
|
||||
|
||||
systemmay: vec![
|
||||
Attribute::DomainSsid,
|
||||
Attribute::DomainLdapBasedn,
|
||||
Attribute::LdapAllowUnixPwBind,
|
||||
Attribute::Image,
|
||||
Attribute::PatchLevel,
|
||||
Attribute::DomainDevelopmentTaint,
|
||||
Attribute::DomainAllowEasterEggs,
|
||||
],
|
||||
systemmust: vec![
|
||||
Attribute::Name,
|
||||
Attribute::DomainUuid,
|
||||
Attribute::DomainName,
|
||||
Attribute::DomainDisplayName,
|
||||
Attribute::Version,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
pub static ref SCHEMA_CLASS_POSIXGROUP: SchemaClass = SchemaClass {
|
||||
uuid: UUID_SCHEMA_CLASS_POSIXGROUP,
|
||||
name: EntryClass::PosixGroup.into(),
|
||||
|
|
|
@ -321,6 +321,8 @@ pub const UUID_SCHEMA_ATTR_APPLICATION_PASSWORD: Uuid =
|
|||
pub const UUID_SCHEMA_ATTR_CREATED_AT_CID: Uuid = uuid!("00000000-0000-0000-0000-ffff00000184");
|
||||
pub const UUID_SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffff00000185");
|
||||
pub const UUID_SCHEMA_ATTR_DOMAIN_ALLOW_EASTER_EGGS: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffff00000186");
|
||||
|
||||
// System and domain infos
|
||||
// I'd like to strongly criticise william of the past for making poor choices about these allocations.
|
||||
|
|
|
@ -647,7 +647,9 @@ impl QueryServerWriteTransaction<'_> {
|
|||
// 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
|
||||
|
@ -663,6 +665,7 @@ impl QueryServerWriteTransaction<'_> {
|
|||
let idm_data = [
|
||||
IDM_ACP_OAUTH2_MANAGE_DL9.clone().into(),
|
||||
IDM_ACP_GROUP_MANAGE_DL9.clone().into(),
|
||||
IDM_ACP_DOMAIN_ADMIN_DL9.clone().into(),
|
||||
];
|
||||
|
||||
idm_data
|
||||
|
|
|
@ -79,6 +79,7 @@ pub struct DomainInfo {
|
|||
pub(crate) d_patch_level: u32,
|
||||
pub(crate) d_devel_taint: bool,
|
||||
pub(crate) d_ldap_allow_unix_pw_bind: bool,
|
||||
pub(crate) d_allow_easter_eggs: bool,
|
||||
// In future this should be image reference instead of the image itself.
|
||||
d_image: Option<ImageValue>,
|
||||
}
|
||||
|
@ -103,6 +104,10 @@ impl DomainInfo {
|
|||
pub fn has_custom_image(&self) -> bool {
|
||||
self.d_image.is_some()
|
||||
}
|
||||
|
||||
pub fn allow_easter_eggs(&self) -> bool {
|
||||
self.d_allow_easter_eggs
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||
|
@ -1657,6 +1662,7 @@ impl QueryServer {
|
|||
// Automatically derive our current taint mode based on the PRERELEASE setting.
|
||||
d_devel_taint: option_env!("KANIDM_PRE_RELEASE").is_some(),
|
||||
d_ldap_allow_unix_pw_bind: false,
|
||||
d_allow_easter_eggs: false,
|
||||
d_image: None,
|
||||
}));
|
||||
|
||||
|
@ -2284,6 +2290,11 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
.get_ava_single_bool(Attribute::DomainDevelopmentTaint)
|
||||
.unwrap_or_default();
|
||||
|
||||
let domain_allow_easter_eggs = domain_info
|
||||
.get_ava_single_bool(Attribute::DomainAllowEasterEggs)
|
||||
// This defaults to false for release versions, and true in development
|
||||
.unwrap_or(option_env!("KANIDM_PRE_RELEASE").is_some());
|
||||
|
||||
// We have to set the domain version here so that features which check for it
|
||||
// will now see it's been increased. This also prevents recursion during reloads
|
||||
// inside of a domain migration.
|
||||
|
@ -2293,6 +2304,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
mut_d_info.d_vers = domain_info_version;
|
||||
mut_d_info.d_patch_level = domain_info_patch_level;
|
||||
mut_d_info.d_devel_taint = domain_info_devel_taint;
|
||||
mut_d_info.d_allow_easter_eggs = domain_allow_easter_eggs;
|
||||
|
||||
// We must both be at the correct domain version *and* the correct patch level. If we are
|
||||
// not, then we only proceed to migrate *if* our server boot phase is correct.
|
||||
|
|
|
@ -12,6 +12,7 @@ impl DomainOpt {
|
|||
| DomainOpt::SetImage { copt, .. }
|
||||
| DomainOpt::RemoveImage { copt }
|
||||
| DomainOpt::SetLdapAllowUnixPasswordBind { copt, .. }
|
||||
| DomainOpt::SetAllowEasterEggs { copt, .. }
|
||||
| DomainOpt::RevokeKey { copt, .. }
|
||||
| DomainOpt::Show(copt) => copt.debug,
|
||||
}
|
||||
|
@ -51,6 +52,19 @@ impl DomainOpt {
|
|||
Err(e) => handle_client_error(e, copt.output_mode),
|
||||
}
|
||||
}
|
||||
DomainOpt::SetAllowEasterEggs { copt, enable } => {
|
||||
let client = copt.to_client(OpType::Write).await;
|
||||
match client.idm_set_domain_allow_easter_eggs(*enable).await {
|
||||
Ok(_) => {
|
||||
if *enable {
|
||||
println!("Success 🎉 🥚 🎉")
|
||||
} else {
|
||||
println!("Success")
|
||||
}
|
||||
}
|
||||
Err(e) => handle_client_error(e, copt.output_mode),
|
||||
}
|
||||
}
|
||||
DomainOpt::Show(copt) => {
|
||||
let client = copt.to_client(OpType::Read).await;
|
||||
match client.idm_domain_get().await {
|
||||
|
|
|
@ -1332,6 +1332,15 @@ pub enum DomainOpt {
|
|||
#[clap(name = "allow", action = clap::ArgAction::Set)]
|
||||
enable: bool,
|
||||
},
|
||||
/// Enable or disable easter eggs in the server. This includes seasonal icons, kanidm
|
||||
/// birthday surprises and other fun components. Defaults to false for production releases
|
||||
/// and true in development builds.
|
||||
SetAllowEasterEggs {
|
||||
#[clap(flatten)]
|
||||
copt: CommonOpt,
|
||||
#[clap(name = "allow", action = clap::ArgAction::Set)]
|
||||
enable: bool,
|
||||
},
|
||||
#[clap(name = "show")]
|
||||
/// Show information about this system's domain
|
||||
Show(CommonOpt),
|
||||
|
|
Loading…
Reference in a new issue