mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-21 08:02:38 +00:00
fix(datatables): the database name is taken exactly, the export is admin-only, and a dropped clone forgets its row
This commit is contained in:
@@ -1354,18 +1354,37 @@ pub struct DropForkedDatatableDatabasesRequest {
|
||||
/// was created in. The permissions row stays until the drop succeeds — with its
|
||||
/// logins gone every role is refused meanwhile — and is forgotten by the caller
|
||||
/// once the database is. Returns the key of that database's permissions when
|
||||
/// roles were dropped.
|
||||
/// this workspace owns them and nothing stands in the way of forgetting them:
|
||||
/// a row with no logins to drop included, or the database's next namesake would
|
||||
/// find it governed by a workspace that is gone.
|
||||
async fn drop_datatable_roles_before_its_database(
|
||||
db: &DB,
|
||||
w_id: &str,
|
||||
dt_name: &str,
|
||||
) -> Option<String> {
|
||||
let planned =
|
||||
crate::datatable_permissions::plan_drop_of_datatable_roles(db, w_id, dt_name).await?;
|
||||
let key = planned.2.clone();
|
||||
crate::datatable_permissions::run_planned_drop_keeping_record(db, w_id, dt_name, planned)
|
||||
let (_, _, key) =
|
||||
windmill_common::workspaces::resolve_datatable_database_unchecked(db, w_id, dt_name)
|
||||
.await
|
||||
.ok()?;
|
||||
let record = windmill_common::workspaces::database_permissions_by_key(db, &key)
|
||||
.await
|
||||
.then_some(key)
|
||||
.ok()
|
||||
.flatten()?;
|
||||
if record.owner_workspace_id.as_deref() != Some(w_id) {
|
||||
return None;
|
||||
}
|
||||
if let Some(planned) =
|
||||
crate::datatable_permissions::plan_drop_of_datatable_roles(db, w_id, dt_name).await
|
||||
{
|
||||
if !crate::datatable_permissions::run_planned_drop_keeping_record(
|
||||
db, w_id, dt_name, planned,
|
||||
)
|
||||
.await
|
||||
{
|
||||
return None;
|
||||
}
|
||||
}
|
||||
Some(key)
|
||||
}
|
||||
|
||||
/// Drop forked datatable databases. Returns errors per datatable that failed.
|
||||
|
||||
@@ -1764,8 +1764,12 @@ pub(crate) async fn tarball_workspace(
|
||||
// the database, with roles and tenants — no passwords, which are direct
|
||||
// database logins, and no login names, which a re-save generates. A database
|
||||
// no entry of the workspace reaches any more cannot be named, and is left out.
|
||||
let permissions =
|
||||
windmill_common::workspaces::database_permissions_owned_by(&mut *tx, &w_id).await?;
|
||||
// Admin-only, like the settings and like the drawer that shows the same thing.
|
||||
let permissions = if include_settings.unwrap_or(false) {
|
||||
windmill_common::workspaces::database_permissions_owned_by(&mut *tx, &w_id).await?
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
if !permissions.is_empty() {
|
||||
let mut reaching: std::collections::HashMap<String, String> =
|
||||
std::collections::HashMap::new();
|
||||
|
||||
@@ -1300,12 +1300,13 @@ pub fn datatable_database_key(
|
||||
use sha2::{Digest, Sha256};
|
||||
// As the connection reads them, not as the JSON spells them: a port
|
||||
// left out is 5432, a number and its string are one port, a host is
|
||||
// one host whatever its case.
|
||||
// one host whatever its case. A database name is taken exactly — `"prod "`
|
||||
// is a database of its own to Postgres.
|
||||
let text = |field: &str| {
|
||||
resolved
|
||||
.get(field)
|
||||
.map(|v| match v.as_str() {
|
||||
Some(s) => s.trim().to_string(),
|
||||
Some(s) => s.to_string(),
|
||||
None => v.to_string(),
|
||||
})
|
||||
.unwrap_or_default()
|
||||
@@ -3476,7 +3477,11 @@ mod tests {
|
||||
// A host is one host whatever its case, as DNS reads it.
|
||||
assert_eq!(
|
||||
datatable_database_key(&pg("u/a/pg"), &resolved("db.example", "prod", "app")),
|
||||
datatable_database_key(&pg("u/a/pg"), &resolved(" DB.Example ", "prod", "app"))
|
||||
datatable_database_key(&pg("u/a/pg"), &resolved("DB.Example", "prod", "app"))
|
||||
);
|
||||
assert_ne!(
|
||||
datatable_database_key(&pg("u/a/pg"), &resolved("db", "prod", "app")),
|
||||
datatable_database_key(&pg("u/a/pg"), &resolved("db", "prod ", "app"))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user