Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/recogito/recogito-server
Browse files Browse the repository at this point in the history
…into develop
  • Loading branch information
dleadbetter committed Oct 16, 2024
2 parents 064079b + 4b717dd commit e4de1bf
Show file tree
Hide file tree
Showing 17 changed files with 1,545 additions and 31 deletions.
29 changes: 19 additions & 10 deletions SQL Scripts/functions/archive_context_documents_rpc.sql
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ DECLARE
_layer_id uuid;
_document_id uuid;
_row RECORD;
_layer_doc_id uuid;
BEGIN
-- Find the project for this context
SELECT p.id INTO _project_id FROM public.projects p
Expand All @@ -25,22 +26,30 @@ BEGIN
FOREACH _document_id IN ARRAY _document_ids
LOOP
-- Archive the context_documents record
UPDATE public.context_document cd
UPDATE public.context_documents cd
SET is_archived = TRUE
WHERE cd.document_id = _document_id AND cd.context_id = _context_id;

-- Archive any related layers
FOR _row IN SELECT * FROM public.layers l
INNER JOIN public.layer_contexts lc ON lc.context_id = _context_id
WHERE l.document_id = _document_id
FOR _row IN SELECT * FROM public.layer_contexts lc
WHERE lc.context_id = _context_id
LOOP
UPDATE public.layers
SET is_archived = TRUE
WHERE id = _row.id;

SELECT l.document_id INTO _layer_doc_id FROM public.layers l WHERE l.id = _row.layer_id;

IF _layer_doc_id = _document_id
THEN
IF _row.is_active_layer IS TRUE
THEN
UPDATE public.layers l
SET is_archived = TRUE
WHERE l.id = _row.layer_id;
END IF;

UPDATE public.layer_contexts lc
SET is_archived = TRUE
WHERE lc.context_id = _context_id AND lc.layer_id = _row.id;
UPDATE public.layer_contexts lc
SET is_archived = TRUE
WHERE lc.id = _row.id;
END IF;
END LOOP;

END LOOP;
Expand Down
16 changes: 9 additions & 7 deletions SQL Scripts/functions/archive_context_rpc.sql
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,19 @@ BEGIN
WHERE cd.id = _row.id;

-- Archive any related layers
FOR _row_2 IN SELECT * FROM public.layers l
INNER JOIN public.layer_contexts lc ON lc.context_id = _context_id
WHERE l.document_id = _row.document_id
FOR _row_2 IN SELECT * FROM public.layer_contexts lc
WHERE lc.context_id = _context_id
LOOP
UPDATE public.layers
SET is_archived = TRUE
WHERE id = _row_2.id;
IF _row_2.is_active_layer IS TRUE
THEN
UPDATE public.layers l
SET is_archived = TRUE
WHERE l.id = _row_2.layer_id;
END IF;

UPDATE public.layer_contexts lc
SET is_archived = TRUE
WHERE lc.context_id = _context_id AND lc.layer_id = _row_2.id;
WHERE lc.id = _row_2.id;
END LOOP;

END LOOP;
Expand Down
32 changes: 32 additions & 0 deletions SQL Scripts/functions/archive_document_rpc.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
CREATE
OR REPLACE FUNCTION archive_document_rpc (
_document_id uuid
) RETURNS BOOLEAN AS $body$
DECLARE
_row public.documents % rowtype;
BEGIN
-- Check project policy that project documents can be updated by this user
IF NOT (check_action_policy_organization(auth.uid(), 'documents', 'UPDATE'))
THEN
RETURN FALSE;
END IF;

-- Get the document
SELECT * INTO _row FROM public.documents d WHERE d.id = _document_id;

-- If the user is the creator or an Org Admin, archive the document
IF _row.created_by = auth.uid() OR is_admin_organization(auth.uid())
THEN
IF NOT EXISTS(SELECT 1 FROM public.project_documents pd WHERE pd.id = _document_id AND pd.is_archived IS FALSE )
THEN
UPDATE public.documents d
SET is_archived = TRUE
WHERE d.id = _document_id;

