Compare commits
2 Commits
v1.682.0
...
trigger-40
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6b29694d2 | ||
|
|
107dfee8ec |
22
backend/.sqlx/query-0d75c9bd7f532622c80cc856e9ee48923a97b5db7130e6517bee3ea90cc24ef5.json
generated
Normal file
22
backend/.sqlx/query-0d75c9bd7f532622c80cc856e9ee48923a97b5db7130e6517bee3ea90cc24ef5.json
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT email FROM password WHERE username = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "email",
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "0d75c9bd7f532622c80cc856e9ee48923a97b5db7130e6517bee3ea90cc24ef5"
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n UPDATE kafka_trigger\n SET\n kafka_resource_path = $1,\n group_id = $2,\n topics = $3,\n filters = $4,\n filter_logic = $5,\n auto_offset_reset = $6,\n auto_commit = $7,\n script_path = $8,\n path = $9,\n is_flow = $10,\n edited_by = $11,\n permissioned_as = $12,\n edited_at = now(),\n server_id = NULL,\n error = NULL,\n error_handler_path = $15,\n error_handler_args = $16,\n retry = $17\n WHERE\n workspace_id = $13 AND path = $14\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"VarcharArray",
|
||||
"JsonbArray",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Bool",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Bool",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Text",
|
||||
"Text",
|
||||
"Varchar",
|
||||
"Jsonb",
|
||||
"Jsonb"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "68c19cb0e18b94870bbe81f9aab92ba37da67cd2a56834c9d1378eab7551284d"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT\n workspace_id,\n auto_invite->'instance_groups_roles' as instance_groups_roles,\n auto_invite->'instance_groups' as instance_groups_json\n FROM workspace_settings\n WHERE\n auto_invite->'instance_groups' IS NOT NULL\n AND auto_invite->'instance_groups' ? $1\n ",
|
||||
"query": "\n SELECT\n workspace_id,\n auto_invite->'instance_groups_roles' as instance_groups_roles\n FROM workspace_settings\n WHERE\n auto_invite->'instance_groups' IS NOT NULL\n AND auto_invite->'instance_groups' ? $1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -12,11 +12,6 @@
|
||||
"ordinal": 1,
|
||||
"name": "instance_groups_roles",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "instance_groups_json",
|
||||
"type_info": "Jsonb"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -26,9 +21,8 @@
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
null,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "66e2f8468ba64f22b7a7caa18639d7c833ac2ec573bd89d878b5c8b1afc74d3a"
|
||||
"hash": "7e01ef5799168c0fc2779d42ce352827e2fda6711c0a1b104ca6435ddb14b47d"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO kafka_trigger (\n workspace_id,\n path,\n kafka_resource_path,\n group_id,\n topics,\n filters,\n filter_logic,\n auto_offset_reset,\n auto_commit,\n script_path,\n is_flow,\n mode,\n edited_by,\n permissioned_as,\n edited_at,\n error_handler_path,\n error_handler_args,\n retry\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, now(), $15, $16, $17\n )\n ",
|
||||
"query": "\n INSERT INTO kafka_trigger (\n workspace_id,\n path,\n kafka_resource_path,\n group_id,\n topics,\n filters,\n auto_offset_reset,\n auto_commit,\n script_path,\n is_flow,\n mode,\n edited_by,\n permissioned_as,\n edited_at,\n error_handler_path,\n error_handler_args,\n retry\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, now(), $14, $15, $16\n )\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -12,7 +12,6 @@
|
||||
"VarcharArray",
|
||||
"JsonbArray",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Bool",
|
||||
"Varchar",
|
||||
"Bool",
|
||||
@@ -37,5 +36,5 @@
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "6a8f4ed9946bb2a3c5e90695c90b70aa2e83fcb5aa0c953febdd9bac2d95bbec"
|
||||
"hash": "a0a545fda5f3ebea0113d5daaf13358c964d9fb0f41bf2a1c834305b4d2398f2"
|
||||
}
|
||||
29
backend/.sqlx/query-a37cfc632dd37cf37c06743239b5ebc784e5da5ee25d47af187a75220d8fded7.json
generated
Normal file
29
backend/.sqlx/query-a37cfc632dd37cf37c06743239b5ebc784e5da5ee25d47af187a75220d8fded7.json
generated
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n UPDATE kafka_trigger\n SET\n kafka_resource_path = $1,\n group_id = $2,\n topics = $3,\n filters = $4,\n auto_offset_reset = $5,\n auto_commit = $6,\n script_path = $7,\n path = $8,\n is_flow = $9,\n edited_by = $10,\n permissioned_as = $11,\n edited_at = now(),\n server_id = NULL,\n error = NULL,\n error_handler_path = $14,\n error_handler_args = $15,\n retry = $16\n WHERE\n workspace_id = $12 AND path = $13\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"VarcharArray",
|
||||
"JsonbArray",
|
||||
"Varchar",
|
||||
"Bool",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Bool",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Text",
|
||||
"Text",
|
||||
"Varchar",
|
||||
"Jsonb",
|
||||
"Jsonb"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "a37cfc632dd37cf37c06743239b5ebc784e5da5ee25d47af187a75220d8fded7"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
-- No-op: this migration is a data fixup and cannot be reversed.
|
||||
@@ -0,0 +1,48 @@
|
||||
-- Pre-fix: before permissioned_as migration drops the email column, update edited_by
|
||||
-- for triggers where the user (edited_by) is not in the workspace but is a superadmin.
|
||||
-- This ensures the subsequent 20260318000000 migration stores the raw email as permissioned_as
|
||||
-- (via the `edited_by LIKE '%@%'` branch).
|
||||
-- For instances that already applied 20260318000000, this is a no-op (email column is gone);
|
||||
-- the 20260401000000 migration handles those as a fallback.
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
trigger_table TEXT;
|
||||
has_email BOOLEAN;
|
||||
BEGIN
|
||||
FOREACH trigger_table IN ARRAY ARRAY[
|
||||
'http_trigger',
|
||||
'websocket_trigger',
|
||||
'postgres_trigger',
|
||||
'mqtt_trigger',
|
||||
'kafka_trigger',
|
||||
'nats_trigger',
|
||||
'sqs_trigger',
|
||||
'gcp_trigger',
|
||||
'email_trigger'
|
||||
]
|
||||
LOOP
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = trigger_table AND column_name = 'email'
|
||||
) INTO has_email;
|
||||
|
||||
IF has_email THEN
|
||||
EXECUTE format($q$
|
||||
UPDATE %I t
|
||||
SET edited_by = t.email
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM usr u
|
||||
WHERE u.username = t.edited_by
|
||||
AND u.workspace_id = t.workspace_id
|
||||
)
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM password p
|
||||
WHERE p.email = t.email
|
||||
AND p.super_admin = true
|
||||
)
|
||||
$q$, trigger_table);
|
||||
END IF;
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
@@ -0,0 +1 @@
|
||||
-- No-op: the forward migration only fixes stale data; reverting is not meaningful.
|
||||
@@ -0,0 +1,103 @@
|
||||
-- Fix triggers/schedules where permissioned_as = 'u/{username}' but the user
|
||||
-- does not exist in the workspace's usr table. Replace with the raw email
|
||||
-- from the instance-level password table so the super-admin check succeeds.
|
||||
|
||||
UPDATE http_trigger t SET permissioned_as = p.email
|
||||
FROM password p
|
||||
WHERE t.permissioned_as LIKE 'u/%'
|
||||
AND p.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM usr u
|
||||
WHERE u.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND u.workspace_id = t.workspace_id
|
||||
);
|
||||
|
||||
UPDATE websocket_trigger t SET permissioned_as = p.email
|
||||
FROM password p
|
||||
WHERE t.permissioned_as LIKE 'u/%'
|
||||
AND p.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM usr u
|
||||
WHERE u.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND u.workspace_id = t.workspace_id
|
||||
);
|
||||
|
||||
UPDATE postgres_trigger t SET permissioned_as = p.email
|
||||
FROM password p
|
||||
WHERE t.permissioned_as LIKE 'u/%'
|
||||
AND p.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM usr u
|
||||
WHERE u.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND u.workspace_id = t.workspace_id
|
||||
);
|
||||
|
||||
UPDATE mqtt_trigger t SET permissioned_as = p.email
|
||||
FROM password p
|
||||
WHERE t.permissioned_as LIKE 'u/%'
|
||||
AND p.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM usr u
|
||||
WHERE u.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND u.workspace_id = t.workspace_id
|
||||
);
|
||||
|
||||
UPDATE kafka_trigger t SET permissioned_as = p.email
|
||||
FROM password p
|
||||
WHERE t.permissioned_as LIKE 'u/%'
|
||||
AND p.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM usr u
|
||||
WHERE u.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND u.workspace_id = t.workspace_id
|
||||
);
|
||||
|
||||
UPDATE nats_trigger t SET permissioned_as = p.email
|
||||
FROM password p
|
||||
WHERE t.permissioned_as LIKE 'u/%'
|
||||
AND p.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM usr u
|
||||
WHERE u.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND u.workspace_id = t.workspace_id
|
||||
);
|
||||
|
||||
UPDATE sqs_trigger t SET permissioned_as = p.email
|
||||
FROM password p
|
||||
WHERE t.permissioned_as LIKE 'u/%'
|
||||
AND p.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM usr u
|
||||
WHERE u.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND u.workspace_id = t.workspace_id
|
||||
);
|
||||
|
||||
UPDATE gcp_trigger t SET permissioned_as = p.email
|
||||
FROM password p
|
||||
WHERE t.permissioned_as LIKE 'u/%'
|
||||
AND p.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM usr u
|
||||
WHERE u.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND u.workspace_id = t.workspace_id
|
||||
);
|
||||
|
||||
UPDATE email_trigger t SET permissioned_as = p.email
|
||||
FROM password p
|
||||
WHERE t.permissioned_as LIKE 'u/%'
|
||||
AND p.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM usr u
|
||||
WHERE u.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND u.workspace_id = t.workspace_id
|
||||
);
|
||||
|
||||
UPDATE schedule t SET permissioned_as = p.email
|
||||
FROM password p
|
||||
WHERE t.permissioned_as LIKE 'u/%'
|
||||
AND p.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM usr u
|
||||
WHERE u.username = SUBSTRING(t.permissioned_as FROM 3)
|
||||
AND u.workspace_id = t.workspace_id
|
||||
);
|
||||
@@ -68,8 +68,20 @@ pub async fn get_email_from_permissioned_as(
|
||||
workspace_id
|
||||
)
|
||||
.fetch_optional(db)
|
||||
.await?
|
||||
.unwrap_or_else(|| format!("{}@unknown.windmill.dev", username));
|
||||
.await?;
|
||||
let email = match email {
|
||||
Some(e) => e,
|
||||
None => {
|
||||
// User not in workspace — check instance-level password table.
|
||||
// This handles super admins who can access any workspace without
|
||||
// a usr record; without the real email, the super_admin check in
|
||||
// fetch_authed_from_permissioned_as would fail.
|
||||
sqlx::query_scalar!("SELECT email FROM password WHERE username = $1", username)
|
||||
.fetch_optional(db)
|
||||
.await?
|
||||
.unwrap_or_else(|| format!("{}@unknown.windmill.dev", username))
|
||||
}
|
||||
};
|
||||
let key = (workspace_id.to_string(), username.to_string());
|
||||
EMAIL_CACHE.insert(key, (email.clone(), std::time::Instant::now()));
|
||||
Ok(email)
|
||||
|
||||
Reference in New Issue
Block a user