mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-21 16:03:26 +00:00
fix: keep an oauth account's creator in step with the user's username
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6e93305e8c
commit
9303ddd50f
@@ -0,0 +1,2 @@
|
||||
DROP TRIGGER IF EXISTS account_created_by_follows_user_trigger ON usr;
|
||||
DROP FUNCTION IF EXISTS account_created_by_follows_user();
|
||||
@@ -0,0 +1,21 @@
|
||||
-- `account.created_by` grants the right to link the account to a variable, so it must name the
|
||||
-- same person for as long as it is set: follow the user through a rename, and clear it when the
|
||||
-- user leaves the workspace, so a later member given the same username does not inherit it.
|
||||
-- A trigger rather than application code, because users are removed from several code paths.
|
||||
CREATE OR REPLACE FUNCTION account_created_by_follows_user() RETURNS trigger AS $$
|
||||
BEGIN
|
||||
IF TG_OP = 'DELETE' THEN
|
||||
UPDATE account SET created_by = NULL
|
||||
WHERE workspace_id = OLD.workspace_id AND created_by = OLD.username;
|
||||
ELSIF NEW.username IS DISTINCT FROM OLD.username THEN
|
||||
UPDATE account SET created_by = NEW.username
|
||||
WHERE workspace_id = OLD.workspace_id AND created_by = OLD.username;
|
||||
END IF;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER account_created_by_follows_user_trigger
|
||||
AFTER UPDATE OF username OR DELETE ON usr
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION account_created_by_follows_user();
|
||||
@@ -454,3 +454,33 @@ async fn test_oauth_account_link_requires_ownership(db: Pool<Postgres>) -> anyho
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The creator recorded on an OAuth account follows the user through a rename and is cleared
|
||||
/// when they leave, so a later member reusing the username cannot link the account.
|
||||
#[sqlx::test(migrations = "../migrations", fixtures("base", "permissions_test"))]
|
||||
async fn test_oauth_account_creator_follows_user(db: Pool<Postgres>) -> anyhow::Result<()> {
|
||||
let account: i32 = sqlx::query_scalar(
|
||||
"INSERT INTO account (workspace_id, client, expires_at, refresh_token, created_by)
|
||||
VALUES ('test-workspace', 'github', now(), 'r', 'alice') RETURNING id",
|
||||
)
|
||||
.fetch_one(&db)
|
||||
.await?;
|
||||
let creator = || async {
|
||||
sqlx::query_scalar::<_, Option<String>>("SELECT created_by FROM account WHERE id = $1")
|
||||
.bind(account)
|
||||
.fetch_one(&db)
|
||||
.await
|
||||
};
|
||||
|
||||
sqlx::query("UPDATE usr SET username = 'alice2' WHERE username = 'alice'")
|
||||
.execute(&db)
|
||||
.await?;
|
||||
assert_eq!(creator().await?.as_deref(), Some("alice2"));
|
||||
|
||||
sqlx::query("DELETE FROM usr WHERE username = 'alice2'")
|
||||
.execute(&db)
|
||||
.await?;
|
||||
assert_eq!(creator().await?, None);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user