mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 22:52:22 +00:00
cli: Add basic functionality to assign membership
This commit is contained in:
72
src/commands/membership.rs
Normal file
72
src/commands/membership.rs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
use clap::{Parser, Subcommand};
|
||||||
|
use rustical_store::auth::AuthenticationProvider;
|
||||||
|
|
||||||
|
#[derive(Debug, Parser)]
|
||||||
|
pub struct AssignArgs {
|
||||||
|
id: String,
|
||||||
|
#[arg(long, help = "The principal to assign a membership to (e.g. a group)")]
|
||||||
|
to: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Parser)]
|
||||||
|
pub struct RemoveArgs {
|
||||||
|
id: String,
|
||||||
|
#[arg(long, help = "The membership to remove")]
|
||||||
|
to: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Parser)]
|
||||||
|
pub struct ListArgs {
|
||||||
|
id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Subcommand)]
|
||||||
|
pub enum MembershipCommand {
|
||||||
|
Assign(AssignArgs),
|
||||||
|
Remove(RemoveArgs),
|
||||||
|
List(ListArgs),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
pub struct MembershipArgs {
|
||||||
|
#[command(subcommand)]
|
||||||
|
command: MembershipCommand,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn handle_membership_command(
|
||||||
|
user_store: impl AuthenticationProvider,
|
||||||
|
MembershipArgs { command }: MembershipArgs,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let id = match &command {
|
||||||
|
MembershipCommand::Assign(AssignArgs { id, .. }) => id,
|
||||||
|
MembershipCommand::Remove(RemoveArgs { id, .. }) => id,
|
||||||
|
MembershipCommand::List(ListArgs { id }) => id,
|
||||||
|
};
|
||||||
|
let mut principal = user_store
|
||||||
|
.get_principal(id)
|
||||||
|
.await?
|
||||||
|
.unwrap_or_else(|| panic!("Principal {id} does not exist"));
|
||||||
|
|
||||||
|
match command {
|
||||||
|
MembershipCommand::Assign(AssignArgs { to, .. }) => {
|
||||||
|
if principal.memberships.contains(&to) {
|
||||||
|
println!("Principal is already member of {to}");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
principal.memberships.push(to);
|
||||||
|
user_store.insert_principal(principal, true).await?;
|
||||||
|
println!("Membership assigned");
|
||||||
|
}
|
||||||
|
MembershipCommand::Remove(RemoveArgs { to, .. }) => {
|
||||||
|
principal.memberships.retain(|principal| principal != &to);
|
||||||
|
user_store.insert_principal(principal, true).await?;
|
||||||
|
println!("Membership removed");
|
||||||
|
}
|
||||||
|
MembershipCommand::List(ListArgs { .. }) => {
|
||||||
|
for membership in principal.memberships {
|
||||||
|
println!("{membership}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ use crate::config::{
|
|||||||
TracingConfig,
|
TracingConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mod membership;
|
||||||
pub mod principals;
|
pub mod principals;
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use super::membership::{MembershipArgs, handle_membership_command};
|
||||||
|
use crate::config::{self, Config};
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use figment::{
|
use figment::{
|
||||||
Figment,
|
Figment,
|
||||||
@@ -8,8 +10,6 @@ use password_hash::SaltString;
|
|||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
use rustical_store::auth::{AuthenticationProvider, TomlPrincipalStore, User, user::PrincipalType};
|
use rustical_store::auth::{AuthenticationProvider, TomlPrincipalStore, User, user::PrincipalType};
|
||||||
|
|
||||||
use crate::config::{self, Config};
|
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
pub struct PrincipalsArgs {
|
pub struct PrincipalsArgs {
|
||||||
#[arg(short, long, env, default_value = "/etc/rustical/config.toml")]
|
#[arg(short, long, env, default_value = "/etc/rustical/config.toml")]
|
||||||
@@ -57,6 +57,7 @@ enum Command {
|
|||||||
Create(CreateArgs),
|
Create(CreateArgs),
|
||||||
Remove(RemoveArgs),
|
Remove(RemoveArgs),
|
||||||
Edit(EditArgs),
|
Edit(EditArgs),
|
||||||
|
Membership(MembershipArgs),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn cmd_principals(args: PrincipalsArgs) -> anyhow::Result<()> {
|
pub async fn cmd_principals(args: PrincipalsArgs) -> anyhow::Result<()> {
|
||||||
@@ -155,6 +156,7 @@ pub async fn cmd_principals(args: PrincipalsArgs) -> anyhow::Result<()> {
|
|||||||
user_store.insert_principal(principal, true).await?;
|
user_store.insert_principal(principal, true).await?;
|
||||||
println!("Principal {id} updated");
|
println!("Principal {id} updated");
|
||||||
}
|
}
|
||||||
|
Command::Membership(args) => handle_membership_command(user_store, args).await?,
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user