bonsaidb_local/cli/
admin.rs

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