Skip to content

Commit

Permalink
Merge pull request #34 from recogito/lwj/locked-projects
Browse files Browse the repository at this point in the history
Implements server side of project locking
  • Loading branch information
lwjameson authored Oct 4, 2024
2 parents e85b574 + 154f441 commit 4b717dd
Show file tree
Hide file tree
Showing 10 changed files with 1,263 additions and 14 deletions.
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;
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;
9 changes: 7 additions & 2 deletions SQL Scripts/tables/projects.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ CREATE TABLE
NAME VARCHAR,
description VARCHAR,
is_open_join BOOLEAN DEFAULT FALSE,
is_open_edit BOOLEAN DEFAULT FALSE
is_open_edit BOOLEAN DEFAULT FALSE,
is_locked BOOLEAN DEFAULT FALSE
);

-- Changes 04/21/23 --
Expand All @@ -33,4 +34,8 @@ ALTER TABLE public.projects
ADD COLUMN is_open_join BOOLEAN DEFAULT FALSE;

ALTER TABLE public.projects
ADD COLUMN is_open_edit BOOLEAN DEFAULT FALSE;
ADD COLUMN is_open_edit BOOLEAN DEFAULT FALSE;

-- Changes 9/20/24
ALTER TABLE public.projects
ADD COLUMN is_locked BOOLEAN DEFAULT FALSE;
963 changes: 962 additions & 1 deletion config.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions create-default-groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const main = async (options) => {
description: orgGroup.description,
is_admin: orgGroup.is_admin,
is_default: orgGroup.is_default,
is_read_only: orgGroup.is_read_only
});
});

Expand All @@ -105,6 +106,8 @@ const main = async (options) => {
(g) => g.is_admin === true
);

console.log('Org group: ', orgAdminGroup)

const getOrgAdminResponse = await supabase
.from('organization_groups')
.select()
Expand Down Expand Up @@ -195,6 +198,7 @@ const main = async (options) => {
role_id: group.role_id,
is_admin: group.is_admin,
is_default: group.is_default,
is_read_only: group.is_read_only
});
});
config.layer_groups.forEach((group) => {
Expand All @@ -206,6 +210,7 @@ const main = async (options) => {
role_id: group.role_id,
is_admin: group.is_admin,
is_default: group.is_default,
is_read_only: group.is_read_only
});
});

Expand Down
Loading

0 comments on commit 4b717dd

Please sign in to comment.