fix(coderd): ensure that user API keys are deleted when a user is (#7270)

Fixes an issue where API tokens belonging to a deleted user were
not invalidated:
- Adds a trigger to delete rows from the api_key stable when the
  column deleted is set to true in the users table.
- Adds a trigger to the api_keys table to ensure that new rows
  may not be added where user_id corresponds to a deleted user.
- Adds a migration to delete all API keys from deleted users.
- Adds tests + dbfake implementation for the above.
This commit is contained in:
Cian Johnston
2023-04-24 21:48:26 +01:00
committed by GitHub
parent ad82a60806
commit 8fc8559076
7 changed files with 165 additions and 2 deletions

View File

@ -129,6 +129,34 @@ CREATE TYPE workspace_transition AS ENUM (
'delete'
);
CREATE FUNCTION delete_deleted_user_api_keys() RETURNS trigger
LANGUAGE plpgsql
AS $$
DECLARE
BEGIN
IF (NEW.deleted) THEN
DELETE FROM api_keys
WHERE user_id = OLD.id;
END IF;
RETURN NEW;
END;
$$;
CREATE FUNCTION insert_apikey_fail_if_user_deleted() RETURNS trigger
LANGUAGE plpgsql
AS $$
DECLARE
BEGIN
IF (NEW.user_id IS NOT NULL) THEN
IF (SELECT deleted FROM users WHERE id = NEW.user_id LIMIT 1) THEN
RAISE EXCEPTION 'Cannot create API key for deleted user';
END IF;
END IF;
RETURN NEW;
END;
$$;
CREATE TABLE api_keys (
id text NOT NULL,
hashed_secret bytea NOT NULL,
@ -895,6 +923,10 @@ CREATE INDEX workspace_resources_job_id_idx ON workspace_resources USING btree (
CREATE UNIQUE INDEX workspaces_owner_id_lower_idx ON workspaces USING btree (owner_id, lower((name)::text)) WHERE (deleted = false);
CREATE TRIGGER trigger_insert_apikeys BEFORE INSERT ON api_keys FOR EACH ROW EXECUTE FUNCTION insert_apikey_fail_if_user_deleted();
CREATE TRIGGER trigger_update_users AFTER INSERT OR UPDATE ON users FOR EACH ROW WHEN ((new.deleted = true)) EXECUTE FUNCTION delete_deleted_user_api_keys();
ALTER TABLE ONLY api_keys
ADD CONSTRAINT api_keys_user_id_uuid_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;