diff --git a/src/Console/CreateUserCommand.php b/src/Console/CreateUserCommand.php new file mode 100644 index 0000000..07fc68b --- /dev/null +++ b/src/Console/CreateUserCommand.php @@ -0,0 +1,53 @@ +addArgument('name', InputArgument::OPTIONAL, 'User name'); + $this->addArgument('password', InputArgument::OPTIONAL, 'User password'); + $this->addArgument('host', InputArgument::OPTIONAL, 'User host'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $question = $this->getHelper('question'); + + $name = $input->getArgument('name'); + $password = $input->getArgument('password'); + $host = $input->getArgument('host'); + + if (!$name) { + $name = $question->ask($input, $output, new Question('User name: ')); + } + if (!$password) { + $passwordQuestion = new Question('User password: '); + $passwordQuestion->setHidden(true); + $password = $question->ask($input, $output, $passwordQuestion); + } + + $this->db->createUser($name, $password, $host); + + $output->writeln(sprintf('User "%s" successfully created', $name)); + + return Command::SUCCESS; + } +} \ No newline at end of file diff --git a/src/Console/DeleteUserCommand.php b/src/Console/DeleteUserCommand.php new file mode 100644 index 0000000..68db6d0 --- /dev/null +++ b/src/Console/DeleteUserCommand.php @@ -0,0 +1,49 @@ +addArgument('name', InputArgument::OPTIONAL, 'User name'); + $this->addArgument('host', InputArgument::OPTIONAL, 'User host'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $question = $this->getHelper('question'); + $host = $input->getArgument('host'); + + if (!$name = $input->getArgument('name')) { + $selectQuestion = new ChoiceQuestion('User name: ', array_map( + fn($user) => $user['name'], + $this->db->listUsers()) + ); + $name = $question->ask($input, $output, $selectQuestion); + } + + $this->db->deleteUser($name, $host); + + $output->writeln(sprintf('User "%s" successfully deleted', $name)); + + return Command::SUCCESS; + } +} \ No newline at end of file diff --git a/src/Service/BackupService.php b/src/Service/BackupService.php index 19d4d70..619f14e 100644 --- a/src/Service/BackupService.php +++ b/src/Service/BackupService.php @@ -10,9 +10,7 @@ class BackupService { public function __construct( private readonly DatabaseCredentials $credentials - ) - { - } + ) {} public function backup(string $db, ?string $fileName = null): string { diff --git a/src/Service/DatabaseService.php b/src/Service/DatabaseService.php index 0948d9e..5345a68 100644 --- a/src/Service/DatabaseService.php +++ b/src/Service/DatabaseService.php @@ -40,6 +40,20 @@ class DatabaseService } } + public function deleteDatabase(string $name): void + { + $result = $this->conn->query(sprintf('DROP DATABASE `%s`', $name)); + if (!$result) { + throw new Exception(sprintf('Database delete error: %s', $this->conn->error)); + } + } + + public function purgeDatabase(string $name): void + { + $this->deleteDatabase($name); + $this->createDatabase($name); + } + public function listUsers(): array { $results = $this->conn->query('select * from mysql.user'); @@ -56,17 +70,44 @@ class DatabaseService return $users; } - public function deleteDatabase(string $name): void + public function createUser( + string $name, + string $password, + ?string $host = null, + ): void { - $result = $this->conn->query(sprintf('DROP DATABASE `%s`', $name)); + $host ??= 'localhost'; + + $users = $this->listUsers(); + foreach ($users as $user) { + if ($user['name'] === $name) { + throw new Exception(sprintf('User "%s" already exists', $name)); + } + } + $result = $this->conn->query(sprintf("CREATE USER '%s'@'%s' IDENTIFIED BY '%s'", $name, $host, $password)); if (!$result) { - throw new Exception(sprintf('Database delete error: %s', $this->conn->error)); + throw new Exception(sprintf('User create error: %s', $this->conn->error)); } } - public function purgeDatabase(string $name): void + public function deleteUser(string $name, ?string $host = null): void { - $this->deleteDatabase($name); - $this->createDatabase($name); + $host ??= 'localhost'; + $users = $this->listUsers(); + $found = false; + foreach ($users as $user) { + if ($user['name'] === $name) { + $found = true; + break; + } + } + if (!$found) { + throw new Exception(sprintf('User "%s" not found', $name)); + } + + $result = $this->conn->query(sprintf("DROP USER '%s'@'%s'", $name, $host)); + if (!$result) { + throw new Exception(sprintf('User delete error: %s', $this->conn->error)); + } } } \ No newline at end of file