1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
use bonsaidb_core::connection::{AsyncStorageConnection, StorageConnection};
use clap::Subcommand;
/// An administrative command-line command.
#[derive(Subcommand, Debug)]
pub enum Command {
/// A command operating on [`User`s](bonsaidb_core::admin::User).
#[clap(subcommand)]
User(UserCommand),
}
/// A command operating on [`User`s](bonsaidb_core::admin::User).
#[derive(Subcommand, Debug)]
pub enum UserCommand {
/// Creates a new user.
Create {
/// The username of the user to create.
username: String,
/// If this flag is provided, the user's initial password will be
/// prompted for over stdin before creating the user.
#[cfg(feature = "password-hashing")]
#[clap(long)]
password: bool,
},
/// Sets an existing user's password. The password will be prompted for over
/// stdin.
#[cfg(feature = "password-hashing")]
SetPassword {
/// The username of the user to change the password of.
username: String,
},
/// Adds a role to a user.
AddRole {
/// The username to add the role to.
username: String,
/// The name of the role to add.
role: String,
},
/// Removes a role from user.
RemoveRole {
/// The username to remove the role from.
username: String,
/// The name of the role to remove.
role: String,
},
/// Adds a role to a user.
AddGroup {
/// The username to add the role to.
username: String,
/// The name of the role to add.
group: String,
},
/// Removes a permission group from user.
RemoveGroup {
/// The username to remove the permission group from.
username: String,
/// The name of the permission group to remove.
group: String,
},
}
impl Command {
/// Executes the command on `storage`.
pub fn execute<SC: StorageConnection>(self, storage: &SC) -> Result<(), crate::Error> {
match self {
Command::User(user) => match user {
UserCommand::Create { username, password } => {
#[cfg(feature = "password-hashing")]
let password = if password {
Some(super::read_password_from_stdin(true)?)
} else {
None
};
let user_id = storage.create_user(&username)?;
#[cfg(feature = "password-hashing")]
if let Some(password) = password {
storage.set_user_password(user_id, password)?;
}
println!("User #{user_id} {username} created");
Ok(())
}
#[cfg(feature = "password-hashing")]
UserCommand::SetPassword { username } => {
let password = super::read_password_from_stdin(true)?;
storage.set_user_password(&username, password)?;
println!("User {username}'s password has been updated.");
Ok(())
}
UserCommand::AddRole { username, role } => {
storage.add_role_to_user(&username, &role)?;
println!("Role {role} added to {username}");
Ok(())
}
UserCommand::RemoveRole { username, role } => {
storage.remove_role_from_user(&username, &role)?;
println!("Role {role} removed from {username}");
Ok(())
}
UserCommand::AddGroup { username, group } => {
storage.add_permission_group_to_user(&username, &group)?;
println!("Group {group} added to {username}");
Ok(())
}
UserCommand::RemoveGroup { username, group } => {
storage.remove_permission_group_from_user(&username, &group)?;
println!("Group {group} removed from {username}");
Ok(())
}
},
}
}
/// Executes the command on `storage`.
pub async fn execute_async<SC: AsyncStorageConnection>(
self,
storage: &SC,
) -> Result<(), crate::Error> {
match self {
Command::User(user) => match user {
UserCommand::Create { username, password } => {
#[cfg(feature = "password-hashing")]
let password = if password {
Some(super::read_password_from_stdin(true)?)
} else {
None
};
let user_id = storage.create_user(&username).await?;
#[cfg(feature = "password-hashing")]
if let Some(password) = password {
storage.set_user_password(user_id, password).await?;
}
println!("User #{user_id} {username} created");
Ok(())
}
#[cfg(feature = "password-hashing")]
UserCommand::SetPassword { username } => {
let password = super::read_password_from_stdin(true)?;
storage.set_user_password(&username, password).await?;
println!("User {username}'s password has been updated.");
Ok(())
}
UserCommand::AddRole { username, role } => {
storage.add_role_to_user(&username, &role).await?;
println!("Role {role} added to {username}");
Ok(())
}
UserCommand::RemoveRole { username, role } => {
storage.remove_role_from_user(&username, &role).await?;
println!("Role {role} removed from {username}");
Ok(())
}
UserCommand::AddGroup { username, group } => {
storage
.add_permission_group_to_user(&username, &group)
.await?;
println!("Group {group} added to {username}");
Ok(())
}
UserCommand::RemoveGroup { username, group } => {
storage
.remove_permission_group_from_user(&username, &group)
.await?;
println!("Group {group} removed from {username}");
Ok(())
}
},
}
}
}