parent
f43499fca0
commit
20669569f3
|
@ -14,8 +14,8 @@ use crate::server::sql::database_privilege_operations::{
|
|||
|
||||
pub fn db_priv_field_human_readable_name(name: &str) -> String {
|
||||
match name {
|
||||
"db" => "Database".to_owned(),
|
||||
"user" => "User".to_owned(),
|
||||
"Db" => "Database".to_owned(),
|
||||
"User" => "User".to_owned(),
|
||||
"select_priv" => "Select".to_owned(),
|
||||
"insert_priv" => "Insert".to_owned(),
|
||||
"update_priv" => "Update".to_owned(),
|
||||
|
@ -128,8 +128,8 @@ pub fn format_privileges_line_for_editor(
|
|||
DATABASE_PRIVILEGE_FIELDS
|
||||
.into_iter()
|
||||
.map(|field| match field {
|
||||
"db" => format!("{:width$}", privs.db, width = database_name_len),
|
||||
"user" => format!("{:width$}", privs.user, width = username_len),
|
||||
"Db" => format!("{:width$}", privs.db, width = database_name_len),
|
||||
"User" => format!("{:width$}", privs.user, width = username_len),
|
||||
privilege => format!(
|
||||
"{:width$}",
|
||||
yn(privs.get_privilege_by_name(privilege)),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::core::common::UnixUser;
|
||||
use sqlx::prelude::*;
|
||||
|
||||
/// This function creates a regex that matches items (users, databases)
|
||||
/// that belong to the user or any of the user's groups.
|
||||
|
@ -9,3 +10,17 @@ pub fn create_user_group_matching_regex(user: &UnixUser) -> String {
|
|||
format!("({}|{})(_.+)?", user.username, user.groups.join("|"))
|
||||
}
|
||||
}
|
||||
|
||||
/// Some mysql versions with some collations mark some columns as binary fields,
|
||||
/// which in the current version of sqlx is not parsable as string.
|
||||
/// See: https://github.com/launchbadge/sqlx/issues/3387
|
||||
#[inline]
|
||||
pub fn try_get_with_binary_fallback(
|
||||
row: &sqlx::mysql::MySqlRow,
|
||||
column: &str,
|
||||
) -> Result<String, sqlx::Error> {
|
||||
row.try_get(column).or_else(|_| {
|
||||
row.try_get::<Vec<u8>, _>(column)
|
||||
.map(|v| String::from_utf8_lossy(&v).to_string())
|
||||
})
|
||||
}
|
|
@ -32,7 +32,7 @@ use crate::{
|
|||
},
|
||||
},
|
||||
server::{
|
||||
common::create_user_group_matching_regex,
|
||||
common::{create_user_group_matching_regex, try_get_with_binary_fallback},
|
||||
input_sanitization::{quote_identifier, validate_name, validate_ownership_by_unix_user},
|
||||
sql::database_operations::unsafe_database_exists,
|
||||
},
|
||||
|
@ -42,8 +42,8 @@ use crate::{
|
|||
/// from the `db` table in the database. If you need to add or remove privilege
|
||||
/// fields, this is a good place to start.
|
||||
pub const DATABASE_PRIVILEGE_FIELDS: [&str; 13] = [
|
||||
"db",
|
||||
"user",
|
||||
"Db",
|
||||
"User",
|
||||
"select_priv",
|
||||
"insert_priv",
|
||||
"update_priv",
|
||||
|
@ -97,6 +97,8 @@ impl DatabasePrivilegeRow {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: get by name instead of row tuple position
|
||||
|
||||
#[inline]
|
||||
fn get_mysql_row_priv_field(row: &MySqlRow, position: usize) -> Result<bool, sqlx::Error> {
|
||||
let field = DATABASE_PRIVILEGE_FIELDS[position];
|
||||
|
@ -113,8 +115,8 @@ fn get_mysql_row_priv_field(row: &MySqlRow, position: usize) -> Result<bool, sql
|
|||
impl FromRow<'_, MySqlRow> for DatabasePrivilegeRow {
|
||||
fn from_row(row: &MySqlRow) -> Result<Self, sqlx::Error> {
|
||||
Ok(Self {
|
||||
db: row.try_get("db")?,
|
||||
user: row.try_get("user")?,
|
||||
db: try_get_with_binary_fallback(row, "Db")?,
|
||||
user: try_get_with_binary_fallback(row, "User")?,
|
||||
select_priv: get_mysql_row_priv_field(row, 2)?,
|
||||
insert_priv: get_mysql_row_priv_field(row, 3)?,
|
||||
update_priv: get_mysql_row_priv_field(row, 4)?,
|
||||
|
@ -137,7 +139,7 @@ async fn unsafe_get_database_privileges(
|
|||
connection: &mut MySqlConnection,
|
||||
) -> Result<Vec<DatabasePrivilegeRow>, sqlx::Error> {
|
||||
let result = sqlx::query_as::<_, DatabasePrivilegeRow>(&format!(
|
||||
"SELECT {} FROM `db` WHERE `db` = ?",
|
||||
"SELECT {} FROM `db` WHERE `Db` = ?",
|
||||
DATABASE_PRIVILEGE_FIELDS
|
||||
.iter()
|
||||
.map(|field| quote_identifier(field))
|
||||
|
@ -166,7 +168,7 @@ pub async fn unsafe_get_database_privileges_for_db_user_pair(
|
|||
connection: &mut MySqlConnection,
|
||||
) -> Result<Option<DatabasePrivilegeRow>, sqlx::Error> {
|
||||
let result = sqlx::query_as::<_, DatabasePrivilegeRow>(&format!(
|
||||
"SELECT {} FROM `db` WHERE `db` = ? AND `user` = ?",
|
||||
"SELECT {} FROM `db` WHERE `Db` = ? AND `User` = ?",
|
||||
DATABASE_PRIVILEGE_FIELDS
|
||||
.iter()
|
||||
.map(|field| quote_identifier(field))
|
||||
|
@ -316,7 +318,7 @@ async fn unsafe_apply_privilege_diff(
|
|||
.join(",");
|
||||
|
||||
sqlx::query(
|
||||
format!("UPDATE `db` SET {} WHERE `db` = ? AND `user` = ?", changes).as_str(),
|
||||
format!("UPDATE `db` SET {} WHERE `Db` = ? AND `User` = ?", changes).as_str(),
|
||||
)
|
||||
.bind(p.db.to_string())
|
||||
.bind(p.user.to_string())
|
||||
|
@ -325,7 +327,7 @@ async fn unsafe_apply_privilege_diff(
|
|||
.map(|_| ())
|
||||
}
|
||||
DatabasePrivilegesDiff::Deleted(p) => {
|
||||
sqlx::query("DELETE FROM `db` WHERE `db` = ? AND `user` = ?")
|
||||
sqlx::query("DELETE FROM `db` WHERE `Db` = ? AND `User` = ?")
|
||||
.bind(p.db.to_string())
|
||||
.bind(p.user.to_string())
|
||||
.execute(connection)
|
||||
|
|
|
@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize};
|
|||
use sqlx::prelude::*;
|
||||
use sqlx::MySqlConnection;
|
||||
|
||||
use crate::server::common::try_get_with_binary_fallback;
|
||||
use crate::{
|
||||
core::{
|
||||
common::UnixUser,
|
||||
|
@ -350,20 +351,6 @@ pub struct DatabaseUser {
|
|||
pub databases: Vec<String>,
|
||||
}
|
||||
|
||||
/// Some mysql versions with some collations mark some columns as binary fields,
|
||||
/// which in the current version of sqlx is not parsable as string.
|
||||
/// See: https://github.com/launchbadge/sqlx/issues/3387
|
||||
#[inline]
|
||||
fn try_get_with_binary_fallback(
|
||||
row: &sqlx::mysql::MySqlRow,
|
||||
column: &str,
|
||||
) -> Result<String, sqlx::Error> {
|
||||
row.try_get(column).or_else(|_| {
|
||||
row.try_get::<Vec<u8>, _>(column)
|
||||
.map(|v| String::from_utf8_lossy(&v).to_string())
|
||||
})
|
||||
}
|
||||
|
||||
impl FromRow<'_, sqlx::mysql::MySqlRow> for DatabaseUser {
|
||||
fn from_row(row: &sqlx::mysql::MySqlRow) -> Result<Self, sqlx::Error> {
|
||||
Ok(Self {
|
||||
|
|
Loading…
Reference in New Issue