1
use std::collections::{BTreeMap, BTreeSet};
2

            
3
use serde::{Deserialize, Serialize};
4

            
5
use crate::core::{
6
    database_privileges::{DatabasePrivilegeRow, DatabasePrivilegeRowDiff, DatabasePrivilegesDiff},
7
    protocol::request_validation::{DbOrUser, NameValidationError, OwnerValidationError},
8
    types::{MySQLDatabase, MySQLUser},
9
};
10

            
11
pub type ModifyPrivilegesRequest = BTreeSet<DatabasePrivilegesDiff>;
12

            
13
pub type ModifyPrivilegesResponse =
14
    BTreeMap<(MySQLDatabase, MySQLUser), Result<(), ModifyDatabasePrivilegesError>>;
15

            
16
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
17
pub enum ModifyDatabasePrivilegesError {
18
    DatabaseSanitizationError(NameValidationError),
19
    DatabaseOwnershipError(OwnerValidationError),
20
    UserSanitizationError(NameValidationError),
21
    UserOwnershipError(OwnerValidationError),
22
    DatabaseDoesNotExist,
23
    DiffDoesNotApply(DiffDoesNotApplyError),
24
    MySqlError(String),
25
}
26

            
27
#[allow(clippy::enum_variant_names)]
28
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
29
pub enum DiffDoesNotApplyError {
30
    RowAlreadyExists(MySQLDatabase, MySQLUser),
31
    RowDoesNotExist(MySQLDatabase, MySQLUser),
32
    RowPrivilegeChangeDoesNotApply(DatabasePrivilegeRowDiff, DatabasePrivilegeRow),
33
}
34

            
35
pub fn print_modify_database_privileges_output_status(output: &ModifyPrivilegesResponse) {
36
    for ((database_name, username), result) in output {
37
        match result {
38
            Ok(()) => {
39
                println!(
40
                    "Privileges for user '{}' on database '{}' modified successfully.",
41
                    username, database_name
42
                );
43
            }
44
            Err(err) => {
45
                println!("{}", err.to_error_message(database_name, username));
46
                println!("Skipping...");
47
            }
48
        }
49
        println!();
50
    }
51
}
52

            
53
impl ModifyDatabasePrivilegesError {
54
    pub fn to_error_message(&self, database_name: &MySQLDatabase, username: &MySQLUser) -> String {
55
        match self {
56
            ModifyDatabasePrivilegesError::DatabaseSanitizationError(err) => {
57
                err.to_error_message(database_name, DbOrUser::Database)
58
            }
59
            ModifyDatabasePrivilegesError::DatabaseOwnershipError(err) => {
60
                err.to_error_message(database_name, DbOrUser::Database)
61
            }
62
            ModifyDatabasePrivilegesError::UserSanitizationError(err) => {
63
                err.to_error_message(username, DbOrUser::User)
64
            }
65
            ModifyDatabasePrivilegesError::UserOwnershipError(err) => {
66
                err.to_error_message(username, DbOrUser::User)
67
            }
68
            ModifyDatabasePrivilegesError::DatabaseDoesNotExist => {
69
                format!("Database '{}' does not exist.", database_name)
70
            }
71
            ModifyDatabasePrivilegesError::DiffDoesNotApply(diff) => {
72
                format!(
73
                    "Could not apply privilege change:\n{}",
74
                    diff.to_error_message()
75
                )
76
            }
77
            ModifyDatabasePrivilegesError::MySqlError(err) => {
78
                format!("MySQL error: {}", err)
79
            }
80
        }
81
    }
82
}
83

            
84
impl DiffDoesNotApplyError {
85
    pub fn to_error_message(&self) -> String {
86
        match self {
87
            DiffDoesNotApplyError::RowAlreadyExists(database_name, username) => {
88
                format!(
89
                    "Privileges for user '{}' on database '{}' already exist.",
90
                    username, database_name
91
                )
92
            }
93
            DiffDoesNotApplyError::RowDoesNotExist(database_name, username) => {
94
                format!(
95
                    "Privileges for user '{}' on database '{}' do not exist.",
96
                    username, database_name
97
                )
98
            }
99
            DiffDoesNotApplyError::RowPrivilegeChangeDoesNotApply(diff, row) => {
100
                format!(
101
                    "Could not apply privilege change {:?} to row {:?}",
102
                    diff, row
103
                )
104
            }
105
        }
106
    }
107
}