Don't fail on erroneus db connection closure

This commit is contained in:
Oystein Kristoffer Tveit 2024-08-07 16:16:46 +02:00
parent 460a8d6abb
commit 01d502337d
Signed by: oysteikt
GPG Key ID: 9F2F7D8250F35146
4 changed files with 25 additions and 15 deletions

View File

@ -3,11 +3,11 @@ use clap::Parser;
use indoc::indoc; use indoc::indoc;
use itertools::Itertools; use itertools::Itertools;
use prettytable::{Cell, Row, Table}; use prettytable::{Cell, Row, Table};
use sqlx::{Connection, MySqlConnection}; use sqlx::MySqlConnection;
use crate::core::{ use crate::core::{
self, self,
common::get_current_unix_user, common::{close_database_connection, get_current_unix_user},
database_operations::{ database_operations::{
apply_permission_diffs, db_priv_field_human_readable_name, diff_permissions, yn, apply_permission_diffs, db_priv_field_human_readable_name, diff_permissions, yn,
DatabasePrivileges, DATABASE_PRIVILEGE_FIELDS, DatabasePrivileges, DATABASE_PRIVILEGE_FIELDS,
@ -155,7 +155,7 @@ pub async fn handle_command(
DatabaseCommand::EditDbPerm(args) => edit_permissions(args, &mut conn).await, DatabaseCommand::EditDbPerm(args) => edit_permissions(args, &mut conn).await,
}; };
conn.close().await?; close_database_connection(conn).await;
result result
} }

View File

@ -7,7 +7,7 @@ use crate::{
user_command, user_command,
}, },
core::{ core::{
common::get_current_unix_user, common::{close_database_connection, get_current_unix_user},
config::{get_config, mysql_connection_from_config, GlobalConfigArgs}, config::{get_config, mysql_connection_from_config, GlobalConfigArgs},
user_operations::{ user_operations::{
create_database_user, delete_database_user, get_all_database_users_for_unix_user, create_database_user, delete_database_user, get_all_database_users_for_unix_user,
@ -107,14 +107,16 @@ pub async fn main() -> anyhow::Result<()> {
delete_database_user(&name, &mut connection).await?; delete_database_user(&name, &mut connection).await?;
} }
} }
Command::Passwd(args) => passwd(args, connection).await?, Command::Passwd(args) => passwd(args, &mut connection).await?,
Command::Show(args) => show(args, connection).await?, Command::Show(args) => show(args, &mut connection).await?,
} }
close_database_connection(connection).await;
Ok(()) Ok(())
} }
async fn passwd(args: PasswdArgs, mut connection: MySqlConnection) -> anyhow::Result<()> { async fn passwd(args: PasswdArgs, connection: &mut MySqlConnection) -> anyhow::Result<()> {
let filtered_names = filter_db_or_user_names(args.name, DbOrUser::User)?; let filtered_names = filter_db_or_user_names(args.name, DbOrUser::User)?;
// NOTE: this gets doubly checked during the call to `set_password_for_database_user`. // NOTE: this gets doubly checked during the call to `set_password_for_database_user`.
@ -123,7 +125,7 @@ async fn passwd(args: PasswdArgs, mut connection: MySqlConnection) -> anyhow::Re
// have entered the password twice. // have entered the password twice.
let mut better_filtered_names = Vec::with_capacity(filtered_names.len()); let mut better_filtered_names = Vec::with_capacity(filtered_names.len());
for name in filtered_names.into_iter() { for name in filtered_names.into_iter() {
if !user_exists(&name, &mut connection).await? { if !user_exists(&name, connection).await? {
println!( println!(
"{}: User '{}' does not exist. You must create it first.", "{}: User '{}' does not exist. You must create it first.",
std::env::args() std::env::args()
@ -138,17 +140,17 @@ async fn passwd(args: PasswdArgs, mut connection: MySqlConnection) -> anyhow::Re
for name in better_filtered_names { for name in better_filtered_names {
let password = user_command::read_password_from_stdin_with_double_check(&name)?; let password = user_command::read_password_from_stdin_with_double_check(&name)?;
set_password_for_database_user(&name, &password, &mut connection).await?; set_password_for_database_user(&name, &password, connection).await?;
println!("Password updated for user '{}'.", name); println!("Password updated for user '{}'.", name);
} }
Ok(()) Ok(())
} }
async fn show(args: ShowArgs, mut connection: MySqlConnection) -> anyhow::Result<()> { async fn show(args: ShowArgs, connection: &mut MySqlConnection) -> anyhow::Result<()> {
let users = if args.name.is_empty() { let users = if args.name.is_empty() {
let unix_user = get_current_unix_user()?; let unix_user = get_current_unix_user()?;
get_all_database_users_for_unix_user(&unix_user, &mut connection) get_all_database_users_for_unix_user(&unix_user, connection)
.await? .await?
.into_iter() .into_iter()
.map(|u| u.user) .map(|u| u.user)
@ -158,7 +160,7 @@ async fn show(args: ShowArgs, mut connection: MySqlConnection) -> anyhow::Result
}; };
for user in users { for user in users {
let password_is_set = password_is_set_for_database_user(&user, &mut connection).await?; let password_is_set = password_is_set_for_database_user(&user, connection).await?;
match password_is_set { match password_is_set {
Some(true) => println!("User '{}': password set.", user), Some(true) => println!("User '{}': password set.", user),

View File

@ -2,9 +2,9 @@ use std::vec;
use anyhow::Context; use anyhow::Context;
use clap::Parser; use clap::Parser;
use sqlx::{Connection, MySqlConnection}; use sqlx::MySqlConnection;
use crate::core::user_operations::validate_user_name; use crate::core::{common::close_database_connection, user_operations::validate_user_name};
#[derive(Parser)] #[derive(Parser)]
pub struct UserArgs { pub struct UserArgs {
@ -67,7 +67,7 @@ pub async fn handle_command(command: UserCommand, mut conn: MySqlConnection) ->
UserCommand::ShowUser(args) => show_users(args, &mut conn).await, UserCommand::ShowUser(args) => show_users(args, &mut conn).await,
}; };
conn.close().await?; close_database_connection(conn).await;
result result
} }

View File

@ -2,6 +2,7 @@ use anyhow::Context;
use indoc::indoc; use indoc::indoc;
use itertools::Itertools; use itertools::Itertools;
use nix::unistd::{getuid, Group, User}; use nix::unistd::{getuid, Group, User};
use sqlx::{Connection, MySqlConnection};
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
use std::ffi::CString; use std::ffi::CString;
@ -140,6 +141,13 @@ pub fn validate_ownership_by_user_prefix<'a>(
Ok(prefix) Ok(prefix)
} }
pub async fn close_database_connection(conn: MySqlConnection) {
if let Err(e) = conn.close().await.context("Failed to close connection properly") {
eprintln!("{}", e);
eprintln!("Ignoring...");
}
}
pub fn quote_literal(s: &str) -> String { pub fn quote_literal(s: &str) -> String {
format!("'{}'", s.replace('\'', r"\'")) format!("'{}'", s.replace('\'', r"\'"))
} }