RETURN TRUE;
END IF;
END IF;

RETURN FALSE;
END
$body$ LANGUAGE plpgsql SECURITY DEFINER;
12 changes: 7 additions & 5 deletions SQL Scripts/functions/create_default_project_groups.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ DECLARE
_description varchar;
_is_admin bool;
_is_default bool;
_is_read_only bool;
BEGIN
FOR _role_id, _name, _description, _is_admin, _is_default IN SELECT role_id, name, description, is_admin, is_default
FROM public.default_groups
WHERE group_type = 'project'
FOR _role_id, _name, _description, _is_admin, _is_default, _is_read_only
IN SELECT role_id, name, description, is_admin, is_default, is_read_only
FROM public.default_groups
WHERE group_type = 'project'
LOOP
_project_group_id = extensions.uuid_generate_v4();
INSERT INTO public.project_groups
(id, project_id, role_id, name, description, is_admin, is_default)
VALUES (_project_group_id, NEW.id, _role_id, _name, _description, _is_admin, _is_default);
(id, project_id, role_id, name, description, is_admin, is_default, is_read_only)
VALUES (_project_group_id, NEW.id, _role_id, _name, _description, _is_admin, _is_default, _is_read_only);

IF _is_admin IS TRUE AND NEW.created_by IS NOT NULL THEN
INSERT INTO public.group_users (group_type, type_id, user_id)
Expand Down
103 changes: 103 additions & 0 deletions SQL Scripts/functions/lock_project_rpc.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
CREATE
OR REPLACE FUNCTION lock_project_rpc (
_project_id uuid
) RETURNS BOOLEAN
AS $body$
DECLARE
_project_read_only_group_id uuid;
_project_group_ids uuid[];
_project_admin_ids uuid[];
_project_group_id uuid;
_row_group_users public.group_users % rowtype;
_read_only_layer_role uuid;
_context_ids uuid[];
_context_id uuid;
_user_id uuid;
BEGIN
-- Must have Update privs on project
IF NOT (check_action_policy_organization(auth.uid(), 'projects', 'UPDATE')
OR check_action_policy_project(auth.uid(), 'projects', 'UPDATE', _project_id))
THEN
RETURN FALSE;
END IF;

-- Select the read only project default group
SELECT pg.id INTO _project_read_only_group_id
FROM public.project_groups pg
WHERE pg.project_id = _project_id
AND pg.is_read_only IS TRUE;

-- Create an array of project_group ids
_project_group_ids := ARRAY(
SELECT pg.id
FROM public.project_groups pg
WHERE pg.project_id = _project_id
AND pg.is_read_only IS NOT TRUE
);

-- Create an array of user ids
_project_admin_ids := ARRAY(
SELECT gu.user_id
FROM public.group_users gu
WHERE gu.type_id = ANY(_project_group_ids)
);

-- For each project group user, set them to read-only
FOREACH _project_group_id IN ARRAY _project_group_ids
LOOP
UPDATE public.group_users
SET type_id = _project_read_only_group_id
WHERE type_id = _project_group_id
AND group_type = 'project';
END LOOP;

-- If we do not have a read-only layer default group then fail
IF NOT EXISTS(SELECT 1 FROM public.default_groups dgx WHERE dgx.group_type = 'layer' AND dgx.is_read_only IS TRUE)
THEN
ROLLBACK;
RETURN FALSE;
END IF;

-- Get the read only role from default groups
SELECT dgx.role_id INTO _read_only_layer_role FROM public.default_groups dgx WHERE dgx.group_type = 'layer' AND dgx.is_read_only IS TRUE;

-- Get an array of context ids for this project
_context_ids := ARRAY(
SELECT c.id
FROM public.contexts c
WHERE c.project_id = _project_id
);

