From 1bb1c133e85f8c0a4db705c2566df5133d620ace Mon Sep 17 00:00:00 2001 From: h7x4 Date: Wed, 7 Aug 2024 21:54:13 +0200 Subject: [PATCH] Consistently name db connection `connection` --- src/cli/database_command.rs | 40 +++++++++++-------- .../mysql_dbadm.rs | 4 +- src/cli/user_command.rs | 34 +++++++++------- src/core/common.rs | 4 +- src/core/config.rs | 2 +- src/core/database_operations.rs | 16 ++++---- src/core/database_privilege_operations.rs | 16 ++++---- src/core/user_operations.rs | 36 ++++++++++------- 8 files changed, 85 insertions(+), 67 deletions(-) diff --git a/src/cli/database_command.rs b/src/cli/database_command.rs index ac47a74..95ed8c5 100644 --- a/src/cli/database_command.rs +++ b/src/cli/database_command.rs @@ -143,9 +143,9 @@ pub struct DatabaseEditPrivsArgs { pub async fn handle_command( command: DatabaseCommand, - mut conn: MySqlConnection, + mut connection: MySqlConnection, ) -> anyhow::Result<()> { - let result = conn + let result = connection .transaction(|txn| { Box::pin(async move { match command { @@ -159,14 +159,14 @@ pub async fn handle_command( }) .await; - close_database_connection(conn).await; + close_database_connection(connection).await; result } async fn create_databases( args: DatabaseCreateArgs, - conn: &mut MySqlConnection, + connection: &mut MySqlConnection, ) -> anyhow::Result<()> { if args.name.is_empty() { anyhow::bail!("No database names provided"); @@ -174,7 +174,7 @@ async fn create_databases( for name in args.name { // TODO: This can be optimized by fetching all the database privileges in one query. - if let Err(e) = create_database(&name, conn).await { + if let Err(e) = create_database(&name, connection).await { eprintln!("Failed to create database '{}': {}", name, e); eprintln!("Skipping..."); } @@ -183,14 +183,17 @@ async fn create_databases( Ok(()) } -async fn drop_databases(args: DatabaseDropArgs, conn: &mut MySqlConnection) -> anyhow::Result<()> { +async fn drop_databases( + args: DatabaseDropArgs, + connection: &mut MySqlConnection, +) -> anyhow::Result<()> { if args.name.is_empty() { anyhow::bail!("No database names provided"); } for name in args.name { // TODO: This can be optimized by fetching all the database privileges in one query. - if let Err(e) = drop_database(&name, conn).await { + if let Err(e) = drop_database(&name, connection).await { eprintln!("Failed to drop database '{}': {}", name, e); eprintln!("Skipping..."); } @@ -199,8 +202,11 @@ async fn drop_databases(args: DatabaseDropArgs, conn: &mut MySqlConnection) -> a Ok(()) } -async fn list_databases(args: DatabaseListArgs, conn: &mut MySqlConnection) -> anyhow::Result<()> { - let databases = get_database_list(conn).await?; +async fn list_databases( + args: DatabaseListArgs, + connection: &mut MySqlConnection, +) -> anyhow::Result<()> { + let databases = get_database_list(connection).await?; if databases.is_empty() { println!("No databases to show."); @@ -220,15 +226,15 @@ async fn list_databases(args: DatabaseListArgs, conn: &mut MySqlConnection) -> a async fn show_database_privileges( args: DatabaseShowPrivsArgs, - conn: &mut MySqlConnection, + connection: &mut MySqlConnection, ) -> anyhow::Result<()> { let database_users_to_show = if args.name.is_empty() { - get_all_database_privileges(conn).await? + get_all_database_privileges(connection).await? } else { // TODO: This can be optimized by fetching all the database privileges in one query. let mut result = Vec::with_capacity(args.name.len()); for name in args.name { - match get_database_privileges(&name, conn).await { + match get_database_privileges(&name, connection).await { Ok(db) => result.extend(db), Err(e) => { eprintln!("Failed to show database '{}': {}", name, e); @@ -417,12 +423,12 @@ fn format_privileges_line( pub async fn edit_privileges( args: DatabaseEditPrivsArgs, - conn: &mut MySqlConnection, + connection: &mut MySqlConnection, ) -> anyhow::Result<()> { let privilege_data = if let Some(name) = &args.name { - get_database_privileges(name, conn).await? + get_database_privileges(name, connection).await? } else { - get_all_database_privileges(conn).await? + get_all_database_privileges(connection).await? }; let privileges_to_change = if !args.privs.is_empty() { @@ -530,7 +536,7 @@ pub async fn edit_privileges( }; for row in privileges_to_change.iter() { - if !user_exists(&row.user, conn).await? { + if !user_exists(&row.user, connection).await? { // TODO: allow user to return and correct their mistake anyhow::bail!("User {} does not exist", row.user); } @@ -545,7 +551,7 @@ pub async fn edit_privileges( // TODO: Add confirmation prompt. - apply_privilege_diffs(diffs, conn).await?; + apply_privilege_diffs(diffs, connection).await?; Ok(()) } diff --git a/src/cli/mysql_admutils_compatibility/mysql_dbadm.rs b/src/cli/mysql_admutils_compatibility/mysql_dbadm.rs index 11b8361..2c0ba21 100644 --- a/src/cli/mysql_admutils_compatibility/mysql_dbadm.rs +++ b/src/cli/mysql_admutils_compatibility/mysql_dbadm.rs @@ -177,12 +177,12 @@ pub async fn main() -> anyhow::Result<()> { Ok(()) } -async fn show_db(name: &str, conn: &mut MySqlConnection) -> anyhow::Result<()> { +async fn show_db(name: &str, connection: &mut MySqlConnection) -> anyhow::Result<()> { // NOTE: mysql-dbadm show has a quirk where valid database names // for non-existent databases will report with no users. // This function should *not* check for db existence, only // validate the names. - let privileges = database_privilege_operations::get_database_privileges(name, conn) + let privileges = database_privilege_operations::get_database_privileges(name, connection) .await .unwrap_or(vec![]); diff --git a/src/cli/user_command.rs b/src/cli/user_command.rs index 79c57b2..5adfc7c 100644 --- a/src/cli/user_command.rs +++ b/src/cli/user_command.rs @@ -74,8 +74,11 @@ pub struct UserShowArgs { json: bool, } -pub async fn handle_command(command: UserCommand, mut conn: MySqlConnection) -> anyhow::Result<()> { - let result = conn +pub async fn handle_command( + command: UserCommand, + mut connection: MySqlConnection, +) -> anyhow::Result<()> { + let result = connection .transaction(|txn| { Box::pin(async move { match command { @@ -88,18 +91,21 @@ pub async fn handle_command(command: UserCommand, mut conn: MySqlConnection) -> }) .await; - close_database_connection(conn).await; + close_database_connection(connection).await; result } -async fn create_users(args: UserCreateArgs, conn: &mut MySqlConnection) -> anyhow::Result<()> { +async fn create_users( + args: UserCreateArgs, + connection: &mut MySqlConnection, +) -> anyhow::Result<()> { if args.username.is_empty() { anyhow::bail!("No usernames provided"); } for username in args.username { - if let Err(e) = create_database_user(&username, conn).await { + if let Err(e) = create_database_user(&username, connection).await { eprintln!("{}", e); eprintln!("Skipping...\n"); continue; @@ -120,7 +126,7 @@ async fn create_users(args: UserCreateArgs, conn: &mut MySqlConnection) -> anyho username, password_file: None, }, - conn, + connection, ) .await?; } @@ -129,13 +135,13 @@ async fn create_users(args: UserCreateArgs, conn: &mut MySqlConnection) -> anyho Ok(()) } -async fn drop_users(args: UserDeleteArgs, conn: &mut MySqlConnection) -> anyhow::Result<()> { +async fn drop_users(args: UserDeleteArgs, connection: &mut MySqlConnection) -> anyhow::Result<()> { if args.username.is_empty() { anyhow::bail!("No usernames provided"); } for username in args.username { - if let Err(e) = delete_database_user(&username, conn).await { + if let Err(e) = delete_database_user(&username, connection).await { eprintln!("{}", e); eprintln!("Skipping..."); } @@ -156,7 +162,7 @@ pub fn read_password_from_stdin_with_double_check(username: &str) -> anyhow::Res async fn change_password_for_user( args: UserPasswdArgs, - conn: &mut MySqlConnection, + connection: &mut MySqlConnection, ) -> anyhow::Result<()> { // NOTE: although this also is checked in `set_password_for_database_user`, we check it here // to provide a more natural order of error messages. @@ -172,16 +178,16 @@ async fn change_password_for_user( read_password_from_stdin_with_double_check(&args.username)? }; - set_password_for_database_user(&args.username, &password, conn).await?; + set_password_for_database_user(&args.username, &password, connection).await?; Ok(()) } -async fn show_users(args: UserShowArgs, conn: &mut MySqlConnection) -> anyhow::Result<()> { +async fn show_users(args: UserShowArgs, connection: &mut MySqlConnection) -> anyhow::Result<()> { let unix_user = get_current_unix_user()?; let users = if args.username.is_empty() { - get_all_database_users_for_unix_user(&unix_user, conn).await? + get_all_database_users_for_unix_user(&unix_user, connection).await? } else { let mut result = vec![]; for username in args.username { @@ -191,7 +197,7 @@ async fn show_users(args: UserShowArgs, conn: &mut MySqlConnection) -> anyhow::R continue; } - let user = get_database_user_for_user(&username, conn).await?; + let user = get_database_user_for_user(&username, connection).await?; if let Some(user) = user { result.push(user); } else { @@ -205,7 +211,7 @@ async fn show_users(args: UserShowArgs, conn: &mut MySqlConnection) -> anyhow::R for user in users.iter() { user_databases.insert( user.user.clone(), - get_databases_where_user_has_privileges(&user.user, conn).await?, + get_databases_where_user_has_privileges(&user.user, connection).await?, ); } diff --git a/src/core/common.rs b/src/core/common.rs index bc4c8a8..2616f0c 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -141,8 +141,8 @@ pub fn validate_ownership_by_user_prefix<'a>( Ok(prefix) } -pub async fn close_database_connection(conn: MySqlConnection) { - if let Err(e) = conn +pub async fn close_database_connection(connection: MySqlConnection) { + if let Err(e) = connection .close() .await .context("Failed to close connection properly") diff --git a/src/core/config.rs b/src/core/config.rs index 53a36bf..54cbaf8 100644 --- a/src/core/config.rs +++ b/src/core/config.rs @@ -107,7 +107,7 @@ pub async fn mysql_connection_from_config(config: Config) -> anyhow::Result conn.context("Failed to connect to MySQL"), + Ok(connection) => connection.context("Failed to connect to MySQL"), Err(_) => Err(anyhow!("Timed out after 2 seconds")).context("Failed to connect to MySQL"), } } diff --git a/src/core/database_operations.rs b/src/core/database_operations.rs index f44a5f2..63687ad 100644 --- a/src/core/database_operations.rs +++ b/src/core/database_operations.rs @@ -13,13 +13,13 @@ use crate::core::{ database_privilege_operations::DATABASE_PRIVILEGE_FIELDS, }; -pub async fn create_database(name: &str, conn: &mut MySqlConnection) -> anyhow::Result<()> { +pub async fn create_database(name: &str, connection: &mut MySqlConnection) -> anyhow::Result<()> { let user = get_current_unix_user()?; validate_database_name(name, &user)?; // NOTE: see the note about SQL injections in `validate_owner_of_database_name` sqlx::query(&format!("CREATE DATABASE {}", quote_identifier(name))) - .execute(conn) + .execute(connection) .await .map_err(|e| { if e.to_string().contains("database exists") { @@ -32,13 +32,13 @@ pub async fn create_database(name: &str, conn: &mut MySqlConnection) -> anyhow:: Ok(()) } -pub async fn drop_database(name: &str, conn: &mut MySqlConnection) -> anyhow::Result<()> { +pub async fn drop_database(name: &str, connection: &mut MySqlConnection) -> anyhow::Result<()> { let user = get_current_unix_user()?; validate_database_name(name, &user)?; // NOTE: see the note about SQL injections in `validate_owner_of_database_name` sqlx::query(&format!("DROP DATABASE {}", quote_identifier(name))) - .execute(conn) + .execute(connection) .await .map_err(|e| { if e.to_string().contains("doesn't exist") { @@ -56,7 +56,7 @@ struct DatabaseName { database: String, } -pub async fn get_database_list(conn: &mut MySqlConnection) -> anyhow::Result> { +pub async fn get_database_list(connection: &mut MySqlConnection) -> anyhow::Result> { let unix_user = get_current_unix_user()?; let databases = sqlx::query_as::<_, DatabaseName>( @@ -68,7 +68,7 @@ pub async fn get_database_list(conn: &mut MySqlConnection) -> anyhow::Result anyhow::Result anyhow::Result> { let result = sqlx::query( formatdoc!( @@ -98,7 +98,7 @@ pub async fn get_databases_where_user_has_privileges( .as_str(), ) .bind(username) - .fetch_all(conn) + .fetch_all(connection) .await? .into_iter() .map(|databases| databases.try_get::("database").unwrap()) diff --git a/src/core/database_privilege_operations.rs b/src/core/database_privilege_operations.rs index ce6f222..bc4bff4 100644 --- a/src/core/database_privilege_operations.rs +++ b/src/core/database_privilege_operations.rs @@ -145,7 +145,7 @@ impl FromRow<'_, MySqlRow> for DatabasePrivilegeRow { pub async fn get_database_privileges( database_name: &str, - conn: &mut MySqlConnection, + connection: &mut MySqlConnection, ) -> anyhow::Result> { let unix_user = get_current_unix_user()?; validate_database_name(database_name, &unix_user)?; @@ -158,7 +158,7 @@ pub async fn get_database_privileges( .join(","), )) .bind(database_name) - .fetch_all(conn) + .fetch_all(connection) .await .context("Failed to show database")?; @@ -166,7 +166,7 @@ pub async fn get_database_privileges( } pub async fn get_all_database_privileges( - conn: &mut MySqlConnection, + connection: &mut MySqlConnection, ) -> anyhow::Result> { let unix_user = get_current_unix_user()?; @@ -184,7 +184,7 @@ pub async fn get_all_database_privileges( .join(","), )) .bind(create_user_group_matching_regex(&unix_user)) - .fetch_all(conn) + .fetch_all(connection) .await .context("Failed to show databases")?; @@ -270,7 +270,7 @@ pub async fn diff_privileges( pub async fn apply_privilege_diffs( diffs: Vec, - conn: &mut MySqlConnection, + connection: &mut MySqlConnection, ) -> anyhow::Result<()> { for diff in diffs { match diff { @@ -300,7 +300,7 @@ pub async fn apply_privilege_diffs( .bind(yn(p.create_tmp_table_priv)) .bind(yn(p.lock_tables_priv)) .bind(yn(p.references_priv)) - .execute(&mut *conn) + .execute(&mut *connection) .await?; } DatabasePrivilegesDiff::Modified(p) => { @@ -318,14 +318,14 @@ pub async fn apply_privilege_diffs( ) .bind(p.db) .bind(p.user) - .execute(&mut *conn) + .execute(&mut *connection) .await?; } DatabasePrivilegesDiff::Deleted(p) => { sqlx::query("DELETE FROM `db` WHERE `db` = ? AND `user` = ?") .bind(p.db) .bind(p.user) - .execute(&mut *conn) + .execute(&mut *connection) .await?; } } diff --git a/src/core/user_operations.rs b/src/core/user_operations.rs index e6daa50..1916982 100644 --- a/src/core/user_operations.rs +++ b/src/core/user_operations.rs @@ -10,7 +10,7 @@ use super::common::{ validate_ownership_by_user_prefix, }; -pub async fn user_exists(db_user: &str, conn: &mut MySqlConnection) -> anyhow::Result { +pub async fn user_exists(db_user: &str, connection: &mut MySqlConnection) -> anyhow::Result { let unix_user = get_current_unix_user()?; validate_user_name(db_user, &unix_user)?; @@ -25,42 +25,48 @@ pub async fn user_exists(db_user: &str, conn: &mut MySqlConnection) -> anyhow::R "#, ) .bind(db_user) - .fetch_one(conn) + .fetch_one(connection) .await? .get::(0); Ok(user_exists) } -pub async fn create_database_user(db_user: &str, conn: &mut MySqlConnection) -> anyhow::Result<()> { +pub async fn create_database_user( + db_user: &str, + connection: &mut MySqlConnection, +) -> anyhow::Result<()> { let unix_user = get_current_unix_user()?; validate_user_name(db_user, &unix_user)?; - if user_exists(db_user, conn).await? { + if user_exists(db_user, connection).await? { anyhow::bail!("User '{}' already exists", db_user); } // NOTE: see the note about SQL injections in `validate_ownership_of_user_name` sqlx::query(format!("CREATE USER {}@'%'", quote_literal(db_user),).as_str()) - .execute(conn) + .execute(connection) .await?; Ok(()) } -pub async fn delete_database_user(db_user: &str, conn: &mut MySqlConnection) -> anyhow::Result<()> { +pub async fn delete_database_user( + db_user: &str, + connection: &mut MySqlConnection, +) -> anyhow::Result<()> { let unix_user = get_current_unix_user()?; validate_user_name(db_user, &unix_user)?; - if !user_exists(db_user, conn).await? { + if !user_exists(db_user, connection).await? { anyhow::bail!("User '{}' does not exist", db_user); } // NOTE: see the note about SQL injections in `validate_ownership_of_user_name` sqlx::query(format!("DROP USER {}@'%'", quote_literal(db_user),).as_str()) - .execute(conn) + .execute(connection) .await?; Ok(()) @@ -69,12 +75,12 @@ pub async fn delete_database_user(db_user: &str, conn: &mut MySqlConnection) -> pub async fn set_password_for_database_user( db_user: &str, password: &str, - conn: &mut MySqlConnection, + connection: &mut MySqlConnection, ) -> anyhow::Result<()> { let unix_user = crate::core::common::get_current_unix_user()?; validate_user_name(db_user, &unix_user)?; - if !user_exists(db_user, conn).await? { + if !user_exists(db_user, connection).await? { anyhow::bail!("User '{}' does not exist", db_user); } @@ -87,7 +93,7 @@ pub async fn set_password_for_database_user( ) .as_str(), ) - .execute(conn) + .execute(connection) .await?; Ok(()) @@ -113,7 +119,7 @@ pub struct DatabaseUser { /// unix username and group names of the given unix user. pub async fn get_all_database_users_for_unix_user( unix_user: &User, - conn: &mut MySqlConnection, + connection: &mut MySqlConnection, ) -> anyhow::Result> { let users = sqlx::query_as::<_, DatabaseUser>( r#" @@ -126,7 +132,7 @@ pub async fn get_all_database_users_for_unix_user( "#, ) .bind(create_user_group_matching_regex(unix_user)) - .fetch_all(conn) + .fetch_all(connection) .await?; Ok(users) @@ -135,7 +141,7 @@ pub async fn get_all_database_users_for_unix_user( /// This function fetches a database user if it exists. pub async fn get_database_user_for_user( username: &str, - conn: &mut MySqlConnection, + connection: &mut MySqlConnection, ) -> anyhow::Result> { let user = sqlx::query_as::<_, DatabaseUser>( r#" @@ -148,7 +154,7 @@ pub async fn get_database_user_for_user( "#, ) .bind(username) - .fetch_optional(conn) + .fetch_optional(connection) .await?; Ok(user)