Skip to content

Commit

Permalink
implement trigger to remove references to capabilities in grants, but…
Browse files Browse the repository at this point in the history
… only if that does not leave the grant without any reference at all
  • Loading branch information
leondutoit committed Jan 27, 2020
1 parent 32b3a66 commit c782a0c
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
29 changes: 27 additions & 2 deletions db_capabilities.sql
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ create table if not exists capabilities_http(
capability_group_existence_check boolean default 't',
capability_metadata jsonb
);
-- on delete remove from capability_names_allowed


drop function if exists ensure_unique_capability_groups() cascade;
Expand All @@ -70,6 +69,7 @@ create or replace function capabilities_http_immutability()
begin
assert OLD.row_id = NEW.row_id, 'row_id is immutable';
assert OLD.capability_id = NEW.capability_id, 'capability_id is immutable';
assert OLD.capability_name = NEW.capability_name, 'capability_name is immutable';
return new;
end;
$$ language plpgsql;
Expand Down Expand Up @@ -199,14 +199,39 @@ create table if not exists capabilities_http_grants(
);


drop function if exists ensure_capability_name_references_consistent() cascade;
create or replace function ensure_capability_name_references_consistent()
returns trigger as $$
declare name_references text[];
declare grant_id uuid;
declare new text[];
begin
for name_references, grant_id in
select capability_names_allowed, capability_grant_id from capabilities_http_grants
where array[OLD.capability_name] <@ capability_names_allowed loop
select array_remove(name_references, OLD.capability_name) into new;
assert cardinality(new) > 0,
'deleting the capability would leave one or more grants ' ||
'without a reference to any capability which is not allowed ' ||
'delete the grant before deleting the capability, or change the reference';
update capabilities_http_grants set capability_names_allowed = new
where capability_grant_id = grant_id;
end loop;
return old;
end;
$$ language plpgsql;
create trigger capabilities_http_consistent_name_references after delete on capabilities_http
for each row execute procedure ensure_capability_name_references_consistent();


drop function if exists ensure_correct_capability_names_allowed() cascade;
create or replace function ensure_correct_capability_names_allowed()
returns trigger as $$
begin
perform assert_array_unique(NEW.capability_names_allowed, 'capability_names_allowed');
assert NEW.capability_names_allowed <@
(select array_append(array_agg(capability_name), 'all') from capabilities_http),
'trying to reference a capability name which does not exists';
'trying to reference a capability name which does not exists: ' || NEW.capability_names_allowed::text;
return new;
end;
$$ language plpgsql;
Expand Down
3 changes: 2 additions & 1 deletion tests.sql
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ create or replace function test_capabilities_http()
capability_grant_hostname, capability_grant_namespace,
capability_grant_http_method, capability_grant_uri_pattern,
capability_grant_required_groups)
values ('{export}',
values ('{export,admin}',
'allow_get',
'api.com', 'files',
'GET', '/(.*)/admin/profile/([a-zA-Z0-9])',
Expand All @@ -762,6 +762,7 @@ create or replace function test_capabilities_http()
select capability_grant_group_remove(grid1::text, 'moderator') into ans;
assert array['self'] = (select capability_grant_required_groups from capabilities_http_grants
where capability_grant_name = 'allow_get'), 'capability_grant_group_remove issue';
-- test that deleting a capability_name automatically removes it from any references in capability_names_allowed
return true;
end;
$$ language plpgsql;
Expand Down

0 comments on commit c782a0c

Please sign in to comment.