mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
Update to account recovery UX (#859)
* JSON-formatted output for recover_account, moved a bunch of logs to debug instead of info * updated documentation
This commit is contained in:
parent
4b1989ee22
commit
57f8fa9d2b
|
@ -148,7 +148,7 @@ in `/tmp/kanidm.db`.
|
||||||
|
|
||||||
Create the initial database and generate an `admin` username:
|
Create the initial database and generate an `admin` username:
|
||||||
|
|
||||||
cargo run --bin kanidmd recover_account -c ./examples/insecure_server.toml -n admin
|
cargo run --bin kanidmd recover_account -c ./examples/insecure_server.toml admin
|
||||||
<snip>
|
<snip>
|
||||||
Success - password reset to -> Et8QRJgQkMJu3v1AQxcbxRWW44qRUZPpr6BJ9fCGapAB9cT4
|
Success - password reset to -> Et8QRJgQkMJu3v1AQxcbxRWW44qRUZPpr6BJ9fCGapAB9cT4
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,7 @@ You should test your configuration is valid before you proceed.
|
||||||
Then you can setup the initial admin account and initialise the database into your volume.
|
Then you can setup the initial admin account and initialise the database into your volume.
|
||||||
|
|
||||||
docker run --rm -i -t -v kanidmd:/data \
|
docker run --rm -i -t -v kanidmd:/data \
|
||||||
kanidm/server:latest /sbin/kanidmd recover_account -c /data/server.toml -n admin
|
kanidm/server:latest /sbin/kanidmd recover_account -c /data/server.toml admin
|
||||||
|
|
||||||
### Run the Server
|
### Run the Server
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ tracing = "^0.1.35"
|
||||||
reqwest = { version = "^0.11.11", features=["cookies", "json", "native-tls"] }
|
reqwest = { version = "^0.11.11", features=["cookies", "json", "native-tls"] }
|
||||||
kanidm_proto = { path = "../kanidm_proto", version = "1.1.0-alpha.8" }
|
kanidm_proto = { path = "../kanidm_proto", version = "1.1.0-alpha.8" }
|
||||||
serde = { version = "^1.0.137", features = ["derive"] }
|
serde = { version = "^1.0.137", features = ["derive"] }
|
||||||
serde_json = "^1.0.80"
|
serde_json = "^1.0.81"
|
||||||
toml = "^0.5.9"
|
toml = "^0.5.9"
|
||||||
uuid = { version = "^1.1.2", features = ["serde", "v4"] }
|
uuid = { version = "^1.1.2", features = ["serde", "v4"] }
|
||||||
url = { version = "^2.2.2", features = ["serde"] }
|
url = { version = "^2.2.2", features = ["serde"] }
|
||||||
|
|
|
@ -12,7 +12,7 @@ repository = "https://github.com/kanidm/kanidm/"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "^1.0.137", features = ["derive"] }
|
serde = { version = "^1.0.137", features = ["derive"] }
|
||||||
serde_json = "^1.0.80"
|
serde_json = "^1.0.81"
|
||||||
uuid = { version = "^1.1.2", features = ["serde"] }
|
uuid = { version = "^1.1.2", features = ["serde"] }
|
||||||
base32 = "^0.4.0"
|
base32 = "^0.4.0"
|
||||||
webauthn-rs = { version = "^0.3.2", default-features = false, features = ["wasm"] }
|
webauthn-rs = { version = "^0.3.2", default-features = false, features = ["wasm"] }
|
||||||
|
|
|
@ -37,7 +37,7 @@ rpassword = "^6.0.1"
|
||||||
clap = { version = "^3.2", features = ["derive", "env"] }
|
clap = { version = "^3.2", features = ["derive", "env"] }
|
||||||
libc = "^0.2.126"
|
libc = "^0.2.126"
|
||||||
serde = { version = "^1.0.137", features = ["derive"] }
|
serde = { version = "^1.0.137", features = ["derive"] }
|
||||||
serde_json = "^1.0.80"
|
serde_json = "^1.0.81"
|
||||||
shellexpand = "^2.1.0"
|
shellexpand = "^2.1.0"
|
||||||
rayon = "^1.5.3"
|
rayon = "^1.5.3"
|
||||||
time = { version = "=0.2.27", features = ["serde", "std"] }
|
time = { version = "=0.2.27", features = ["serde", "std"] }
|
||||||
|
|
|
@ -60,7 +60,7 @@ bytes = "^1.1.0"
|
||||||
|
|
||||||
libc = "^0.2.126"
|
libc = "^0.2.126"
|
||||||
serde = { version = "^1.0.137", features = ["derive"] }
|
serde = { version = "^1.0.137", features = ["derive"] }
|
||||||
serde_json = "^1.0.80"
|
serde_json = "^1.0.81"
|
||||||
clap = { version = "^3.2", features = ["derive"] }
|
clap = { version = "^3.2", features = ["derive"] }
|
||||||
|
|
||||||
libsqlite3-sys = "0.24.2"
|
libsqlite3-sys = "0.24.2"
|
||||||
|
|
|
@ -28,7 +28,7 @@ use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use kanidm::audit::LogLevel;
|
use kanidm::audit::LogLevel;
|
||||||
use kanidm::config::{Configuration, OnlineBackup, ServerRole};
|
use kanidm::config::{Configuration, ConsoleOutputMode, OnlineBackup, ServerRole};
|
||||||
use kanidm::tracing_tree;
|
use kanidm::tracing_tree;
|
||||||
use kanidm::utils::file_permissions_readonly;
|
use kanidm::utils::file_permissions_readonly;
|
||||||
use score::{
|
use score::{
|
||||||
|
@ -221,6 +221,9 @@ async fn main() {
|
||||||
config.update_domain(&sconfig.domain.as_str());
|
config.update_domain(&sconfig.domain.as_str());
|
||||||
config.update_db_arc_size(sconfig.db_arc_size);
|
config.update_db_arc_size(sconfig.db_arc_size);
|
||||||
config.update_role(sconfig.role);
|
config.update_role(sconfig.role);
|
||||||
|
config.update_output_mode(
|
||||||
|
ConsoleOutputMode::from_str(opt.commands.commonopt().output_mode.as_str()).unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
// Apply any cli overrides, normally debug level.
|
// Apply any cli overrides, normally debug level.
|
||||||
if let Some(dll) = opt.commands.commonopt().debug.as_ref() {
|
if let Some(dll) = opt.commands.commonopt().debug.as_ref() {
|
||||||
|
|
|
@ -6,6 +6,10 @@ struct CommonOpt {
|
||||||
#[clap(parse(from_os_str), short, long = "config", env = "KANIDM_CONFIG")]
|
#[clap(parse(from_os_str), short, long = "config", env = "KANIDM_CONFIG")]
|
||||||
/// Path to the server's configuration file. If it does not exist, it will be created.
|
/// Path to the server's configuration file. If it does not exist, it will be created.
|
||||||
config_path: PathBuf,
|
config_path: PathBuf,
|
||||||
|
//TODO: remove this once we work out the format
|
||||||
|
/// Log format (still in very early development)
|
||||||
|
#[clap(short, long = "output", env = "KANIDM_OUTPUT", default_value="text")]
|
||||||
|
output_mode: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Args)]
|
#[derive(Debug, Args)]
|
||||||
|
@ -28,7 +32,7 @@ struct RestoreOpt {
|
||||||
|
|
||||||
#[derive(Debug, Args)]
|
#[derive(Debug, Args)]
|
||||||
struct RecoverAccountOpt {
|
struct RecoverAccountOpt {
|
||||||
#[clap(short)]
|
#[clap(value_parser)]
|
||||||
/// The account name to recover credentials for.
|
/// The account name to recover credentials for.
|
||||||
name: String,
|
name: String,
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
|
|
|
@ -48,7 +48,7 @@ uuid = { version = "^1.1.2", features = ["serde", "v4" ] }
|
||||||
compiled-uuid = "0.1.2"
|
compiled-uuid = "0.1.2"
|
||||||
serde = { version = "^1.0.137", features = ["derive"] }
|
serde = { version = "^1.0.137", features = ["derive"] }
|
||||||
serde_cbor = "^0.11.2"
|
serde_cbor = "^0.11.2"
|
||||||
serde_json = "^1.0.80"
|
serde_json = "^1.0.81"
|
||||||
|
|
||||||
libsqlite3-sys = "0.24.2"
|
libsqlite3-sys = "0.24.2"
|
||||||
rusqlite = "^0.27.0"
|
rusqlite = "^0.27.0"
|
||||||
|
|
|
@ -1255,7 +1255,7 @@ impl<'a> BackendWriteTransaction<'a> {
|
||||||
|
|
||||||
pub fn upgrade_reindex(&self, v: i64) -> Result<(), OperationError> {
|
pub fn upgrade_reindex(&self, v: i64) -> Result<(), OperationError> {
|
||||||
let dbv = self.get_db_index_version();
|
let dbv = self.get_db_index_version();
|
||||||
admin_info!(?dbv, ?v, "upgrade_reindex");
|
admin_debug!(?dbv, ?v, "upgrade_reindex");
|
||||||
if dbv < v {
|
if dbv < v {
|
||||||
limmediate_warning!(
|
limmediate_warning!(
|
||||||
"NOTICE: A system reindex is required. This may take a long time ...\n"
|
"NOTICE: A system reindex is required. This may take a long time ...\n"
|
||||||
|
@ -1514,9 +1514,9 @@ impl Backend {
|
||||||
idxkeys: Vec<IdxKey>,
|
idxkeys: Vec<IdxKey>,
|
||||||
vacuum: bool,
|
vacuum: bool,
|
||||||
) -> Result<Self, OperationError> {
|
) -> Result<Self, OperationError> {
|
||||||
info!("DB tickets -> {:?}", cfg.pool_size);
|
debug!("DB tickets -> {:?}", cfg.pool_size);
|
||||||
info!("Profile -> {}", env!("KANIDM_PROFILE_NAME"));
|
debug!("Profile -> {}", env!("KANIDM_PROFILE_NAME"));
|
||||||
info!("CPU Flags -> {}", env!("KANIDM_CPU_FLAGS"));
|
debug!("CPU Flags -> {}", env!("KANIDM_CPU_FLAGS"));
|
||||||
|
|
||||||
// If in memory, reduce pool to 1
|
// If in memory, reduce pool to 1
|
||||||
if cfg.path.is_empty() {
|
if cfg.path.is_empty() {
|
||||||
|
|
|
@ -74,6 +74,31 @@ impl FromStr for ServerRole {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this should probably be in the kanidm crate
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum ConsoleOutputMode {
|
||||||
|
Text,
|
||||||
|
JSON,
|
||||||
|
}
|
||||||
|
impl Default for ConsoleOutputMode {
|
||||||
|
fn default() -> Self {
|
||||||
|
ConsoleOutputMode::Text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for ConsoleOutputMode {
|
||||||
|
type Err = &'static str;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
match s {
|
||||||
|
"json" => Ok(ConsoleOutputMode::JSON),
|
||||||
|
"text" => Ok(ConsoleOutputMode::Text),
|
||||||
|
_ => Err("Must be one of json, text"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||||
pub struct Configuration {
|
pub struct Configuration {
|
||||||
pub address: String,
|
pub address: String,
|
||||||
|
@ -93,6 +118,7 @@ pub struct Configuration {
|
||||||
pub domain: String,
|
pub domain: String,
|
||||||
pub origin: String,
|
pub origin: String,
|
||||||
pub role: ServerRole,
|
pub role: ServerRole,
|
||||||
|
pub output_mode: ConsoleOutputMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Configuration {
|
impl fmt::Display for Configuration {
|
||||||
|
@ -112,21 +138,23 @@ impl fmt::Display for Configuration {
|
||||||
.and_then(|_| write!(f, "secure cookies: {}, ", self.secure_cookies))
|
.and_then(|_| write!(f, "secure cookies: {}, ", self.secure_cookies))
|
||||||
.and_then(|_| write!(f, "with TLS: {}, ", self.tls_config.is_some()))
|
.and_then(|_| write!(f, "with TLS: {}, ", self.tls_config.is_some()))
|
||||||
.and_then(|_| match self.log_level {
|
.and_then(|_| match self.log_level {
|
||||||
Some(u) => write!(f, "with log_level: {:x}, ", u),
|
Some(u) => write!(f, "log_level: {:x}, ", u),
|
||||||
None => write!(f, "with log_level: default, "),
|
None => write!(f, "log_level: default, "),
|
||||||
})
|
})
|
||||||
|
// TODO: include the backup timings
|
||||||
.and_then(|_| match &self.online_backup {
|
.and_then(|_| match &self.online_backup {
|
||||||
Some(_) => write!(f, "with online_backup: enabled, "),
|
Some(_) => write!(f, "online_backup: enabled, "),
|
||||||
None => write!(f, "with online_backup: disabled, "),
|
None => write!(f, "online_backup: disabled, "),
|
||||||
})
|
})
|
||||||
.and_then(|_| write!(f, "role: {}, ", self.role.to_string()))
|
.and_then(|_| write!(f, "role: {}, ", self.role.to_string()))
|
||||||
.and_then(|_| {
|
.and_then(|_| {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"integration mode: {}",
|
"integration mode: {}, ",
|
||||||
self.integration_test_config.is_some()
|
self.integration_test_config.is_some()
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
.and_then(|_| write!(f, "console output format: {:?} ", self.output_mode))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +172,7 @@ impl Configuration {
|
||||||
db_path: String::from(""),
|
db_path: String::from(""),
|
||||||
db_fs_type: None,
|
db_fs_type: None,
|
||||||
db_arc_size: None,
|
db_arc_size: None,
|
||||||
maximum_request: 262_144, // 256k
|
maximum_request: 256 * 1024, // 256k
|
||||||
// log type
|
// log type
|
||||||
// log path
|
// log path
|
||||||
// TODO #63: default true in prd
|
// TODO #63: default true in prd
|
||||||
|
@ -157,6 +185,7 @@ impl Configuration {
|
||||||
domain: "idm.example.com".to_string(),
|
domain: "idm.example.com".to_string(),
|
||||||
origin: "https://idm.example.com".to_string(),
|
origin: "https://idm.example.com".to_string(),
|
||||||
role: ServerRole::WriteReplica,
|
role: ServerRole::WriteReplica,
|
||||||
|
output_mode: ConsoleOutputMode::default(),
|
||||||
};
|
};
|
||||||
let mut rng = StdRng::from_entropy();
|
let mut rng = StdRng::from_entropy();
|
||||||
rng.fill(&mut c.cookie_key);
|
rng.fill(&mut c.cookie_key);
|
||||||
|
@ -218,6 +247,11 @@ impl Configuration {
|
||||||
self.role = r;
|
self.role = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the output mode for writing to the console
|
||||||
|
pub fn update_output_mode(&mut self, om: ConsoleOutputMode) {
|
||||||
|
self.output_mode = om;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update_tls(&mut self, chain: &Option<String>, key: &Option<String>) {
|
pub fn update_tls(&mut self, chain: &Option<String>, key: &Option<String>) {
|
||||||
match (chain, key) {
|
match (chain, key) {
|
||||||
(None, None) => {}
|
(None, None) => {}
|
||||||
|
|
|
@ -93,9 +93,9 @@ pub mod prelude {
|
||||||
ValueSetUuid,
|
ValueSetUuid,
|
||||||
};
|
};
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
admin_error, admin_info, admin_warn, filter_error, filter_info, filter_trace, filter_warn,
|
admin_debug, admin_error, admin_info, admin_warn, filter_error, filter_info, filter_trace,
|
||||||
perf_trace, request_error, request_info, request_trace, request_warn, security_access,
|
filter_warn, perf_trace, request_error, request_info, request_trace, request_warn,
|
||||||
security_critical, security_error, security_info, spanned,
|
security_access, security_critical, security_error, security_info, spanned,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1354,10 +1354,10 @@ impl<'a> SchemaWriteTransaction<'a> {
|
||||||
|
|
||||||
let r = self.validate();
|
let r = self.validate();
|
||||||
if r.is_empty() {
|
if r.is_empty() {
|
||||||
admin_info!("schema validate -> passed");
|
admin_debug!("schema validate -> passed");
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
admin_info!(err = ?r, "schema validate -> errors");
|
admin_error!(err = ?r, "schema validate -> errors");
|
||||||
Err(OperationError::ConsistencyError(r))
|
Err(OperationError::ConsistencyError(r))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1094,7 +1094,7 @@ impl QueryServer {
|
||||||
Err(OperationError::NoMatchingEntries) => Ok(0),
|
Err(OperationError::NoMatchingEntries) => Ok(0),
|
||||||
Err(r) => Err(r),
|
Err(r) => Err(r),
|
||||||
}?;
|
}?;
|
||||||
admin_info!(?system_info_version);
|
admin_debug!(?system_info_version);
|
||||||
|
|
||||||
if system_info_version < 3 {
|
if system_info_version < 3 {
|
||||||
migrate_txn.migrate_2_to_3()?;
|
migrate_txn.migrate_2_to_3()?;
|
||||||
|
@ -1119,8 +1119,8 @@ impl QueryServer {
|
||||||
ts_write_3
|
ts_write_3
|
||||||
.initialise_idm()
|
.initialise_idm()
|
||||||
.and_then(|_| ts_write_3.commit())?;
|
.and_then(|_| ts_write_3.commit())?;
|
||||||
|
// TODO: work out if we've actually done any migrations before printing this
|
||||||
admin_info!("migrations success! ☀️ ");
|
admin_debug!("Database version check and migrations success! ☀️ ");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2267,7 +2267,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub fn initialise_schema_core(&self) -> Result<(), OperationError> {
|
pub fn initialise_schema_core(&self) -> Result<(), OperationError> {
|
||||||
admin_info!("initialise_schema_core -> start ...");
|
admin_debug!("initialise_schema_core -> start ...");
|
||||||
// Load in all the "core" schema, that we already have in "memory".
|
// Load in all the "core" schema, that we already have in "memory".
|
||||||
let entries = self.schema.to_entries();
|
let entries = self.schema.to_entries();
|
||||||
|
|
||||||
|
@ -2277,9 +2277,9 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
self.internal_migrate_or_create(e)
|
self.internal_migrate_or_create(e)
|
||||||
});
|
});
|
||||||
if r.is_ok() {
|
if r.is_ok() {
|
||||||
admin_info!("initialise_schema_core -> Ok!");
|
admin_debug!("initialise_schema_core -> Ok!");
|
||||||
} else {
|
} else {
|
||||||
admin_info!(?r, "initialise_schema_core -> Error");
|
admin_error!(?r, "initialise_schema_core -> Error");
|
||||||
}
|
}
|
||||||
// why do we have error handling if it's always supposed to be `Ok`?
|
// why do we have error handling if it's always supposed to be `Ok`?
|
||||||
debug_assert!(r.is_ok());
|
debug_assert!(r.is_ok());
|
||||||
|
@ -2287,7 +2287,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initialise_schema_idm(&self) -> Result<(), OperationError> {
|
pub fn initialise_schema_idm(&self) -> Result<(), OperationError> {
|
||||||
admin_info!("initialise_schema_idm -> start ...");
|
admin_debug!("initialise_schema_idm -> start ...");
|
||||||
// List of IDM schemas to init.
|
// List of IDM schemas to init.
|
||||||
let idm_schema: Vec<&str> = vec![
|
let idm_schema: Vec<&str> = vec![
|
||||||
JSON_SCHEMA_ATTR_DISPLAYNAME,
|
JSON_SCHEMA_ATTR_DISPLAYNAME,
|
||||||
|
@ -2338,7 +2338,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
.try_for_each(|e_str| self.internal_migrate_or_create_str(e_str));
|
.try_for_each(|e_str| self.internal_migrate_or_create_str(e_str));
|
||||||
|
|
||||||
if r.is_ok() {
|
if r.is_ok() {
|
||||||
admin_info!("initialise_schema_idm -> Ok!");
|
admin_debug!("initialise_schema_idm -> Ok!");
|
||||||
} else {
|
} else {
|
||||||
admin_error!(res = ?r, "initialise_schema_idm -> Error");
|
admin_error!(res = ?r, "initialise_schema_idm -> Error");
|
||||||
}
|
}
|
||||||
|
@ -2467,7 +2467,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
.iter()
|
.iter()
|
||||||
.try_for_each(|e_str| self.internal_migrate_or_create_str(e_str));
|
.try_for_each(|e_str| self.internal_migrate_or_create_str(e_str));
|
||||||
if res.is_ok() {
|
if res.is_ok() {
|
||||||
admin_info!("initialise_idm -> result Ok!");
|
admin_debug!("initialise_idm -> result Ok!");
|
||||||
} else {
|
} else {
|
||||||
admin_error!(?res, "initialise_idm p3 -> result");
|
admin_error!(?res, "initialise_idm p3 -> result");
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||||
#[derive(Debug, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
|
#[derive(Debug, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
|
||||||
#[repr(u64)]
|
#[repr(u64)]
|
||||||
pub enum EventTag {
|
pub enum EventTag {
|
||||||
|
AdminDebug,
|
||||||
AdminError,
|
AdminError,
|
||||||
AdminWarn,
|
AdminWarn,
|
||||||
AdminInfo,
|
AdminInfo,
|
||||||
|
@ -24,6 +25,7 @@ pub enum EventTag {
|
||||||
impl EventTag {
|
impl EventTag {
|
||||||
pub fn pretty(self) -> &'static str {
|
pub fn pretty(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
|
EventTag::AdminDebug => "admin.debug",
|
||||||
EventTag::AdminError => "admin.error",
|
EventTag::AdminError => "admin.error",
|
||||||
EventTag::AdminWarn => "admin.warn",
|
EventTag::AdminWarn => "admin.warn",
|
||||||
EventTag::AdminInfo => "admin.info",
|
EventTag::AdminInfo => "admin.info",
|
||||||
|
@ -46,8 +48,9 @@ impl EventTag {
|
||||||
pub fn emoji(self) -> &'static str {
|
pub fn emoji(self) -> &'static str {
|
||||||
use EventTag::*;
|
use EventTag::*;
|
||||||
match self {
|
match self {
|
||||||
|
AdminDebug => "🐛",
|
||||||
AdminError | FilterError | RequestError | SecurityError => "🚨",
|
AdminError | FilterError | RequestError | SecurityError => "🚨",
|
||||||
AdminWarn | FilterWarn | RequestWarn => "⚠️ ",
|
AdminWarn | FilterWarn | RequestWarn => "⚠️",
|
||||||
AdminInfo | FilterInfo | RequestInfo | SecurityInfo => " ",
|
AdminInfo | FilterInfo | RequestInfo | SecurityInfo => " ",
|
||||||
RequestTrace | FilterTrace | PerfTrace => "📍",
|
RequestTrace | FilterTrace | PerfTrace => "📍",
|
||||||
SecurityCritical => "🔐",
|
SecurityCritical => "🔐",
|
||||||
|
|
|
@ -25,6 +25,11 @@ macro_rules! tagged_event {
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! admin_debug {
|
||||||
|
($($arg:tt)*) => { tagged_event!(DEBUG, EventTag::AdminDebug, $($arg)*) }
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! admin_error {
|
macro_rules! admin_error {
|
||||||
($($arg:tt)*) => { tagged_event!(ERROR, EventTag::AdminError, $($arg)*) }
|
($($arg:tt)*) => { tagged_event!(ERROR, EventTag::AdminError, $($arg)*) }
|
||||||
|
|
|
@ -31,6 +31,8 @@ ldap3_proto = "^0.2.3"
|
||||||
|
|
||||||
tracing = { version = "^0.1.35", features = ["attributes"] }
|
tracing = { version = "^0.1.35", features = ["attributes"] }
|
||||||
serde = { version = "^1.0.137", features = ["derive"] }
|
serde = { version = "^1.0.137", features = ["derive"] }
|
||||||
|
serde_json = "^1.0.81"
|
||||||
|
|
||||||
async-trait = "^0.1.53"
|
async-trait = "^0.1.53"
|
||||||
async-std = { version = "^1.12.0", features = ["tokio1"] }
|
async-std = { version = "^1.12.0", features = ["tokio1"] }
|
||||||
compact_jwt = "^0.2.1"
|
compact_jwt = "^0.2.1"
|
||||||
|
@ -44,7 +46,6 @@ tracing-subscriber = "^0.3.11"
|
||||||
# kanidm = { path = "../kanidmd" }
|
# kanidm = { path = "../kanidmd" }
|
||||||
# score = { path = "../kanidmd/score" }
|
# score = { path = "../kanidmd/score" }
|
||||||
futures = "^0.3.21"
|
futures = "^0.3.21"
|
||||||
serde_json = "^1.0.80"
|
|
||||||
# async-std = { version = "1.6", features = ["tokio1"] }
|
# async-std = { version = "1.6", features = ["tokio1"] }
|
||||||
|
|
||||||
webauthn-authenticator-rs = "^0.3.2"
|
webauthn-authenticator-rs = "^0.3.2"
|
||||||
|
|
|
@ -27,19 +27,17 @@ extern crate kanidm;
|
||||||
|
|
||||||
mod https;
|
mod https;
|
||||||
mod ldaps;
|
mod ldaps;
|
||||||
use libc::umask;
|
|
||||||
|
|
||||||
// use crossbeam::channel::unbounded;
|
// use crossbeam::channel::unbounded;
|
||||||
|
use async_std::task;
|
||||||
|
use compact_jwt::JwsSigner;
|
||||||
use kanidm::prelude::*;
|
use kanidm::prelude::*;
|
||||||
use std::sync::Arc;
|
use libc::umask;
|
||||||
|
|
||||||
use kanidm::config::Configuration;
|
|
||||||
|
|
||||||
// SearchResult
|
|
||||||
// use self::ctx::ServerCtx;
|
|
||||||
use kanidm::actors::v1_read::QueryServerReadV1;
|
use kanidm::actors::v1_read::QueryServerReadV1;
|
||||||
use kanidm::actors::v1_write::QueryServerWriteV1;
|
use kanidm::actors::v1_write::QueryServerWriteV1;
|
||||||
use kanidm::be::{Backend, BackendConfig, BackendTransaction, FsType};
|
use kanidm::be::{Backend, BackendConfig, BackendTransaction, FsType};
|
||||||
|
use kanidm::config::{Configuration, ConsoleOutputMode};
|
||||||
use kanidm::crypto::setup_tls;
|
use kanidm::crypto::setup_tls;
|
||||||
use kanidm::idm::server::{IdmServer, IdmServerDelayed};
|
use kanidm::idm::server::{IdmServer, IdmServerDelayed};
|
||||||
use kanidm::interval::IntervalActor;
|
use kanidm::interval::IntervalActor;
|
||||||
|
@ -47,11 +45,12 @@ use kanidm::ldap::LdapServer;
|
||||||
use kanidm::schema::Schema;
|
use kanidm::schema::Schema;
|
||||||
use kanidm::status::StatusActor;
|
use kanidm::status::StatusActor;
|
||||||
use kanidm::utils::{duration_from_epoch_now, touch_file_or_quit};
|
use kanidm::utils::{duration_from_epoch_now, touch_file_or_quit};
|
||||||
|
|
||||||
use kanidm_proto::v1::OperationError;
|
use kanidm_proto::v1::OperationError;
|
||||||
|
|
||||||
use async_std::task;
|
use serde::{Deserialize, Serialize};
|
||||||
use compact_jwt::JwsSigner;
|
use serde_json;
|
||||||
|
use std::fmt;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
// === internal setup helpers
|
// === internal setup helpers
|
||||||
|
|
||||||
|
@ -484,6 +483,42 @@ pub fn verify_server_core(config: &Configuration) {
|
||||||
// Now add IDM server verifications?
|
// Now add IDM server verifications?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: should this go somewhere else
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
enum MessageStatus {
|
||||||
|
Failure,
|
||||||
|
Success,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for MessageStatus {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> {
|
||||||
|
match *self {
|
||||||
|
MessageStatus::Failure => f.write_str("failure"),
|
||||||
|
MessageStatus::Success => f.write_str("status"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct AccountChangeMessage {
|
||||||
|
action: String,
|
||||||
|
result: String,
|
||||||
|
status: MessageStatus,
|
||||||
|
src_user: String,
|
||||||
|
dest_user: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for AccountChangeMessage {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{}",
|
||||||
|
serde_json::to_string(self).unwrap_or(format!("{:?}", self))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn recover_account_core(config: &Configuration, name: &str) {
|
pub fn recover_account_core(config: &Configuration, name: &str) {
|
||||||
let schema = match Schema::new() {
|
let schema = match Schema::new() {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
|
@ -527,7 +562,26 @@ pub fn recover_account_core(config: &Configuration, name: &str) {
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("Success - password reset to -> {}", new_pw);
|
match config.output_mode {
|
||||||
|
ConsoleOutputMode::JSON => {
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
AccountChangeMessage {
|
||||||
|
status: MessageStatus::Success,
|
||||||
|
src_user: String::from("command-line invocation"),
|
||||||
|
dest_user: name.to_string(),
|
||||||
|
result: new_pw,
|
||||||
|
action: String::from("recover_account"),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ConsoleOutputMode::Text => {
|
||||||
|
println!(
|
||||||
|
"Successfully recovered account '{}' - password reset to -> {}",
|
||||||
|
name, new_pw
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_server_core(config: Configuration, config_test: bool) -> Result<(), ()> {
|
pub async fn create_server_core(config: Configuration, config_test: bool) -> Result<(), ()> {
|
||||||
|
|
|
@ -18,7 +18,7 @@ crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "^1.0.137", features = ["derive"] }
|
serde = { version = "^1.0.137", features = ["derive"] }
|
||||||
serde_json = "^1.0.80"
|
serde_json = "^1.0.81"
|
||||||
|
|
||||||
wasm-bindgen = { version = "^0.2.81", features = ["serde-serialize"] }
|
wasm-bindgen = { version = "^0.2.81", features = ["serde-serialize"] }
|
||||||
wasm-bindgen-futures = { version = "^0.4.30" }
|
wasm-bindgen-futures = { version = "^0.4.30" }
|
||||||
|
|
|
@ -91,7 +91,7 @@ impl Component for DeleteApp {
|
||||||
type Message = Msg;
|
type Message = Msg;
|
||||||
type Properties = ModalProps;
|
type Properties = ModalProps;
|
||||||
|
|
||||||
fn create(ctx: &Context<Self>) -> Self {
|
fn create(_ctx: &Context<Self>) -> Self {
|
||||||
console::log!("delete modal create");
|
console::log!("delete modal create");
|
||||||
|
|
||||||
DeleteApp { state: State::Init }
|
DeleteApp { state: State::Init }
|
||||||
|
|
|
@ -24,7 +24,7 @@ clap = { version = "^3.2", features = ["derive"] }
|
||||||
uuid = { version = "^1.1.2", features = ["serde", "v4" ] }
|
uuid = { version = "^1.1.2", features = ["serde", "v4" ] }
|
||||||
csv = "1.1.6"
|
csv = "1.1.6"
|
||||||
serde = { version = "^1.0.137", features = ["derive"] }
|
serde = { version = "^1.0.137", features = ["derive"] }
|
||||||
serde_json = "^1.0.80"
|
serde_json = "^1.0.81"
|
||||||
|
|
||||||
rand = "^0.8.5"
|
rand = "^0.8.5"
|
||||||
toml = "^0.5.9"
|
toml = "^0.5.9"
|
||||||
|
|
Loading…
Reference in a new issue