chore: implement databased backend for custom roles (#13295)

Includes db schema and dbauthz layer for upserting custom roles. Unit test in `customroles_test.go` verify against escalating permissions through this feature.
This commit is contained in:
Steven Masley
2024-05-16 13:11:26 -05:00
committed by GitHub
parent 194be12133
commit cf91eff7cf
21 changed files with 854 additions and 19 deletions

View File

@ -0,0 +1,2 @@
DROP INDEX IF EXISTS idx_custom_roles_name_lower;
DROP TABLE IF EXISTS custom_roles;

View File

@ -0,0 +1,26 @@
CREATE TABLE custom_roles (
-- name is globally unique. Org scoped roles have their orgid appended
-- like: "name":"organization-admin:bbe8c156-c61e-4d36-b91e-697c6b1477e8"
name text primary key,
-- display_name is the actual name of the role displayed to the user.
display_name text NOT NULL,
-- Unfortunately these values are schemaless json documents.
-- If there was a permission table for these, that would involve
-- many necessary joins to accomplish this simple json.
-- site_permissions is '[]Permission'
site_permissions jsonb NOT NULL default '[]',
-- org_permissions is 'map[<org_id>][]Permission'
org_permissions jsonb NOT NULL default '{}',
-- user_permissions is '[]Permission'
user_permissions jsonb NOT NULL default '[]',
-- extra convenience meta data.
created_at timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- Ensure no case variants of the same roles
CREATE UNIQUE INDEX idx_custom_roles_name_lower ON custom_roles USING btree (lower(name));
COMMENT ON TABLE custom_roles IS 'Custom roles allow dynamic roles expanded at runtime';

View File

@ -0,0 +1,20 @@
INSERT INTO
custom_roles (
name,
display_name,
site_permissions,
org_permissions,
user_permissions,
created_at,
updated_at
)
VALUES
(
'custom-role',
'Custom Role',
'[{"negate":false,"resource_type":"deployment_config","action":"update"},{"negate":false,"resource_type":"workspace","action":"read"}]',
'{}',
'[{"negate":false,"resource_type":"workspace","action":"read"}]',
date_trunc('hour', NOW()),
date_trunc('hour', NOW()) + '30 minute'::interval
);