mirror of
https://github.com/coder/coder.git
synced 2025-07-08 11:39:50 +00:00
- As part of merging support for Template RBAC and user groups a permission check on reading files was relaxed. With the addition of admin roles on individual templates, regular users are now able to push template versions if they have inherited the 'admin' role for a template. In order to do so they need to be able to create and read their own files. Since collisions on hash in the past were ignored, this means that a regular user who pushes a template version with a file hash that collides with an existing hash will not be able to read the file (since it belongs to another user). This commit fixes the underlying problem which was that the files table had a primary key on the 'hash' column. This was not a problem at the time because only template admins and other users with similar elevated roles were able to read all files regardless of ownership. To fix this a new column and primary key 'id' has been introduced to the files table. The unique constraint has been updated to be hash+created_by. Tables (provisioner_jobs) that referenced files.hash have been updated to reference files.id. Relevant API endpoints have also been updated.
42 lines
1.1 KiB
PL/PgSQL
42 lines
1.1 KiB
PL/PgSQL
BEGIN;
|
|
|
|
-- Add back the storage_source column. This must be nullable temporarily.
|
|
ALTER TABLE provisioner_jobs ADD COLUMN storage_source text;
|
|
|
|
-- Set the storage_source to the hash of the files.id reference.
|
|
UPDATE
|
|
provisioner_jobs
|
|
SET
|
|
storage_source=files.hash
|
|
FROM
|
|
files
|
|
WHERE
|
|
provisioner_jobs.file_id = files.id;
|
|
|
|
-- Now that we've populated storage_source drop the file_id column.
|
|
ALTER TABLE provisioner_jobs DROP COLUMN file_id;
|
|
-- We can set the storage_source column as NOT NULL now.
|
|
ALTER TABLE provisioner_jobs ALTER COLUMN storage_source SET NOT NULL;
|
|
|
|
-- Delete all the duplicate rows where hashes collide.
|
|
-- We filter on 'id' to ensure only 1 unique row.
|
|
DELETE FROM
|
|
files a
|
|
USING
|
|
files b
|
|
WHERE
|
|
a.created_by < b.created_by
|
|
AND
|
|
a.hash = b.hash;
|
|
|
|
-- Drop the primary key on files.id.
|
|
ALTER TABLE files DROP CONSTRAINT files_pkey;
|
|
-- Drop the id column.
|
|
ALTER TABLE files DROP COLUMN id;
|
|
-- Drop the unique constraint on hash + owner.
|
|
ALTER TABLE files DROP CONSTRAINT files_hash_created_by_key;
|
|
-- Set the primary key back to hash.
|
|
ALTER TABLE files ADD PRIMARY KEY (hash);
|
|
|
|
COMMIT;
|