-- Set all context users to read-only
FOREACH _context_id IN ARRAY _context_ids
LOOP
UPDATE public.context_users
SET role_id = _read_only_layer_role
WHERE _context_id = _context_id;
END LOOP;

-- Add the admins to each context as read-only
FOREACH _context_id IN ARRAY _context_ids
LOOP
FOREACH _user_id IN ARRAY _project_admin_ids
LOOP
INSERT INTO public.context_users
(role_id, user_id, context_id)
VALUES (_read_only_layer_role, _user_id, _context_id)
ON CONFLICT(user_id, context_id)
DO NOTHING;
END LOOP;
END LOOP;

-- Set the admins to the read only project group

-- Update the project
UPDATE public.projects
SET is_locked = TRUE
WHERE id = _project_id;

-- Success
RETURN TRUE;

END
$body$ LANGUAGE plpgsql SECURITY DEFINER;
65 changes: 65 additions & 0 deletions SQL Scripts/helpful-stuff/fix-corrupted-base-layer.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
CREATE
OR REPLACE FUNCTION fix_corrupted_baselayers ()
RETURNS void
AS $body$
DECLARE
_default_ctx_id uuid;
_proj_doc_array uuid[];
_proj_row public.projects % rowtype;
_ctx_doc_row public.context_documents;
_layer_context_row public.layer_contexts % rowtype;
BEGIN
-- This script fixes corrupted baselayers using the following steps
-- 1. Iterate through all projects
FOR _proj_row IN SELECT * FROM public.projects p
LOOP
-- 2. For each project get the default context
SELECT c.id INTO _default_ctx_id FROM public.contexts c
WHERE c.project_id = _proj_row.id
AND c.is_project_default IS TRUE
AND c.is_archived IS NOT TRUE;

-- 3. Create an array of project_document ids
_proj_doc_array := ARRAY(SELECT pd.document_id FROM public.project_documents pd WHERE pd.project_id = _proj_row.id AND pd.is_archived IS NOT TRUE);
RAISE LOG 'Doc Array for project %: %', _proj_row.id, _proj_doc_array;

-- 4. Archive any context documents that reference documents not in the project_documents array

IF EXISTS(
SELECT 1 a
FROM public.context_documents cd
WHERE cd.context_id = _default_ctx_id
AND cd.is_archived IS NOT TRUE
AND NOT (cd.document_id = ANY(_proj_doc_array)))
THEN
FOR _ctx_doc_row IN SELECT *
FROM public.context_documents cd
WHERE cd.context_id = _default_ctx_id
AND cd.is_archived IS NOT TRUE
AND NOT (cd.document_id = ANY(_proj_doc_array))
LOOP
UPDATE public.context_documents cd
SET is_archived = TRUE
WHERE cd.id = _ctx_doc_row.id;

-- 5. Archive any layer contexts and layers associated with these documents
FOR _layer_context_row IN SELECT *
FROM public.layer_contexts lc
INNER JOIN public.layers l ON l.project_id = _proj_row.id
AND (l.document_id = _ctx_doc_row.document_id OR NOT (l.document_id = ANY(_proj_doc_array)))
AND l.is_archived IS NOT TRUE
WHERE lc.layer_id = l.id AND lc.context_id = _default_ctx_id
LOOP
UPDATE public.layer_contexts lc
SET is_archived = TRUE
WHERE lc.id = _layer_context_row.id;

UPDATE public.layers l
SET is_archived = TRUE
WHERE l.id = _layer_context_row.layer_id;
END LOOP;
END LOOP;
END IF;
END LOOP;
END;
$body$ LANGUAGE plpgsql SECURITY DEFINER;
7 changes: 6 additions & 1 deletion SQL Scripts/tables/default_groups.sql
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ CREATE TABLE public.default_groups
description varchar NOT NULL,
role_id uuid REFERENCES public.roles NOT NULL,
is_admin bool DEFAULT FALSE,
is_default bool DEFAULT FALSE
is_default bool DEFAULT FALSE,
is_read_only bool DEFAULT FALSE
);

