use crate::command_runner::CommandRunner; use crate::symbols::Symbol; use async_trait::async_trait; use std::error::Error; #[derive(Debug)] pub struct User<'a, U, C> { user_name: U, command_runner: &'a C, } impl<'a, U: AsRef, C: CommandRunner> User<'a, U, C> { pub fn new(user_name: U, command_runner: &'a C) -> Self { Self { user_name, command_runner, } } async fn run_sql(&self, sql: &str) -> Result> { let b = self .command_runner .get_output("mariadb", args!["--skip-column-names", "-B", "-e", sql]) .await?; Ok(String::from_utf8(b)?) } } #[async_trait(?Send)] impl, C: CommandRunner> Symbol for User<'_, U, C> { async fn target_reached(&self) -> Result> { Ok( self .run_sql(&format!( "SELECT User FROM mysql.user WHERE User = '{}' AND plugin = 'unix_socket'", self.user_name.as_ref() )) .await? .trim_end() == self.user_name.as_ref(), ) } async fn execute(&self) -> Result<(), Box> { self .run_sql(&format!( "GRANT ALL ON {0}.* TO {0} IDENTIFIED VIA unix_socket", self.user_name.as_ref() )) .await?; Ok(()) } } #[cfg(test)] mod test {}