1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-02 00:22:50 -05:00

[AC-1682] Postgres migrations

This commit is contained in:
Rui Tome
2023-12-20 11:57:36 +00:00
parent c5f1be4d79
commit 86ba89f230
9 changed files with 4752 additions and 63 deletions

View File

@ -1,10 +1,10 @@
-- Create a temporary table to store the groups with AccessAll = true
CREATE TEMPORARY TABLE TempGroup AS
-- Step 1: Create a temporary table to store the groups with AccessAll = 1
CREATE TEMP TABLE IF NOT EXISTS TempGroup AS
SELECT "Id" AS "GroupId", "OrganizationId"
FROM "Group"
WHERE "AccessAll" = true;
-- Update existing rows in "CollectionGroups"
-- Step 2: Update existing rows in "CollectionGroup"
UPDATE "CollectionGroups" CG
SET
"ReadOnly" = false,
@ -12,16 +12,16 @@ SET
"Manage" = false
FROM "CollectionGroups" CGUpdate
INNER JOIN "Collection" C ON CGUpdate."CollectionId" = C."Id"
INNER JOIN TempGroup TG ON CGUpdate."GroupId" = TG."GroupId"
INNER JOIN TempGroup TG ON CGUpdate."GroupId" = TG."GroupId"
WHERE C."OrganizationId" = TG."OrganizationId";
-- Insert new rows into "CollectionGroups"
-- Step 3: Insert new rows into "CollectionGroup"
INSERT INTO "CollectionGroups" ("CollectionId", "GroupId", "ReadOnly", "HidePasswords", "Manage")
SELECT C."Id", TG."GroupId", false, false, false
FROM "Collection" C
INNER JOIN TempGroup TG ON C."OrganizationId" = TG."OrganizationId"
LEFT JOIN "CollectionGroups" CG ON CG."CollectionId" = C."Id" AND CG."GroupId" = TG."GroupId"
INNER JOIN TempGroup TG ON C."OrganizationId" = TG."OrganizationId"
LEFT JOIN "CollectionGroups" CG ON CG."CollectionId" = C."Id" AND CG."GroupId" = TG."GroupId"
WHERE CG."CollectionId" IS NULL;
-- Drop the temporary table
-- Step 4: Drop the temporary table
DROP TABLE IF EXISTS TempGroup;

View File

@ -1,51 +1,22 @@
-- Step 1: Insert into a temporary table with an additional column for batch processing, update 50 k at a time
CREATE TEMPORARY TABLE "TempOrgUser" AS
SELECT "Id" AS "OrganizationUserId", "OrganizationId", CAST(ROW_NUMBER() OVER(ORDER BY "Id") / 50000 AS INT) AS "Batch"
FROM "OrganizationUser"
WHERE "AccessAll" = true;
-- Step 2: Get the maximum batch number
DO $$
DECLARE
MaxBatch INT;
CurrentBatch INT := 0;
BEGIN
SELECT MAX("Batch") INTO MaxBatch FROM "TempOrgUser";
-- Step 3: Process each batch
WHILE CurrentBatch <= MaxBatch LOOP
-- Update existing rows in "CollectionUsers"
UPDATE "CollectionUsers" AS target
-- Update existing rows in CollectionUsers
UPDATE "CollectionUsers"
SET
"ReadOnly" = false,
"HidePasswords" = false,
"Manage" = false
FROM (
SELECT "C"."Id" AS "CollectionId", "T"."OrganizationUserId"
FROM "Collection" "C"
INNER JOIN "TempOrgUser" "T" ON "C"."OrganizationId" = "T"."OrganizationId" AND "T"."Batch" = CurrentBatch
) AS source
WHERE target."CollectionId" = source."CollectionId" AND target."OrganizationUserId" = source."OrganizationUserId";
FROM "Collection" AS C
INNER JOIN "CollectionUsers" AS CU ON CU."CollectionId" = C."Id"
INNER JOIN "OrganizationUser" AS OU ON CU."CollectionId" = C."Id" AND C."OrganizationId" = OU."OrganizationId"
WHERE OU."AccessAll" = true;
-- Insert new rows into "CollectionUsers"
-- Insert new rows into CollectionUsers
INSERT INTO "CollectionUsers" ("CollectionId", "OrganizationUserId", "ReadOnly", "HidePasswords", "Manage")
SELECT source."CollectionId", source."OrganizationUserId", false, false, false
FROM (
SELECT "C"."Id" AS "CollectionId", "T"."OrganizationUserId"
FROM "Collection" "C"
INNER JOIN "TempOrgUser" "T" ON "C"."OrganizationId" = "T"."OrganizationId" AND "T"."Batch" = CurrentBatch
) AS source
WHERE NOT EXISTS (
SELECT C."Id" AS "CollectionId", OU."Id" AS "OrganizationUserId", false, false, false
FROM "Collection" AS C
INNER JOIN "OrganizationUser" AS OU ON C."OrganizationId" = OU."OrganizationId"
WHERE OU."AccessAll" = true
AND NOT EXISTS (
SELECT 1
FROM "CollectionUsers" target
WHERE target."CollectionId" = source."CollectionId" AND target."OrganizationUserId" = source."OrganizationUserId"
FROM "CollectionUsers" AS CU
WHERE CU."CollectionId" = C."Id" AND CU."OrganizationUserId" = OU."Id"
);
-- Move to the next batch
CurrentBatch := CurrentBatch + 1;
END LOOP;
END $$;
-- Step 4: Drop the temporary table
DROP TABLE "TempOrgUser";

View File

@ -1,10 +1,24 @@
-- Update "CollectionUser" with "Manage" = 1 for all users with Manager role or 'EditAssignedCollections' permission
-- Update `CollectionUsers` with `Manage` = 1 for all users with Manager role or 'EditAssignedCollections' permission
UPDATE "CollectionUsers" cu
SET "ReadOnly" = false,
SET
"ReadOnly" = false,
"HidePasswords" = false,
"Manage" = true
FROM "OrganizationUser" ou
FROM "OrganizationUser" ou
WHERE cu."OrganizationUserId" = ou."Id"
AND (ou."Type" = 3 OR
AND (ou."Type" = 3 OR
(ou."Permissions" IS NOT NULL AND
(ou."Permissions"::text)::jsonb->>'editAssignedCollections' = 'true'));
((ou."Permissions"::text)::jsonb->>'editAssignedCollections') = 'true'));
-- Insert rows into CollectionUsers for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access
INSERT INTO "CollectionUsers" ("CollectionId", "OrganizationUserId", "ReadOnly", "HidePasswords", "Manage")
SELECT cg."CollectionId", ou."Id", false, false, true
FROM "CollectionGroups" cg
INNER JOIN "GroupUser" gu ON cg."GroupId" = gu."GroupId"
INNER JOIN "OrganizationUser" ou ON gu."OrganizationUserId" = ou."Id"
WHERE (ou."Type" = 3 OR
(ou."Permissions" IS NOT NULL AND
((ou."Permissions"::text)::jsonb->>'editAssignedCollections') = 'true'))
AND NOT EXISTS (
SELECT 1 FROM "CollectionUsers" cu
WHERE cu."CollectionId" = cg."CollectionId" AND cu."OrganizationUserId" = ou."Id");