-- Changes 6/6/23 --
Expand All @@ -25,3 +26,7 @@ ALTER TABLE public.default_groups
-- Changes 7/26/23 --
ALTER TABLE public.default_groups
ADD COLUMN is_archived bool DEFAULT FALSE;

-- Changes 9/20/24 --
ALTER TABLE public.default_groups
ADD COLUMN is_read_only bool DEFAULT FALSE;
8 changes: 7 additions & 1 deletion SQL Scripts/tables/layer_groups.sql
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ CREATE TABLE PUBLIC.LAYER_GROUPS (
DESCRIPTION VARCHAR,
ROLE_ID UUID REFERENCES PUBLIC.ROLES NOT NULL,
IS_ADMIN BOOL DEFAULT FALSE,
IS_DEFAULT BOOLEAN DEFAULT FALSE
IS_DEFAULT BOOLEAN DEFAULT FALSE,
IS_READ_ONLY BOOLEAN DEFAULT FALSE
);

-- Changes 05/01/23 ---
Expand Down Expand Up @@ -67,3 +68,8 @@ ADD COLUMN IS_ADMIN BOOL DEFAULT FALSE;
-- Changes 11/30/23 --
ALTER TABLE PUBLIC.LAYER_GROUPS
ADD COLUMN IS_DEFAULT BOOLEAN DEFAULT FALSE;

-- Changes 9/20/24 --
ALTER TABLE PUBLIC.LAYER_GROUPS
ADD COLUMN is_read_only BOOLEAN DEFAULT FALSE;

9 changes: 7 additions & 2 deletions SQL Scripts/tables/organization_groups.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ CREATE TABLE public .organization_groups (
description VARCHAR,
role_id UUID REFERENCES public .roles UNIQUE NOT NULL,
is_admin BOOLEAN DEFAULT FALSE,
is_default BOOLEAN DEFAULT FALSE
is_default BOOLEAN DEFAULT FALSE,
is_read_only BOOLEAN DEFAULT FALSE
);
-- Changes 05/08/23
ALTER TABLE public .organization_groups
Expand Down Expand Up @@ -39,4 +40,8 @@ ALTER TABLE public .organization_groups
ADD COLUMN is_admin bool DEFAULT FALSE;
-- Changes 11/27/23 --
ALTER TABLE public .organization_groups
ADD COLUMN is_default bool DEFAULT FALSE;
ADD COLUMN is_default bool DEFAULT FALSE;

-- Changes 9/23/24 --
ALTER TABLE public.organization_groups
ADD COLUMN is_read_only bool DEFAULT FALSE;
9 changes: 7 additions & 2 deletions SQL Scripts/tables/project_groups.sql
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ CREATE TABLE PUBLIC.PROJECT_GROUPS (
DESCRIPTION VARCHAR,
ROLE_ID UUID REFERENCES PUBLIC.ROLES NOT NULL,
IS_ADMIN BOOL DEFAULT FALSE,
IS_DEFAULT BOOLEAN DEFAULT FALSE
IS_DEFAULT BOOLEAN DEFAULT FALSE,
IS_READ_ONLY BOOLEAN DEFAULT FALSE
);

-- Changes 05/08/23
Expand Down Expand Up @@ -53,4 +54,8 @@ ADD COLUMN IS_ADMIN BOOL DEFAULT FALSE;

-- Changes 11/30/23 --
ALTER TABLE PUBLIC.PROJECT_GROUPS
ADD COLUMN IS_DEFAULT BOOLEAN DEFAULT FALSE;
ADD COLUMN IS_DEFAULT BOOLEAN DEFAULT FALSE;

-- Changed 9/20/24
ALTER TABLE public.project_groups
ADD COLUMN is_read_only BOOLEAN DEFAULT FALSE;
Loading

0 comments on commit e4de1bf

Please sign in to comment.