mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-29 16:15:51 +00:00
fix: evict every alias a superadmin principal can be spelled as
This commit is contained in:
@@ -44,19 +44,18 @@ EXECUTE FUNCTION notify_usr_email_change();
|
||||
CREATE OR REPLACE FUNCTION notify_superadmin_identity_change()
|
||||
RETURNS TRIGGER AS $$
|
||||
DECLARE
|
||||
new_name TEXT;
|
||||
old_name TEXT;
|
||||
names TEXT[] := '{}';
|
||||
BEGIN
|
||||
IF TG_OP <> 'DELETE' THEN new_name := COALESCE(NEW.username, NEW.email); END IF;
|
||||
IF TG_OP <> 'INSERT' THEN old_name := COALESCE(OLD.username, OLD.email); END IF;
|
||||
IF new_name IS NOT NULL THEN
|
||||
INSERT INTO notify_event (channel, payload)
|
||||
VALUES ('notify_user_email_change', '*:' || new_name);
|
||||
END IF;
|
||||
IF old_name IS NOT NULL AND old_name IS DISTINCT FROM new_name THEN
|
||||
INSERT INTO notify_event (channel, payload)
|
||||
VALUES ('notify_user_email_change', '*:' || old_name);
|
||||
END IF;
|
||||
-- Both columns, not `COALESCE`: `resolve_username_to_email` matches a `u/` principal against
|
||||
-- `username` OR `email`, and whichever string the caller passed is the key it cached under,
|
||||
-- so an account with a username can still hold a live entry under its address. Old and new
|
||||
-- of each, because a change to either leaves the other's entry behind.
|
||||
IF TG_OP <> 'DELETE' THEN names := names || ARRAY[NEW.username, NEW.email]; END IF;
|
||||
IF TG_OP <> 'INSERT' THEN names := names || ARRAY[OLD.username, OLD.email]; END IF;
|
||||
INSERT INTO notify_event (channel, payload)
|
||||
SELECT DISTINCT 'notify_user_email_change', '*:' || n
|
||||
FROM unnest(names) AS n
|
||||
WHERE n IS NOT NULL;
|
||||
RETURN COALESCE(NEW, OLD);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
||||
|
||||
@@ -383,22 +383,27 @@ async fn test_trigger_notify_user_email_change(db: Pool<Postgres>) {
|
||||
// A superadmin outside their workspaces resolves through `password`, which names no
|
||||
// workspace: the wildcard is the only way to reach that key. `super_admin` is half of what
|
||||
// that fallback matches on, so losing it moves the mapping just as the address does.
|
||||
for (label, stmt) in [
|
||||
for (label, stmt, expected_aliases) in [
|
||||
(
|
||||
"email change",
|
||||
"UPDATE password SET email = 'sa2@windmill.dev' WHERE email = 'test@windmill.dev'",
|
||||
// old address, new address, and the username that outlives both
|
||||
vec!["test@windmill.dev", "sa2@windmill.dev", "test-user"],
|
||||
),
|
||||
(
|
||||
"demotion",
|
||||
"UPDATE password SET super_admin = false WHERE email = 'sa2@windmill.dev'",
|
||||
vec!["sa2@windmill.dev", "test-user"],
|
||||
),
|
||||
(
|
||||
"promotion",
|
||||
"UPDATE password SET super_admin = true WHERE email = 'sa2@windmill.dev'",
|
||||
vec!["sa2@windmill.dev", "test-user"],
|
||||
),
|
||||
(
|
||||
"deletion",
|
||||
"DELETE FROM password WHERE email = 'sa2@windmill.dev'",
|
||||
vec!["sa2@windmill.dev", "test-user"],
|
||||
),
|
||||
] {
|
||||
let before_id = get_latest_event_id(&db).await.unwrap();
|
||||
@@ -410,11 +415,19 @@ async fn test_trigger_notify_user_email_change(db: Pool<Postgres>) {
|
||||
let events = poll_notify_events(&db, before_id)
|
||||
.await
|
||||
.expect("Should poll events");
|
||||
assert!(
|
||||
events.iter().any(|e| e.channel == "notify_user_email_change"
|
||||
&& e.payload.starts_with("*:")),
|
||||
"superadmin {label} should emit a workspace-wildcard eviction for that name"
|
||||
);
|
||||
// Every alias the principal can be spelled as, since `resolve_username_to_email`
|
||||
// matches a `u/` principal against the username or the address.
|
||||
let evicted: Vec<&str> = events
|
||||
.iter()
|
||||
.filter(|e| e.channel == "notify_user_email_change")
|
||||
.filter_map(|e| e.payload.strip_prefix("*:"))
|
||||
.collect();
|
||||
for alias in expected_aliases {
|
||||
assert!(
|
||||
evicted.contains(&alias),
|
||||
"superadmin {label} should evict {alias}, got {evicted:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user