Compare commits
	
		
			3 Commits
		
	
	
		
			dpkg-packa
			...
			publish-de
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| fc27159c46 | |||
| c2d22ee7f8 | |||
| 8ba946976d | 
							
								
								
									
										32
									
								
								.gitea/workflows/publish-deb.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								.gitea/workflows/publish-deb.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | name: "publish-deb" | ||||||
|  | on: | ||||||
|  |   workflow_dispatch: | ||||||
|  |     inputs: | ||||||
|  |       version: | ||||||
|  |         description: "Version to publish" | ||||||
|  |         required: true | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v3 | ||||||
|  |  | ||||||
|  |       - name: Install rust toolchain | ||||||
|  |         uses: actions-rs/toolchain@v1 | ||||||
|  |         with: | ||||||
|  |             toolchain: stable | ||||||
|  |             override: true | ||||||
|  |  | ||||||
|  |       - name: Install cargo-deb | ||||||
|  |         run: cargo install cargo-deb | ||||||
|  |  | ||||||
|  |       - name: Build deb package | ||||||
|  |         run: ./create-deb.sh | ||||||
|  |  | ||||||
|  |       - name: Publish deb package | ||||||
|  |         run: | | ||||||
|  |           curl \ | ||||||
|  |             --user your_username:your_password_or_token \ | ||||||
|  |             --upload-file target/debian/*.deb \ | ||||||
|  |             https://git.pvv.ntnu.no/api/packages/testuser/debian/pool/bionic/main/upload | ||||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -6,6 +6,3 @@ config.toml | |||||||
| /.direnv/ | /.direnv/ | ||||||
| result | result | ||||||
| result-* | result-* | ||||||
|  |  | ||||||
| # Packaging |  | ||||||
| /assets/completions/ |  | ||||||
							
								
								
									
										657
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										657
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										60
									
								
								Cargo.toml
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								Cargo.toml
									
									
									
									
									
								
							| @@ -2,36 +2,26 @@ | |||||||
| name = "mysqladm-rs" | name = "mysqladm-rs" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| edition = "2021" | edition = "2021" | ||||||
| license = "BSD3" |  | ||||||
| authors = [ |  | ||||||
|   "oysteikt@pvv.ntnu.no", |  | ||||||
|   "felixalb@pvv.ntnu.no", |  | ||||||
| ] |  | ||||||
| repository = "https://git.pvv.ntnu.no/Projects/mysqladm-rs" |  | ||||||
| description = "A command-line utility for MySQL administration for non-admin users" |  | ||||||
| categories = ["command-line-interface", "command-line-utilities"] |  | ||||||
| keywords = ["mysql", "cli", "administration"] |  | ||||||
| readme = "README.md" |  | ||||||
|  |  | ||||||
| [dependencies] | [dependencies] | ||||||
| anyhow = "1.0.95" | anyhow = "1.0.95" | ||||||
| async-bincode = "0.7.3" | async-bincode = "0.8.0" | ||||||
| bincode = "1.3.3" | bincode = "2.0.1" | ||||||
| clap = { version = "4.5.26", features = ["derive"] } | clap = { version = "4.5.26", features = ["derive"] } | ||||||
| clap-verbosity-flag = "2.2.3" | clap-verbosity-flag = "3.0.2" | ||||||
| clap_complete = "4.5.42" | clap_complete = "4.5.42" | ||||||
| derive_more = { version = "1.0.0", features = ["display", "error"] } | derive_more = { version = "2.0.1", features = ["display", "error"] } | ||||||
| dialoguer = "0.11.0" | dialoguer = "0.11.0" | ||||||
| env_logger = "0.11.6" | env_logger = "0.11.6" | ||||||
| futures = "0.3.31" | futures = "0.3.31" | ||||||
| futures-util = "0.3.31" | futures-util = "0.3.31" | ||||||
| indoc = "2.0.5" | indoc = "2.0.5" | ||||||
| itertools = "0.13.0" | itertools = "0.14.0" | ||||||
| log = "0.4.25" | log = "0.4.25" | ||||||
| nix = { version = "0.29.0", features = ["fs", "process", "socket", "user"] } | nix = { version = "0.30.1", features = ["fs", "process", "socket", "user"] } | ||||||
| prettytable = "0.10.0" | prettytable = "0.10.0" | ||||||
| rand = "0.8.5" | rand = "0.9.1" | ||||||
| ratatui = { version = "0.28.1", optional = true } | ratatui = { version = "0.29.0", optional = true } | ||||||
| sd-notify = "0.4.5" | sd-notify = "0.4.5" | ||||||
| serde = "1.0.217" | serde = "1.0.217" | ||||||
| serde_json = { version = "1.0.135", features = ["preserve_order"] } | serde_json = { version = "1.0.135", features = ["preserve_order"] } | ||||||
| @@ -64,37 +54,3 @@ anyhow = "1.0.95" | |||||||
|  |  | ||||||
| [dev-dependencies] | [dev-dependencies] | ||||||
| regex = "1.11.1" | regex = "1.11.1" | ||||||
|  |  | ||||||
| # TODO: package shell completions |  | ||||||
| [package.metadata.deb] |  | ||||||
| maintainer = "Programvareverkstedet <projects@pvv.ntnu.no>" |  | ||||||
| section = "admin" |  | ||||||
| assets = [ |  | ||||||
|     [ |  | ||||||
|         "target/release/mysqladm", |  | ||||||
|         "usr/bin/", |  | ||||||
|         "755", |  | ||||||
|     ], |  | ||||||
|     [ |  | ||||||
|         "example-config.toml", |  | ||||||
|         "etc/mysqladm/config.toml", |  | ||||||
|         "644", |  | ||||||
|     ], |  | ||||||
|     [ |  | ||||||
|         "assets/completions/_*", |  | ||||||
|         "usr/share/zsh/site-functions/completions/", |  | ||||||
|         "644", |  | ||||||
|     ], |  | ||||||
|     [ |  | ||||||
|         "assets/completions/*.bash", |  | ||||||
|         "usr/share/bash-completion/completions/", |  | ||||||
|         "644", |  | ||||||
|     ], |  | ||||||
|     [ |  | ||||||
|         "assets/completions/*.fish", |  | ||||||
|         "usr/share/fish/vendor_completions.d/", |  | ||||||
|         "644", |  | ||||||
|     ], |  | ||||||
| ] |  | ||||||
| conf-files = ["etc/mysqladm/config.toml"] |  | ||||||
| depends = [] |  | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								README.md
									
									
									
									
									
								
							| @@ -2,7 +2,26 @@ | |||||||
|  |  | ||||||
| # mysqladm-rs | # mysqladm-rs | ||||||
|  |  | ||||||
| Work in progress rewrite of https://git.pvv.ntnu.no/Projects/mysql-admutils | Healing mysql spasms since 2024 | ||||||
|  |  | ||||||
|  | ## What is this? | ||||||
|  |  | ||||||
|  | This is a CLI tool that let's normal users perform administrative operations on a MySQL DBMS, with some restrictions. | ||||||
|  | The default restriction is to only let the user perform these actions on databases and database users that are prefixed with their username, | ||||||
|  | or with the name of any unix group that the user is a part of. i.e. `<user>_mydb`, `<user>_mydbuser`, or `<group>_myotherdb`. | ||||||
|  |  | ||||||
|  | The administrative actions available to the user includes: | ||||||
|  |  | ||||||
|  | - creating/listing/modifying/deleting databases and database users | ||||||
|  | - modifying database user privileges | ||||||
|  | - changing the passwords of the database users | ||||||
|  | - locking and unlocking database user accounts | ||||||
|  | - ... more to come | ||||||
|  |  | ||||||
|  | The software is split into a client and a server. The server has administrative access to the mysql server, | ||||||
|  | and is responsible for checking client authorization for the different types of actions the client might request. | ||||||
|  |  | ||||||
|  | This is designed for (and is only really useful for) multi-user servers, like tilde servers, university unix servers, etc. | ||||||
|  |  | ||||||
| ## Installation | ## Installation | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,19 +0,0 @@ | |||||||
| #!/usr/bin/env bash |  | ||||||
|  |  | ||||||
| cargo build --release |  | ||||||
|  |  | ||||||
| mkdir -p assets/completions |  | ||||||
|  |  | ||||||
| ./target/release/mysqladm generate-completions --shell bash > assets/completions/mysqladm.bash |  | ||||||
| ./target/release/mysqladm generate-completions --shell zsh > assets/completions/_mysqladm |  | ||||||
| ./target/release/mysqladm generate-completions --shell fish > assets/completions/mysqladm.fish |  | ||||||
|  |  | ||||||
| ./target/release/mysqladm generate-completions --shell bash --command mysql-dbadm > assets/completions/mysql-dbadm.bash |  | ||||||
| ./target/release/mysqladm generate-completions --shell zsh --command mysql-dbadm > assets/completions/_mysql-dbadm |  | ||||||
| ./target/release/mysqladm generate-completions --shell fish --command mysql-dbadm > assets/completions/mysql-dbadm.fish |  | ||||||
|  |  | ||||||
| ./target/release/mysqladm generate-completions --shell bash --command mysql-useradm > assets/completions/mysql-useradm.bash |  | ||||||
| ./target/release/mysqladm generate-completions --shell zsh --command mysql-useradm > assets/completions/_mysql-useradm |  | ||||||
| ./target/release/mysqladm generate-completions --shell fish --command mysql-useradm > assets/completions/mysql-useradm.fish |  | ||||||
|  |  | ||||||
| cargo deb |  | ||||||
| @@ -19,4 +19,4 @@ port = 3306 | |||||||
| username = "root" | username = "root" | ||||||
| password = "secret" | password = "secret" | ||||||
|  |  | ||||||
| timeout = 2 # seconds | timeout = 2 # seconds | ||||||
							
								
								
									
										12
									
								
								flake.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										12
									
								
								flake.lock
									
									
									
										generated
									
									
									
								
							| @@ -2,11 +2,11 @@ | |||||||
|   "nodes": { |   "nodes": { | ||||||
|     "nixpkgs": { |     "nixpkgs": { | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1737062831, |         "lastModified": 1746461020, | ||||||
|         "narHash": "sha256-Tbk1MZbtV2s5aG+iM99U8FqwxU/YNArMcWAv6clcsBc=", |         "narHash": "sha256-7+pG1I9jvxNlmln4YgnlW4o+w0TZX24k688mibiFDUE=", | ||||||
|         "owner": "NixOS", |         "owner": "NixOS", | ||||||
|         "repo": "nixpkgs", |         "repo": "nixpkgs", | ||||||
|         "rev": "5df43628fdf08d642be8ba5b3625a6c70731c19c", |         "rev": "3730d8a308f94996a9ba7c7138ede69c1b9ac4ae", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
| @@ -29,11 +29,11 @@ | |||||||
|         ] |         ] | ||||||
|       }, |       }, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1737166965, |         "lastModified": 1746585402, | ||||||
|         "narHash": "sha256-vlDROBAgq+7PEVM0vaS2zboY6DXs3oKK0qW/1dVuFs4=", |         "narHash": "sha256-Pf+ufu6bYNA1+KQKHnGMNEfTwpD9ZIcAeLoE2yPWIP0=", | ||||||
|         "owner": "oxalica", |         "owner": "oxalica", | ||||||
|         "repo": "rust-overlay", |         "repo": "rust-overlay", | ||||||
|         "rev": "fc839c9d5d1ebc789b4657c43c4d54838c7c01de", |         "rev": "72dd969389583664f87aa348b3458f2813693617", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|   | |||||||
| @@ -48,7 +48,6 @@ | |||||||
|         mysql-client |         mysql-client | ||||||
|         cargo-nextest |         cargo-nextest | ||||||
|         cargo-deny |         cargo-deny | ||||||
|         cargo-deb |  | ||||||
|       ]; |       ]; | ||||||
|  |  | ||||||
|       RUST_SRC_PATH = "${toolchain}/lib/rustlib/src/rust/library"; |       RUST_SRC_PATH = "${toolchain}/lib/rustlib/src/rust/library"; | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								rustfmt.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								rustfmt.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | style_edition = "2024" | ||||||
| @@ -2,7 +2,7 @@ use anyhow::Context; | |||||||
| use clap::Parser; | use clap::Parser; | ||||||
| use dialoguer::{Confirm, Editor}; | use dialoguer::{Confirm, Editor}; | ||||||
| use futures_util::{SinkExt, StreamExt}; | use futures_util::{SinkExt, StreamExt}; | ||||||
| use nix::unistd::{getuid, User}; | use nix::unistd::{User, getuid}; | ||||||
| use prettytable::{Cell, Row, Table}; | use prettytable::{Cell, Row, Table}; | ||||||
|  |  | ||||||
| use crate::{ | use crate::{ | ||||||
| @@ -15,13 +15,13 @@ use crate::{ | |||||||
|             parse_privilege_table_cli_arg, |             parse_privilege_table_cli_arg, | ||||||
|         }, |         }, | ||||||
|         protocol::{ |         protocol::{ | ||||||
|  |             ClientToServerMessageStream, MySQLDatabase, Request, Response, | ||||||
|             print_create_databases_output_status, print_create_databases_output_status_json, |             print_create_databases_output_status, print_create_databases_output_status_json, | ||||||
|             print_drop_databases_output_status, print_drop_databases_output_status_json, |             print_drop_databases_output_status, print_drop_databases_output_status_json, | ||||||
|             print_modify_database_privileges_output_status, ClientToServerMessageStream, |             print_modify_database_privileges_output_status, | ||||||
|             MySQLDatabase, Request, Response, |  | ||||||
|         }, |         }, | ||||||
|     }, |     }, | ||||||
|     server::sql::database_privilege_operations::{DatabasePrivilegeRow, DATABASE_PRIVILEGE_FIELDS}, |     server::sql::database_privilege_operations::{DATABASE_PRIVILEGE_FIELDS, DatabasePrivilegeRow}, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #[derive(Parser, Debug, Clone)] | #[derive(Parser, Debug, Clone)] | ||||||
|   | |||||||
| @@ -19,8 +19,8 @@ use crate::{ | |||||||
|     core::{ |     core::{ | ||||||
|         bootstrap::bootstrap_server_connection_and_drop_privileges, |         bootstrap::bootstrap_server_connection_and_drop_privileges, | ||||||
|         protocol::{ |         protocol::{ | ||||||
|             create_client_to_server_message_stream, ClientToServerMessageStream, |             ClientToServerMessageStream, GetDatabasesPrivilegeDataError, MySQLDatabase, Request, | ||||||
|             GetDatabasesPrivilegeDataError, MySQLDatabase, Request, Response, |             Response, create_client_to_server_message_stream, | ||||||
|         }, |         }, | ||||||
|     }, |     }, | ||||||
|     server::sql::database_privilege_operations::DatabasePrivilegeRow, |     server::sql::database_privilege_operations::DatabasePrivilegeRow, | ||||||
| @@ -307,11 +307,7 @@ async fn show_databases( | |||||||
|  |  | ||||||
| #[inline] | #[inline] | ||||||
| fn yn(value: bool) -> &'static str { | fn yn(value: bool) -> &'static str { | ||||||
|     if value { |     if value { "Y" } else { "N" } | ||||||
|         "Y" |  | ||||||
|     } else { |  | ||||||
|         "N" |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn print_db_privs(name: &str, rows: Vec<DatabasePrivilegeRow>) -> anyhow::Result<()> { | fn print_db_privs(name: &str, rows: Vec<DatabasePrivilegeRow>) -> anyhow::Result<()> { | ||||||
|   | |||||||
| @@ -19,8 +19,8 @@ use crate::{ | |||||||
|     core::{ |     core::{ | ||||||
|         bootstrap::bootstrap_server_connection_and_drop_privileges, |         bootstrap::bootstrap_server_connection_and_drop_privileges, | ||||||
|         protocol::{ |         protocol::{ | ||||||
|             create_client_to_server_message_stream, ClientToServerMessageStream, MySQLUser, |             ClientToServerMessageStream, MySQLUser, Request, Response, | ||||||
|             Request, Response, |             create_client_to_server_message_stream, | ||||||
|         }, |         }, | ||||||
|     }, |     }, | ||||||
|     server::sql::user_operations::DatabaseUser, |     server::sql::user_operations::DatabaseUser, | ||||||
|   | |||||||
| @@ -4,12 +4,12 @@ use dialoguer::{Confirm, Password}; | |||||||
| use futures_util::{SinkExt, StreamExt}; | use futures_util::{SinkExt, StreamExt}; | ||||||
|  |  | ||||||
| use crate::core::protocol::{ | use crate::core::protocol::{ | ||||||
|  |     ClientToServerMessageStream, ListUsersError, MySQLUser, Request, Response, | ||||||
|     print_create_users_output_status, print_create_users_output_status_json, |     print_create_users_output_status, print_create_users_output_status_json, | ||||||
|     print_drop_users_output_status, print_drop_users_output_status_json, |     print_drop_users_output_status, print_drop_users_output_status_json, | ||||||
|     print_lock_users_output_status, print_lock_users_output_status_json, |     print_lock_users_output_status, print_lock_users_output_status_json, | ||||||
|     print_set_password_output_status, print_unlock_users_output_status, |     print_set_password_output_status, print_unlock_users_output_status, | ||||||
|     print_unlock_users_output_status_json, ClientToServerMessageStream, ListUsersError, MySQLUser, |     print_unlock_users_output_status_json, | ||||||
|     Request, Response, |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| use super::common::erroneous_server_response; | use super::common::erroneous_server_response; | ||||||
|   | |||||||
| @@ -1,12 +1,12 @@ | |||||||
| use std::{fs, path::PathBuf}; | use std::{fs, path::PathBuf}; | ||||||
|  |  | ||||||
| use anyhow::Context; | use anyhow::Context; | ||||||
| use nix::libc::{exit, EXIT_SUCCESS}; | use nix::libc::{EXIT_SUCCESS, exit}; | ||||||
| use std::os::unix::net::UnixStream as StdUnixStream; | use std::os::unix::net::UnixStream as StdUnixStream; | ||||||
| use tokio::net::UnixStream as TokioUnixStream; | use tokio::net::UnixStream as TokioUnixStream; | ||||||
|  |  | ||||||
| use crate::{ | use crate::{ | ||||||
|     core::common::{UnixUser, DEFAULT_CONFIG_PATH, DEFAULT_SOCKET_PATH}, |     core::common::{DEFAULT_CONFIG_PATH, DEFAULT_SOCKET_PATH, UnixUser}, | ||||||
|     server::{config::read_config_from_path, server_loop::handle_requests_for_single_session}, |     server::{config::read_config_from_path, server_loop::handle_requests_for_single_session}, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -66,11 +66,7 @@ impl UnixUser { | |||||||
|  |  | ||||||
| #[inline] | #[inline] | ||||||
| pub(crate) fn yn(b: bool) -> &'static str { | pub(crate) fn yn(b: bool) -> &'static str { | ||||||
|     if b { |     if b { "Y" } else { "N" } | ||||||
|         "Y" |  | ||||||
|     } else { |  | ||||||
|         "N" |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #[inline] | #[inline] | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| use anyhow::{anyhow, Context}; | use anyhow::{Context, anyhow}; | ||||||
| use itertools::Itertools; | use itertools::Itertools; | ||||||
| use prettytable::Table; | use prettytable::Table; | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| @@ -12,7 +12,7 @@ use super::{ | |||||||
|     protocol::{MySQLDatabase, MySQLUser}, |     protocol::{MySQLDatabase, MySQLUser}, | ||||||
| }; | }; | ||||||
| use crate::server::sql::database_privilege_operations::{ | use crate::server::sql::database_privilege_operations::{ | ||||||
|     DatabasePrivilegeRow, DATABASE_PRIVILEGE_FIELDS, |     DATABASE_PRIVILEGE_FIELDS, DatabasePrivilegeRow, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| pub fn db_priv_field_human_readable_name(name: &str) -> String { | pub fn db_priv_field_human_readable_name(name: &str) -> String { | ||||||
| @@ -288,10 +288,10 @@ fn parse_privilege_row_from_editor(row: &str) -> PrivilegeRowParseResult { | |||||||
|  |  | ||||||
|     match parts.len() { |     match parts.len() { | ||||||
|         n if (n < DATABASE_PRIVILEGE_FIELDS.len()) => { |         n if (n < DATABASE_PRIVILEGE_FIELDS.len()) => { | ||||||
|             return PrivilegeRowParseResult::TooFewFields(n) |             return PrivilegeRowParseResult::TooFewFields(n); | ||||||
|         } |         } | ||||||
|         n if (n > DATABASE_PRIVILEGE_FIELDS.len()) => { |         n if (n > DATABASE_PRIVILEGE_FIELDS.len()) => { | ||||||
|             return PrivilegeRowParseResult::TooManyFields(n) |             return PrivilegeRowParseResult::TooManyFields(n); | ||||||
|         } |         } | ||||||
|         _ => {} |         _ => {} | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ use std::{ | |||||||
|  |  | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| use tokio::net::UnixStream; | use tokio::net::UnixStream; | ||||||
| use tokio_serde::{formats::Bincode, Framed as SerdeFramed}; | use tokio_serde::{Framed as SerdeFramed, formats::Bincode}; | ||||||
| use tokio_util::codec::{Framed, LengthDelimitedCodec}; | use tokio_util::codec::{Framed, LengthDelimitedCodec}; | ||||||
|  |  | ||||||
| use crate::core::{database_privileges::DatabasePrivilegesDiff, protocol::*}; | use crate::core::{database_privileges::DatabasePrivilegesDiff, protocol::*}; | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
| extern crate prettytable; | extern crate prettytable; | ||||||
|  |  | ||||||
| use clap::{CommandFactory, Parser, ValueEnum}; | use clap::{CommandFactory, Parser, ValueEnum}; | ||||||
| use clap_complete::{generate, Shell}; | use clap_complete::{Shell, generate}; | ||||||
| use clap_verbosity_flag::Verbosity; | use clap_verbosity_flag::Verbosity; | ||||||
|  |  | ||||||
| use std::path::PathBuf; | use std::path::PathBuf; | ||||||
| @@ -15,7 +15,7 @@ use futures::StreamExt; | |||||||
| use crate::{ | use crate::{ | ||||||
|     core::{ |     core::{ | ||||||
|         bootstrap::bootstrap_server_connection_and_drop_privileges, |         bootstrap::bootstrap_server_connection_and_drop_privileges, | ||||||
|         protocol::{create_client_to_server_message_stream, Response}, |         protocol::{Response, create_client_to_server_message_stream}, | ||||||
|     }, |     }, | ||||||
|     server::command::ServerArgs, |     server::command::ServerArgs, | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ use std::os::unix::net::UnixStream as StdUnixStream; | |||||||
| use tokio::net::UnixStream as TokioUnixStream; | use tokio::net::UnixStream as TokioUnixStream; | ||||||
|  |  | ||||||
| use crate::core::common::UnixUser; | use crate::core::common::UnixUser; | ||||||
| use crate::core::protocol::{create_server_to_client_message_stream, Response}; | use crate::core::protocol::{Response, create_server_to_client_message_stream}; | ||||||
| use crate::server::config::read_config_from_path_with_arg_overrides; | use crate::server::config::read_config_from_path_with_arg_overrides; | ||||||
| use crate::server::server_loop::listen_for_incoming_connections; | use crate::server::server_loop::listen_for_incoming_connections; | ||||||
| use crate::server::{ | use crate::server::{ | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| use std::{fs, path::PathBuf, time::Duration}; | use std::{fs, path::PathBuf, time::Duration}; | ||||||
|  |  | ||||||
| use anyhow::{anyhow, Context}; | use anyhow::{Context, anyhow}; | ||||||
| use clap::Parser; | use clap::Parser; | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| use sqlx::{mysql::MySqlConnectOptions, ConnectOptions, MySqlConnection}; | use sqlx::{ConnectOptions, MySqlConnection, mysql::MySqlConnectOptions}; | ||||||
|  |  | ||||||
| use crate::core::common::DEFAULT_CONFIG_PATH; | use crate::core::common::DEFAULT_CONFIG_PATH; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,20 +4,20 @@ use futures_util::{SinkExt, StreamExt}; | |||||||
| use indoc::concatdoc; | use indoc::concatdoc; | ||||||
| use tokio::net::{UnixListener, UnixStream}; | use tokio::net::{UnixListener, UnixStream}; | ||||||
|  |  | ||||||
| use sqlx::prelude::*; |  | ||||||
| use sqlx::MySqlConnection; | use sqlx::MySqlConnection; | ||||||
|  | use sqlx::prelude::*; | ||||||
|  |  | ||||||
| use crate::core::protocol::SetPasswordError; | use crate::core::protocol::SetPasswordError; | ||||||
| use crate::server::sql::database_operations::list_databases; | use crate::server::sql::database_operations::list_databases; | ||||||
| use crate::{ | use crate::{ | ||||||
|     core::{ |     core::{ | ||||||
|         common::{UnixUser, DEFAULT_SOCKET_PATH}, |         common::{DEFAULT_SOCKET_PATH, UnixUser}, | ||||||
|         protocol::request_response::{ |         protocol::request_response::{ | ||||||
|             create_server_to_client_message_stream, Request, Response, ServerToClientMessageStream, |             Request, Response, ServerToClientMessageStream, create_server_to_client_message_stream, | ||||||
|         }, |         }, | ||||||
|     }, |     }, | ||||||
|     server::{ |     server::{ | ||||||
|         config::{create_mysql_connection_from_config, ServerConfig}, |         config::{ServerConfig, create_mysql_connection_from_config}, | ||||||
|         sql::{ |         sql::{ | ||||||
|             database_operations::{create_databases, drop_databases, list_all_databases_for_user}, |             database_operations::{create_databases, drop_databases, list_all_databases_for_user}, | ||||||
|             database_privilege_operations::{ |             database_privilege_operations::{ | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| use std::collections::BTreeMap; | use std::collections::BTreeMap; | ||||||
|  |  | ||||||
| use sqlx::prelude::*; |  | ||||||
| use sqlx::MySqlConnection; | use sqlx::MySqlConnection; | ||||||
|  | use sqlx::prelude::*; | ||||||
|  |  | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,11 +19,11 @@ use std::collections::{BTreeMap, BTreeSet}; | |||||||
| use indoc::indoc; | use indoc::indoc; | ||||||
| use itertools::Itertools; | use itertools::Itertools; | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| use sqlx::{mysql::MySqlRow, prelude::*, MySqlConnection}; | use sqlx::{MySqlConnection, mysql::MySqlRow, prelude::*}; | ||||||
|  |  | ||||||
| use crate::{ | use crate::{ | ||||||
|     core::{ |     core::{ | ||||||
|         common::{rev_yn, yn, UnixUser}, |         common::{UnixUser, rev_yn, yn}, | ||||||
|         database_privileges::{DatabasePrivilegeChange, DatabasePrivilegesDiff}, |         database_privileges::{DatabasePrivilegeChange, DatabasePrivilegesDiff}, | ||||||
|         protocol::{ |         protocol::{ | ||||||
|             DiffDoesNotApplyError, GetAllDatabasesPrivilegeData, GetAllDatabasesPrivilegeDataError, |             DiffDoesNotApplyError, GetAllDatabasesPrivilegeData, GetAllDatabasesPrivilegeDataError, | ||||||
| @@ -280,9 +280,8 @@ async fn unsafe_apply_privilege_diff( | |||||||
|                 .map(|field| quote_identifier(field)) |                 .map(|field| quote_identifier(field)) | ||||||
|                 .join(","); |                 .join(","); | ||||||
|  |  | ||||||
|             let question_marks = std::iter::repeat("?") |             let question_marks = | ||||||
|                 .take(DATABASE_PRIVILEGE_FIELDS.len()) |                 std::iter::repeat_n("?", DATABASE_PRIVILEGE_FIELDS.len()).join(","); | ||||||
|                 .join(","); |  | ||||||
|  |  | ||||||
|             sqlx::query( |             sqlx::query( | ||||||
|                 format!("INSERT INTO `db` ({}) VALUES ({})", tables, question_marks).as_str(), |                 format!("INSERT INTO `db` ({}) VALUES ({})", tables, question_marks).as_str(), | ||||||
|   | |||||||
| @@ -4,8 +4,8 @@ use std::collections::BTreeMap; | |||||||
|  |  | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
|  |  | ||||||
| use sqlx::prelude::*; |  | ||||||
| use sqlx::MySqlConnection; | use sqlx::MySqlConnection; | ||||||
|  | use sqlx::prelude::*; | ||||||
|  |  | ||||||
| use crate::{ | use crate::{ | ||||||
|     core::{ |     core::{ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user