mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-19 08:03:16 +00:00
refactor: drop the app address from the identity sweeps
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYWxvwmteVyzcWenJfbnzs
This commit is contained in:
co-authored by
Claude Opus 5
parent
673e3f26e7
commit
8deab82f56
@@ -2062,19 +2062,6 @@ async fn change_user_email(
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
|
||||
// Apps store an address next to their principal, and the synthetic
|
||||
// `group-{name}@windmill.dev` may be a real user's, so a group-owned app has to keep its
|
||||
// address when a colliding user moves: an app running in Anonymous or Publisher mode takes
|
||||
// its permissions from that pair rather than from the caller, and a half-rewritten pair
|
||||
// names two accounts. Drafts below carry the same pair and need the same guard.
|
||||
sqlx::query!(
|
||||
"UPDATE app SET policy = jsonb_set(policy, ARRAY['on_behalf_of_email'], to_jsonb($1::text)) WHERE policy->>'on_behalf_of_email' = $2 AND (policy->>'on_behalf_of' IS NULL OR policy->>'on_behalf_of' NOT LIKE 'g/%')",
|
||||
&new_email,
|
||||
&old_email
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
|
||||
// ---- permissioned_as naming the account by its address ----
|
||||
// `usr.username` is constrained to `[\w-]+`, so a workspace member is always named
|
||||
// `u/{username}` and their principals survive an address change untouched. The address form
|
||||
@@ -2103,8 +2090,9 @@ async fn change_user_email(
|
||||
|
||||
// The address these two keep beside the principal is what a worker predating
|
||||
// MIN_VERSION_SUPPORTS_ON_BEHALF_OF_PRINCIPAL reads, so it follows the account for as long
|
||||
// as one may be live. Group-owned rows are held back for the reason given above the app
|
||||
// sweep: their address is the group's, which a colliding user does not take with them.
|
||||
// as one may be live. Group-owned rows are held back: the synthetic
|
||||
// `group-{name}@windmill.dev` may be a real user's, and their address is the group's, which
|
||||
// a colliding user does not take with them — a half-rewritten pair names two accounts.
|
||||
sqlx::query!(
|
||||
"UPDATE script SET on_behalf_of_email = $1 WHERE on_behalf_of_email = $2 AND (on_behalf_of IS NULL OR on_behalf_of NOT LIKE 'g/%')",
|
||||
&new_email,
|
||||
@@ -2132,7 +2120,7 @@ async fn change_user_email(
|
||||
// Script/flow rows store only the principal, but drafts carry an address beside it and
|
||||
// `deployDraft` sends both — left stale it contradicts the principal, which resolves to the
|
||||
// new address, and the deploy is rejected. Group-owned drafts are held back for the reason
|
||||
// given above the app sweep.
|
||||
// given above the script sweep.
|
||||
sqlx::query!(
|
||||
r#"UPDATE draft SET value = to_json(jsonb_set(to_jsonb(value), ARRAY['on_behalf_of_email'], to_jsonb($1::text))) WHERE typ IN ('script', 'flow') AND value->>'on_behalf_of_email' = $2 AND (value->>'on_behalf_of' IS NULL OR value->>'on_behalf_of' NOT LIKE 'g/%')"#,
|
||||
&new_email,
|
||||
@@ -2158,19 +2146,6 @@ async fn change_user_email(
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
|
||||
// A raw-app draft persists the address the client read back too. The deploy sends it beside
|
||||
// the principal, where an address naming somebody else is rejected — and unlike a live read
|
||||
// it never refreshes on its own. Same group guard as the deployed policy above, plus the
|
||||
// `IS NULL` arm: without it the predicate is `NULL` for a draft with no principal, which is
|
||||
// neither true nor false, so those rows would be skipped.
|
||||
sqlx::query!(
|
||||
r#"UPDATE draft SET value = to_json(jsonb_set(to_jsonb(value), ARRAY['policy', 'on_behalf_of_email'], to_jsonb($1::text))) WHERE typ IN ('app', 'raw_app') AND value->'policy'->>'on_behalf_of_email' = $2 AND (value->'policy'->>'on_behalf_of' IS NULL OR value->'policy'->>'on_behalf_of' NOT LIKE 'g/%')"#,
|
||||
&new_email,
|
||||
&old_email
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
|
||||
// A folder's default rules are an ordered array, first match wins, so the rewrite has to
|
||||
// preserve their order. A rule left on the old address makes `ensure_permissioned_as_exists`
|
||||
// reject the creation of every runnable the rule matches.
|
||||
|
||||
Reference in New Issue
Block a user