67 lines
3.4 KiB
SQL
67 lines
3.4 KiB
SQL
-- Split review and delivery without changing identities, memberships or owners.
|
|||
|
|
CREATE TABLE IF NOT EXISTS workbench_content_permission_migrations (
|
||
|
|
version integer PRIMARY KEY,
|
||
|
|
changes jsonb NOT NULL,
|
||
|
|
created_at timestamptz NOT NULL DEFAULT now()
|
||
|
|
);
|
||
|
|
|
||
|
|
DO $migration$
|
||
|
|
DECLARE r record; saved jsonb; before_permissions jsonb; next_permissions jsonb;
|
||
|
|
mapped_permissions jsonb; source_permissions jsonb; changes jsonb := '[]'::jsonb;
|
||
|
|
restored boolean;
|
||
|
|
BEGIN
|
||
|
|
PERFORM pg_advisory_xact_lock(207, 11905);
|
||
|
|
IF EXISTS(SELECT 1 FROM workbench_content_permission_migrations WHERE version=207) THEN RETURN; END IF;
|
||
|
|
LOCK TABLE workbench_access_roles IN SHARE ROW EXCLUSIVE MODE;
|
||
|
|
FOR r IN SELECT * FROM workbench_access_roles ORDER BY tenant_id,id LOOP
|
||
|
|
saved := NULL;
|
||
|
|
IF to_regclass('yawan_legacy_access_mappings') IS NOT NULL THEN
|
||
|
|
EXECUTE 'SELECT source_spec FROM yawan_legacy_access_mappings
|
||
|
|
WHERE source_system=$1 AND target_tenant_id=$2 AND entity_key LIKE ''role/%''
|
||
|
|
AND source_spec->>''id''=$3'
|
||
|
|
INTO saved USING 'yawan-workbench',r.tenant_id,r.id;
|
||
|
|
END IF;
|
||
|
|
before_permissions := r.permissions;
|
||
|
|
-- Before this split, readers could export and producers could approve/review.
|
||
|
|
SELECT coalesce(jsonb_agg(p ORDER BY p),'[]'::jsonb) INTO next_permissions FROM (
|
||
|
|
SELECT DISTINCT p FROM (
|
||
|
|
SELECT jsonb_array_elements_text(r.permissions) AS p
|
||
|
|
UNION ALL SELECT 'content.review' WHERE r.permissions ? 'content.write'
|
||
|
|
UNION ALL SELECT 'content.deliver' WHERE r.permissions ? 'content.read'
|
||
|
|
) existing
|
||
|
|
) permissions;
|
||
|
|
mapped_permissions := NULL;
|
||
|
|
restored := false;
|
||
|
|
IF saved IS NOT NULL THEN
|
||
|
|
source_permissions := saved->'source_permissions';
|
||
|
|
SELECT coalesce(jsonb_agg(p ORDER BY p),'[]'::jsonb) INTO mapped_permissions
|
||
|
|
FROM jsonb_array_elements_text(saved->'permissions') p WHERE p NOT LIKE 'content.%';
|
||
|
|
-- Legacy task GETs required tasks:review; generic read alone granted no task access.
|
||
|
|
IF source_permissions ? 'tasks:review' OR source_permissions ? 'review' THEN
|
||
|
|
mapped_permissions := mapped_permissions || '["content.read","content.review"]'::jsonb;
|
||
|
|
IF source_permissions ? 'tasks:write' OR source_permissions ? 'content:write' THEN
|
||
|
|
mapped_permissions := mapped_permissions || '"content.write"'::jsonb;
|
||
|
|
END IF;
|
||
|
|
IF source_permissions ? 'tasks:deliver' OR source_permissions ? 'content:write' THEN
|
||
|
|
mapped_permissions := mapped_permissions || '"content.deliver"'::jsonb;
|
||
|
|
END IF;
|
||
|
|
END IF;
|
||
|
|
SELECT coalesce(jsonb_agg(p ORDER BY p),'[]'::jsonb) INTO mapped_permissions
|
||
|
|
FROM jsonb_array_elements_text(mapped_permissions) p;
|
||
|
|
-- An edited imported role keeps its current native policy.
|
||
|
|
IF r.version=1 AND r.name=saved->>'name' AND r.permissions=saved->'permissions' THEN
|
||
|
|
next_permissions := mapped_permissions;
|
||
|
|
restored := true;
|
||
|
|
END IF;
|
||
|
|
END IF;
|
||
|
|
IF next_permissions IS DISTINCT FROM before_permissions THEN
|
||
|
|
UPDATE workbench_access_roles SET permissions=next_permissions,version=version+1,updated_at=now()
|
||
|
|
WHERE id=r.id AND tenant_id=r.tenant_id;
|
||
|
|
END IF;
|
||
|
|
changes := changes || jsonb_build_array(jsonb_build_object(
|
||
|
|
'role_id',r.id,'tenant_id',r.tenant_id,'before',before_permissions,'after',next_permissions,
|
||
|
|
'legacy_source_spec',saved,'mapped_permissions',mapped_permissions,'legacy_restored',restored));
|
||
|
|
END LOOP;
|
||
|
|
INSERT INTO workbench_content_permission_migrations(version,changes) VALUES(207,changes);
|
||
|
|
END $migration$;
|