feat(sql): Add a domain type for URL safe IDs

This creates a new domain in SQL that constrains the characters of an ID
to the unreserved character set defined RFC 3986 Section 2.3.
pull/3251/head
Michael Gaffney 3 years ago committed by Timothy Messier
parent 647cf0d33d
commit 94f77d36b3
No known key found for this signature in database
GPG Key ID: EFD2F184F7600572

@ -16,4 +16,18 @@ begin;
comment on function wt_encode_base64_url_safe is
'Encodes binary data into URL safe base64';
-- wt_url_safe_id is a domain that constrains the characters of a value to the
-- unreserved character set defined RFC 3986 Section 2.3. The valid characters are
-- the ASCII characters in the 'a-z', 'A-Z', or '0-9' ranges plus the four ASCII
-- characters '~', '-', '.', and '_'.
--
-- See https://www.rfc-editor.org/rfc/rfc3986.html#section-2.3
create domain wt_url_safe_id as text
constraint wt_url_safe_id_can_only_contain_unreserved_characters
check (value ~ '^[a-zA-Z0-9\-~\._]+$')
constraint wt_url_safe_id_must_be_more_than_10_characters
check (length(trim(value)) > 10);
comment on domain wt_url_safe_id is
'An ID that contains only URL safe characters';
commit;

@ -0,0 +1,48 @@
-- Copyright (c) HashiCorp, Inc.
-- SPDX-License-Identifier: MPL-2.0
begin;
select plan(10);
select has_domain('wt_url_safe_id');
select domain_type_is('wt_url_safe_id', 'text');
create table test_table (
id wt_url_safe_id primary key
);
prepare insert_valid_ids as
insert into test_table
values ('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~-._'),
('__________a'), ('__________1'), ('__________~'), ('__________-'), ('__________.'), ('___________');
select lives_ok('insert_valid_ids', 'Inserting IDs with valid characters should not cause an error');
prepare insert_slash as insert into test_table values ('/0123456789');
select throws_like('insert_slash', '%"wt_url_safe_id_can_only_contain_unreserved_characters"', 'Inserting an ID with the "/" character should cause an error');
prepare insert_plus as insert into test_table values ('+0123456789');
select throws_like('insert_plus', '%"wt_url_safe_id_can_only_contain_unreserved_characters"', 'Inserting an ID with the "+" character should cause an error');
prepare insert_equals as insert into test_table values ('=0123456789');
select throws_like('insert_equals', '%"wt_url_safe_id_can_only_contain_unreserved_characters"', 'Inserting an ID with the "=" character should cause an error');
prepare insert_percent as insert into test_table values ('%0123456789');
select throws_like('insert_percent', '%"wt_url_safe_id_can_only_contain_unreserved_characters"', 'Inserting an ID with the "%" character should cause an error');
prepare insert_empty as insert into test_table values (' ');
select throws_like('insert_empty', '%"wt_url_safe_id_can_only_contain_unreserved_characters"', 'Inserting an empty ID should cause an error');
prepare update_to_invalid as
update test_table
set id = '/0123456789'
where id = '__________a';
select throws_like('update_to_invalid', '%"wt_url_safe_id_can_only_contain_unreserved_characters"', 'Changing an ID to an invalid character should cause an error');
prepare update_to_valid as
update test_table
set id = '0123456789a'
where id = '__________a';
select lives_ok('update_to_valid', 'Changing an ID to another valid ID should not cause an error');
select * from finish();
rollback;
Loading…
Cancel
Save