fix(datatables): guard the resource upsert too, and cache its query

create_resource with update_if_exists is an edit when the row is already
there, so it answered to none of the rule the other two write paths do. And
the lookup the guard makes had no offline entry, which is what CI compiles
against.
This commit is contained in:
Diego Imbert
2026-09-02 00:00:07 +02:00
parent c289a40e5b
commit 2cde025d8e
2 changed files with 44 additions and 0 deletions
@@ -0,0 +1,23 @@
{
"db_name": "PostgreSQL",
"query": "SELECT value FROM resource WHERE path = $1 AND workspace_id = $2",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "value",
"type_info": "Jsonb"
}
],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": [
true
]
},
"hash": "63c16a4277983aaed0aed54972923919cee3cc444725ac6b7906922554bae800"
}
+21
View File
@@ -1187,6 +1187,27 @@ async fn create_resource(
.await?;
}
if update_if_exists {
// An upsert over an existing row is an edit, so it answers to the same
// rule: a permissioned data table's roles live in the database its
// resource names, and that is not free to move while they exist.
let previous = sqlx::query_scalar!(
"SELECT value FROM resource WHERE path = $1 AND workspace_id = $2",
resource.path,
w_id
)
.fetch_optional(&db)
.await?
.flatten();
let nvalue: serde_json::Value = serde_json::from_str(raw_json.0.get())
.map_err(|e| Error::BadRequest(format!("Invalid resource value: {e}")))?;
windmill_common::workspaces::ensure_resource_identity_change_allowed(
&db,
&w_id,
&resource.path,
previous.as_ref(),
Some(&nvalue),
)
.await?;
sqlx::query!(
"INSERT INTO resource
(workspace_id, path, value, description, resource_type, created_by, edited_at, labels)