148 lines
5.4 KiB
Rust
148 lines
5.4 KiB
Rust
use std::collections::{BTreeMap, BTreeSet};
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
use thiserror::Error;
|
|
|
|
use crate::core::{
|
|
database_privileges::{DatabasePrivilegeRow, DatabasePrivilegeRowDiff, DatabasePrivilegesDiff},
|
|
protocol::request_validation::ValidationError,
|
|
types::{DbOrUser, MySQLDatabase, MySQLUser},
|
|
};
|
|
|
|
pub type ModifyPrivilegesRequest = BTreeSet<DatabasePrivilegesDiff>;
|
|
|
|
pub type ModifyPrivilegesResponse =
|
|
BTreeMap<(MySQLDatabase, MySQLUser), Result<(), ModifyDatabasePrivilegesError>>;
|
|
|
|
#[derive(Error, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub enum ModifyDatabasePrivilegesError {
|
|
#[error("Database validation error: {0}")]
|
|
DatabaseValidationError(ValidationError),
|
|
|
|
#[error("User validation error: {0}")]
|
|
UserValidationError(ValidationError),
|
|
|
|
#[error("Database does not exist")]
|
|
DatabaseDoesNotExist,
|
|
|
|
#[error("User does not exist")]
|
|
UserDoesNotExist,
|
|
|
|
#[error("Diff does not apply: {0}")]
|
|
DiffDoesNotApply(DiffDoesNotApplyError),
|
|
|
|
#[error("MySQL error: {0}")]
|
|
MySqlError(String),
|
|
}
|
|
|
|
#[allow(clippy::enum_variant_names)]
|
|
#[derive(Error, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub enum DiffDoesNotApplyError {
|
|
#[error("Privileges row already exists for database '{0}' and user '{1}'")]
|
|
RowAlreadyExists(MySQLDatabase, MySQLUser),
|
|
|
|
#[error("Privileges row does not exist for database '{0}' and user '{1}'")]
|
|
RowDoesNotExist(MySQLDatabase, MySQLUser),
|
|
|
|
#[error("Privilege change '{0:?}' does not apply to row '{1:?}'")]
|
|
RowPrivilegeChangeDoesNotApply(DatabasePrivilegeRowDiff, DatabasePrivilegeRow),
|
|
}
|
|
|
|
pub fn print_modify_database_privileges_output_status(output: &ModifyPrivilegesResponse) {
|
|
for ((database_name, username), result) in output {
|
|
match result {
|
|
Ok(()) => {
|
|
println!(
|
|
"Privileges for user '{}' on database '{}' modified successfully.",
|
|
username, database_name
|
|
);
|
|
}
|
|
Err(err) => {
|
|
eprintln!("{}", err.to_error_message(database_name, username));
|
|
eprintln!("Skipping...");
|
|
}
|
|
}
|
|
println!();
|
|
}
|
|
}
|
|
|
|
impl ModifyDatabasePrivilegesError {
|
|
pub fn to_error_message(&self, database_name: &MySQLDatabase, username: &MySQLUser) -> String {
|
|
match self {
|
|
ModifyDatabasePrivilegesError::DatabaseValidationError(err) => {
|
|
err.to_error_message(DbOrUser::Database(database_name.clone()))
|
|
}
|
|
ModifyDatabasePrivilegesError::UserValidationError(err) => {
|
|
err.to_error_message(DbOrUser::User(username.clone()))
|
|
}
|
|
ModifyDatabasePrivilegesError::DatabaseDoesNotExist => {
|
|
format!("Database '{}' does not exist.", database_name)
|
|
}
|
|
ModifyDatabasePrivilegesError::UserDoesNotExist => {
|
|
format!("User '{}' does not exist.", username)
|
|
}
|
|
ModifyDatabasePrivilegesError::DiffDoesNotApply(diff) => {
|
|
format!(
|
|
"Could not apply privilege change:\n{}",
|
|
diff.to_error_message()
|
|
)
|
|
}
|
|
ModifyDatabasePrivilegesError::MySqlError(err) => {
|
|
format!("MySQL error: {}", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub fn error_type(&self) -> String {
|
|
match self {
|
|
// TODO: should these be subtyped?
|
|
ModifyDatabasePrivilegesError::DatabaseValidationError(err) => err.error_type(),
|
|
ModifyDatabasePrivilegesError::UserValidationError(err) => err.error_type(),
|
|
ModifyDatabasePrivilegesError::DatabaseDoesNotExist => {
|
|
"database-does-not-exist".to_string()
|
|
}
|
|
ModifyDatabasePrivilegesError::UserDoesNotExist => "user-does-not-exist".to_string(),
|
|
ModifyDatabasePrivilegesError::DiffDoesNotApply(err) => {
|
|
format!("diff-does-not-apply/{}", err.error_type())
|
|
}
|
|
ModifyDatabasePrivilegesError::MySqlError(_) => "mysql-error".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl DiffDoesNotApplyError {
|
|
pub fn to_error_message(&self) -> String {
|
|
match self {
|
|
DiffDoesNotApplyError::RowAlreadyExists(database_name, username) => {
|
|
format!(
|
|
"Privileges for user '{}' on database '{}' already exist.",
|
|
username, database_name
|
|
)
|
|
}
|
|
DiffDoesNotApplyError::RowDoesNotExist(database_name, username) => {
|
|
format!(
|
|
"Privileges for user '{}' on database '{}' do not exist.",
|
|
username, database_name
|
|
)
|
|
}
|
|
DiffDoesNotApplyError::RowPrivilegeChangeDoesNotApply(diff, row) => {
|
|
format!(
|
|
"Could not apply privilege change {:?} to row {:?}",
|
|
diff, row
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn error_type(&self) -> String {
|
|
match self {
|
|
DiffDoesNotApplyError::RowAlreadyExists(_, _) => "row-already-exists".to_string(),
|
|
DiffDoesNotApplyError::RowDoesNotExist(_, _) => "row-does-not-exist".to_string(),
|
|
DiffDoesNotApplyError::RowPrivilegeChangeDoesNotApply(_, _) => {
|
|
"row-privilege-change-does-not-apply".to_string()
|
|
}
|
|
}
|
|
}
|
|
}
|