swarmctl: add user list
This commit is contained in:
parent
e0e5823080
commit
0138b0e0ac
2 changed files with 45 additions and 0 deletions
|
|
@ -8,6 +8,7 @@ This document contains the help content for the `swarmctl` command-line program.
|
||||||
* [`swarmctl user`↴](#swarmctl-user)
|
* [`swarmctl user`↴](#swarmctl-user)
|
||||||
* [`swarmctl user add`↴](#swarmctl-user-add)
|
* [`swarmctl user add`↴](#swarmctl-user-add)
|
||||||
* [`swarmctl user update`↴](#swarmctl-user-update)
|
* [`swarmctl user update`↴](#swarmctl-user-update)
|
||||||
|
* [`swarmctl user list`↴](#swarmctl-user-list)
|
||||||
* [`swarmctl completions`↴](#swarmctl-completions)
|
* [`swarmctl completions`↴](#swarmctl-completions)
|
||||||
|
|
||||||
## `swarmctl`
|
## `swarmctl`
|
||||||
|
|
@ -41,6 +42,7 @@ Manage subjects in the swarm's SSO provider
|
||||||
|
|
||||||
* `add` — Add a user, generating a password for them
|
* `add` — Add a user, generating a password for them
|
||||||
* `update` — Change an existing user's attributes
|
* `update` — Change an existing user's attributes
|
||||||
|
* `list` — List every user in the canonical store
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -83,6 +85,16 @@ Every flag is optional and they compose, so one call can set several things at o
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## `swarmctl user list`
|
||||||
|
|
||||||
|
List every user in the canonical store.
|
||||||
|
|
||||||
|
Reads `store` only — never authelia's rendered `users.yml`, which is a derived artifact this crate writes and never reads back (see the crate doc comment). One line per user: username, display name, email (if set), groups (if any).
|
||||||
|
|
||||||
|
**Usage:** `swarmctl user list`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## `swarmctl completions`
|
## `swarmctl completions`
|
||||||
|
|
||||||
Generate a shell completion script for `swarmctl` and print it to stdout.
|
Generate a shell completion script for `swarmctl` and print it to stdout.
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,13 @@ enum UserVerb {
|
||||||
/// editing an attribute, and folded together an attribute edit can
|
/// editing an attribute, and folded together an attribute edit can
|
||||||
/// invalidate a login by accident.
|
/// invalidate a login by accident.
|
||||||
Update(UpdateArgs),
|
Update(UpdateArgs),
|
||||||
|
/// List every user in the canonical store.
|
||||||
|
///
|
||||||
|
/// Reads `store` only — never authelia's rendered `users.yml`, which
|
||||||
|
/// is a derived artifact this crate writes and never reads back (see
|
||||||
|
/// the crate doc comment). One line per user: username, display name,
|
||||||
|
/// email (if set), groups (if any).
|
||||||
|
List,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Args)]
|
#[derive(Args)]
|
||||||
|
|
@ -220,6 +227,9 @@ fn main() -> Result<()> {
|
||||||
Verb::User {
|
Verb::User {
|
||||||
command: UserVerb::Update(args),
|
command: UserVerb::Update(args),
|
||||||
} => user_update(&paths.resolve()?, args),
|
} => user_update(&paths.resolve()?, args),
|
||||||
|
Verb::User {
|
||||||
|
command: UserVerb::List,
|
||||||
|
} => user_list(&paths.resolve()?),
|
||||||
Verb::MarkdownDocs => {
|
Verb::MarkdownDocs => {
|
||||||
print!("{}", clap_markdown::help_markdown::<Cli>());
|
print!("{}", clap_markdown::help_markdown::<Cli>());
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -306,6 +316,29 @@ fn user_update(paths: &Paths, args: UpdateArgs) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `swarmctl user list` — read-only, never touches authelia's users file
|
||||||
|
/// or restarts it. Prints one line per user from the canonical store.
|
||||||
|
fn user_list(paths: &Paths) -> Result<()> {
|
||||||
|
use std::fmt::Write as _;
|
||||||
|
|
||||||
|
let store = load_store(&paths.store, &paths.users_file)?;
|
||||||
|
if store.users.is_empty() {
|
||||||
|
println!("no users in {}", paths.store.display());
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
for (username, user) in &store.users {
|
||||||
|
let mut line = format!("{username}\t{}", user.displayname);
|
||||||
|
if let Some(email) = &user.email {
|
||||||
|
let _ = write!(line, "\t{email}");
|
||||||
|
}
|
||||||
|
if !user.groups.is_empty() {
|
||||||
|
let _ = write!(line, "\tgroups: {}", users::fmt_groups(&user.groups));
|
||||||
|
}
|
||||||
|
println!("{line}");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Write the store + the rendered users file, then restart authelia.
|
/// Write the store + the rendered users file, then restart authelia.
|
||||||
///
|
///
|
||||||
/// Shared by every verb that mutates the store, so the ordering rules
|
/// Shared by every verb that mutates the store, so the ordering rules
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue