mysqladm/core/database_privileges/
base.rs

1//! This module contains some base datastructures and functionality for dealing with
2//! database privileges in MySQL.
3
4use std::fmt;
5
6use crate::core::types::{MySQLDatabase, MySQLUser};
7use serde::{Deserialize, Serialize};
8
9/// This is the list of fields that are used to fetch the db + user + privileges
10/// from the `db` table in the database. If you need to add or remove privilege
11/// fields, this is a good place to start.
12pub const DATABASE_PRIVILEGE_FIELDS: [&str; 13] = [
13    "Db",
14    "User",
15    "select_priv",
16    "insert_priv",
17    "update_priv",
18    "delete_priv",
19    "create_priv",
20    "drop_priv",
21    "alter_priv",
22    "index_priv",
23    "create_tmp_table_priv",
24    "lock_tables_priv",
25    "references_priv",
26];
27
28// NOTE: ord is needed for BTreeSet to accept the type, but it
29//       doesn't have any natural implementation semantics.
30
31/// Representation of the set of privileges for a single user on a single database.
32#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)]
33pub struct DatabasePrivilegeRow {
34    // TODO: don't store the db and user here, let the type be stored in a mapping
35    pub db: MySQLDatabase,
36    pub user: MySQLUser,
37    pub select_priv: bool,
38    pub insert_priv: bool,
39    pub update_priv: bool,
40    pub delete_priv: bool,
41    pub create_priv: bool,
42    pub drop_priv: bool,
43    pub alter_priv: bool,
44    pub index_priv: bool,
45    pub create_tmp_table_priv: bool,
46    pub lock_tables_priv: bool,
47    pub references_priv: bool,
48}
49
50impl DatabasePrivilegeRow {
51    /// Gets the value of a privilege by its name as a &str.
52    pub fn get_privilege_by_name(&self, name: &str) -> Option<bool> {
53        match name {
54            "select_priv" => Some(self.select_priv),
55            "insert_priv" => Some(self.insert_priv),
56            "update_priv" => Some(self.update_priv),
57            "delete_priv" => Some(self.delete_priv),
58            "create_priv" => Some(self.create_priv),
59            "drop_priv" => Some(self.drop_priv),
60            "alter_priv" => Some(self.alter_priv),
61            "index_priv" => Some(self.index_priv),
62            "create_tmp_table_priv" => Some(self.create_tmp_table_priv),
63            "lock_tables_priv" => Some(self.lock_tables_priv),
64            "references_priv" => Some(self.references_priv),
65            _ => None,
66        }
67    }
68}
69
70impl fmt::Display for DatabasePrivilegeRow {
71    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72        for field in DATABASE_PRIVILEGE_FIELDS.into_iter().skip(2) {
73            if self.get_privilege_by_name(field).unwrap() {
74                f.write_str(db_priv_field_human_readable_name(field).as_str())?;
75                f.write_str(": Y\n")?;
76            } else {
77                f.write_str(db_priv_field_human_readable_name(field).as_str())?;
78                f.write_str(": N\n")?;
79            }
80        }
81        Ok(())
82    }
83}
84
85/// Converts a database privilege field name to a human-readable name.
86pub fn db_priv_field_human_readable_name(name: &str) -> String {
87    match name {
88        "Db" => "Database".to_owned(),
89        "User" => "User".to_owned(),
90        "select_priv" => "Select".to_owned(),
91        "insert_priv" => "Insert".to_owned(),
92        "update_priv" => "Update".to_owned(),
93        "delete_priv" => "Delete".to_owned(),
94        "create_priv" => "Create".to_owned(),
95        "drop_priv" => "Drop".to_owned(),
96        "alter_priv" => "Alter".to_owned(),
97        "index_priv" => "Index".to_owned(),
98        "create_tmp_table_priv" => "Temp".to_owned(),
99        "lock_tables_priv" => "Lock".to_owned(),
100        "references_priv" => "References".to_owned(),
101        _ => format!("Unknown({})", name),
102    }
103}