Misc #35
|
@ -11,7 +11,7 @@ use crate::{
|
|||
config::{get_config, mysql_connection_from_config, GlobalConfigArgs},
|
||||
user_operations::{
|
||||
create_database_user, delete_database_user, get_all_database_users_for_unix_user,
|
||||
password_is_set_for_database_user, set_password_for_database_user, user_exists,
|
||||
get_database_user_for_user, set_password_for_database_user, user_exists,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -150,22 +150,24 @@ async fn passwd(args: PasswdArgs, connection: &mut MySqlConnection) -> anyhow::R
|
|||
async fn show(args: ShowArgs, connection: &mut MySqlConnection) -> anyhow::Result<()> {
|
||||
let users = if args.name.is_empty() {
|
||||
let unix_user = get_current_unix_user()?;
|
||||
get_all_database_users_for_unix_user(&unix_user, connection)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|u| u.user)
|
||||
.collect()
|
||||
get_all_database_users_for_unix_user(&unix_user, connection).await?
|
||||
} else {
|
||||
filter_db_or_user_names(args.name, DbOrUser::User)?
|
||||
let filtered_usernames = filter_db_or_user_names(args.name, DbOrUser::User)?;
|
||||
let mut result = Vec::with_capacity(filtered_usernames.len());
|
||||
for username in filtered_usernames.iter() {
|
||||
// TODO: fetch all users in one query
|
||||
get_database_user_for_user(username, connection)
|
||||
.await?
|
||||
.map(|user| result.push(user));
|
||||
}
|
||||
result
|
||||
};
|
||||
|
||||
for user in users {
|
||||
let password_is_set = password_is_set_for_database_user(&user, connection).await?;
|
||||
|
||||
match password_is_set {
|
||||
Some(true) => println!("User '{}': password set.", user),
|
||||
Some(false) => println!("User '{}': no password set.", user),
|
||||
None => {}
|
||||
if user.has_password {
|
||||
println!("User '{}': password set.", user.user);
|
||||
} else {
|
||||
println!("User '{}': no password set.", user.user);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -197,7 +197,7 @@ async fn show_users(args: UserShowArgs, conn: &mut MySqlConnection) -> anyhow::R
|
|||
println!(
|
||||
"User '{}': {}",
|
||||
&user.user,
|
||||
if !(user.authentication_string.is_empty() && user.password.is_empty()) {
|
||||
if user.has_password {
|
||||
"password set."
|
||||
} else {
|
||||
"no password set."
|
||||
|
|
|
@ -93,30 +93,6 @@ pub async fn set_password_for_database_user(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Helper struct to deserialize the query made in `password_is_set_for_database_user`.
|
||||
#[derive(sqlx::FromRow)]
|
||||
#[sqlx(transparent)]
|
||||
struct PasswordIsSet(bool);
|
||||
|
||||
/// This function checks if a database user has a password set.
|
||||
/// It returns `Ok(None)` if the user does not exist.
|
||||
pub async fn password_is_set_for_database_user(
|
||||
db_user: &str,
|
||||
conn: &mut MySqlConnection,
|
||||
) -> anyhow::Result<Option<bool>> {
|
||||
let unix_user = crate::core::common::get_current_unix_user()?;
|
||||
validate_user_name(db_user, &unix_user)?;
|
||||
|
||||
let user_has_password = sqlx::query_as::<_, PasswordIsSet>(
|
||||
"SELECT authentication_string != '' FROM mysql.user WHERE User = ?",
|
||||
)
|
||||
.bind(db_user)
|
||||
.fetch_optional(conn)
|
||||
.await?;
|
||||
|
||||
Ok(user_has_password.map(|PasswordIsSet(is_set)| is_set))
|
||||
}
|
||||
|
||||
/// This struct contains information about a database user.
|
||||
/// This can be extended if we need more information in the future.
|
||||
#[derive(Debug, Clone, FromRow, Serialize, Deserialize)]
|
||||
|
@ -127,10 +103,8 @@ pub struct DatabaseUser {
|
|||
#[sqlx(rename = "Host")]
|
||||
pub host: String,
|
||||
|
||||
#[sqlx(rename = "Password")]
|
||||
pub password: String,
|
||||
|
||||
pub authentication_string: String,
|
||||
#[sqlx(rename = "`Password` != '' OR `authentication_string` != ''")]
|
||||
pub has_password: bool,
|
||||
}
|
||||
|
||||
/// This function fetches all database users that have a prefix matching the
|
||||
|
@ -141,7 +115,10 @@ pub async fn get_all_database_users_for_unix_user(
|
|||
) -> anyhow::Result<Vec<DatabaseUser>> {
|
||||
let users = sqlx::query_as::<_, DatabaseUser>(
|
||||
r#"
|
||||
SELECT `User`, `Host`, `Password`, `authentication_string`
|
||||
SELECT
|
||||
`User`,
|
||||
`Host`,
|
||||
`Password` != '' OR `authentication_string` != ''
|
||||
FROM `mysql`.`user`
|
||||
WHERE `User` REGEXP ?
|
||||
"#,
|
||||
|
@ -160,7 +137,10 @@ pub async fn get_database_user_for_user(
|
|||
) -> anyhow::Result<Option<DatabaseUser>> {
|
||||
let user = sqlx::query_as::<_, DatabaseUser>(
|
||||
r#"
|
||||
SELECT `User`, `Host`, `Password`, `authentication_string`
|
||||
SELECT
|
||||
`User`,
|
||||
`Host`,
|
||||
`Password` != '' OR `authentication_string` != ''
|
||||
FROM `mysql`.`user`
|
||||
WHERE `User` = ?
|
||||
"#,
|
||||
|
|
Loading…
Reference in New Issue