feat(sql): Add static credential hst tables to session recording
This adds the `recording_static_credential` join table and a trigger that runs as an after insert on the `recording_session` table. The join table joins the `recording_session`, `credential_static_store_hst`, `credential_static_history_base`, and the `credential_purpose_enm` tables.
This commit is contained in:
1 parent
3a64fb3d58
commit
06e4e46248
3 files changed
+179
-9
No files matched your search
@@ -0,0 +1,82 @@
|
||||
-- Copyright (c) HashiCorp, Inc.
|
||||
-- SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
begin;
|
||||
|
||||
create table recording_static_credential (
|
||||
recording_id wt_public_id not null
|
||||
constraint recording_session_fk
|
||||
references recording_session (public_id)
|
||||
on delete cascade
|
||||
on update cascade,
|
||||
credential_static_store_hst_id wt_url_safe_id not null
|
||||
constraint credential_static_store_hst_fk
|
||||
references credential_static_store_hst (history_id)
|
||||
on delete restrict -- History records with session recordings cannot be deleted
|
||||
on update cascade,
|
||||
credential_static_hst_id wt_url_safe_id not null
|
||||
constraint credential_static_history_base_fk
|
||||
references credential_static_history_base (history_id)
|
||||
on delete restrict -- History records with session recordings cannot be deleted
|
||||
on update cascade,
|
||||
credential_purpose text not null
|
||||
constraint credential_purpose_fkey
|
||||
references credential_purpose_enm (name)
|
||||
on delete restrict
|
||||
on update cascade,
|
||||
primary key(recording_id, credential_static_store_hst_id, credential_static_hst_id, credential_purpose)
|
||||
);
|
||||
comment on table recording_static_credential is
|
||||
'recording_static_credential table is a join table that associates a session recording with '
|
||||
'a static credential, the static credential''s static credential store, and the credential''s purpose '
|
||||
'along with the values of those entities at the time of the recording. '
|
||||
'These values are also stored in the BSR file.';
|
||||
|
||||
create function insert_recording_static_credentials() returns trigger
|
||||
as $$
|
||||
begin
|
||||
with
|
||||
session_recording(session_id, recording_id) as (
|
||||
select session_id, public_id
|
||||
from recording_session
|
||||
where session_id = new.session_id
|
||||
),
|
||||
session_static_creds(cred_id, purpose, recording_id) as (
|
||||
select credential_static_id, credential_purpose, recording_id
|
||||
from session_credential_static
|
||||
join session_recording using (session_id)
|
||||
),
|
||||
static_cred_history(public_id, store_id, cred_hst_id, valid_range) as (
|
||||
select public_id, store_id, history_id, valid_range
|
||||
from credential_static_json_credential_hst
|
||||
union
|
||||
select public_id, store_id, history_id, valid_range
|
||||
from credential_static_ssh_private_key_credential_hst
|
||||
union
|
||||
select public_id, store_id, history_id, valid_range
|
||||
from credential_static_username_password_credential_hst
|
||||
),
|
||||
final(recording_id, cred_id, store_id, cred_hst_id, store_hst_id, cred_purpose) as (
|
||||
select ssc.recording_id, sc.public_id, sc.store_id, sc.cred_hst_id, store_hst.history_id, ssc.purpose
|
||||
from static_cred_history as sc
|
||||
join credential_static_store_hst as store_hst on sc.store_id = store_hst.public_id
|
||||
and store_hst.valid_range @> current_timestamp
|
||||
join session_static_creds as ssc on sc.public_id = ssc.cred_id
|
||||
where sc.public_id in (select cred_id from session_static_creds)
|
||||
and sc.valid_range @> current_timestamp
|
||||
)
|
||||
insert into recording_static_credential
|
||||
(recording_id, credential_static_store_hst_id, credential_static_hst_id, credential_purpose)
|
||||
select recording_id, store_hst_id, cred_hst_id, cred_purpose
|
||||
from final;
|
||||
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
comment on function insert_recording_static_credentials is
|
||||
'insert_recording_static_credentials is an after insert trigger for the recording_session table.';
|
||||
|
||||
create trigger insert_recording_static_credentials after insert on recording_session
|
||||
for each row execute procedure insert_recording_static_credentials();
|
||||
|
||||
commit;
|
||||
@@ -440,6 +440,7 @@ begin;
|
||||
('p____bcolors', 't_________cb', 'csj__bcolors', 'brokered'),
|
||||
('p____bcolors', 'tssh______cb', 'csj__bcolors', 'injected_application'),
|
||||
('p____gcolors', 'tssh______cg', 'csj__gcolors', 'brokered'),
|
||||
('p____gcolors', 'tssh______cg', 'csu__gcolors', 'brokered'),
|
||||
('p____gcolors', 'tssh______cg', 'cspk_gcolors', 'injected_application');
|
||||
|
||||
insert into target_credential_library
|
||||
@@ -449,16 +450,30 @@ begin;
|
||||
('p____bcolors', 'tssh______cb', 'vl______cvl', 'brokered');
|
||||
|
||||
insert into session
|
||||
(project_id, target_id, user_id, auth_token_id, certificate, endpoint, public_id)
|
||||
values
|
||||
('p____bcolors', 'tssh______cb', 'u______clare', 'tok____clare', 'abc'::bytea, 'ep1', 's1_____clare'),
|
||||
('p____bcolors', 't_________cb', 'u______cindy', 'tok____cindy', 'abc'::bytea, 'ep1', 's1_____cindy'),
|
||||
('p____bcolors', 't_________cb', 'u______cindy', 'tok____cindy', 'abc'::bytea, 'ep1', 's1_____ciara'),
|
||||
('p____bcolors', 't_________cb', 'u______carly', 'tok____carly', 'abc'::bytea, 'ep1', 's1_____carly'),
|
||||
('p____gcolors', 'tssh______cg', 'u_______cora', 'tok_____cora', 'abc'::bytea, 'ep1', 's1______cora'),
|
||||
(project_id, target_id, public_id, user_id, auth_token_id, certificate, endpoint)
|
||||
values
|
||||
('p____bcolors', 'tssh______cb', 's1_____clare', 'u______clare', 'tok____clare', 'abc'::bytea, 'ep1'),
|
||||
('p____bcolors', 't_________cb', 's1_____cindy', 'u______cindy', 'tok____cindy', 'abc'::bytea, 'ep1'),
|
||||
('p____bcolors', 't_________cb', 's1_____ciara', 'u______cindy', 'tok____cindy', 'abc'::bytea, 'ep1'),
|
||||
('p____bcolors', 't_________cb', 's1_____carly', 'u______carly', 'tok____carly', 'abc'::bytea, 'ep1'),
|
||||
('p____gcolors', 'tssh______cg', 's1______cora', 'u_______cora', 'tok_____cora', 'abc'::bytea, 'ep1'),
|
||||
--- the next two are used in recording_session tests
|
||||
('p____bcolors', 'tssh______cb', 'u______clare', 'tok____clare', 'abc'::bytea, 'ep1', 's2_____clare'),
|
||||
('p____gcolors', 'tssh______cg', 'u_______cora', 'tok_____cora', 'abc'::bytea, 'ep1', 's2______cora');
|
||||
('p____bcolors', 'tssh______cb', 's2_____clare', 'u______clare', 'tok____clare', 'abc'::bytea, 'ep1'),
|
||||
('p____gcolors', 'tssh______cg', 's2______cora', 'u_______cora', 'tok_____cora', 'abc'::bytea, 'ep1');
|
||||
|
||||
insert into session_credential_static
|
||||
(session_id, credential_static_id, credential_purpose)
|
||||
values
|
||||
('s1_____clare', 'csj__bcolors', 'injected_application'), -- tssh______cb
|
||||
('s2_____clare', 'csj__bcolors', 'injected_application'), -- tssh______cb
|
||||
('s1_____cindy', 'csj__bcolors', 'brokered'), -- t_________cb
|
||||
('s1_____ciara', 'csj__bcolors', 'brokered'), -- t_________cb
|
||||
('s1_____carly', 'csj__bcolors', 'brokered'), -- t_________cb
|
||||
('s1______cora', 'csj__gcolors', 'brokered'), -- tssh______cg
|
||||
('s1______cora', 'csu__gcolors', 'brokered'), -- tssh______cg
|
||||
('s1______cora', 'cspk_gcolors', 'injected_application'), -- tssh______cg
|
||||
('s2______cora', 'csj__gcolors', 'brokered'), -- tssh______cg
|
||||
('s2______cora', 'cspk_gcolors', 'injected_application'); -- tssh______cg
|
||||
|
||||
insert into session_host_set_host
|
||||
(session_id, host_set_id, host_id)
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
-- Copyright (c) HashiCorp, Inc.
|
||||
-- SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
begin;
|
||||
select plan(27);
|
||||
|
||||
select has_table('recording_static_credential');
|
||||
|
||||
-- tests a fk column referencing a history table
|
||||
-- add 5 to the plan for each time this function is called
|
||||
create function hst_fk_column(column_name name, pk_table name) returns text
|
||||
as $$
|
||||
select * from collect_tap(
|
||||
has_column('recording_static_credential', column_name),
|
||||
col_not_null('recording_static_credential', column_name),
|
||||
col_type_is('recording_static_credential', column_name, 'wt_url_safe_id'), -- should be the same type as the operational table
|
||||
col_hasnt_default('recording_static_credential', column_name),
|
||||
fk_ok('recording_static_credential', column_name, pk_table, 'history_id')
|
||||
);
|
||||
$$ language sql;
|
||||
|
||||
select hst_fk_column('credential_static_store_hst_id', 'credential_static_store_hst');
|
||||
select hst_fk_column('credential_static_hst_id', 'credential_static_history_base');
|
||||
|
||||
select has_column('recording_static_credential', 'recording_id');
|
||||
select col_not_null('recording_static_credential', 'recording_id');
|
||||
select col_type_is('recording_static_credential', 'recording_id', 'wt_public_id'); -- should be the same type as the operational table
|
||||
select col_hasnt_default('recording_static_credential', 'recording_id');
|
||||
select fk_ok('recording_static_credential', 'recording_id', 'recording_session', 'public_id');
|
||||
|
||||
select has_column('recording_static_credential', 'credential_purpose');
|
||||
select col_not_null('recording_static_credential', 'credential_purpose');
|
||||
select col_type_is('recording_static_credential', 'credential_purpose', 'text'); -- should be the same type as the operational table
|
||||
select col_hasnt_default('recording_static_credential', 'credential_purpose');
|
||||
select fk_ok('recording_static_credential', 'credential_purpose', 'credential_purpose_enm', 'name');
|
||||
|
||||
select col_is_pk('recording_static_credential',
|
||||
array['recording_id', 'credential_static_store_hst_id', 'credential_static_hst_id', 'credential_purpose']);
|
||||
-- 22
|
||||
|
||||
prepare get_target_creds as
|
||||
select credential_static_id, credential_purpose
|
||||
from target_static_credential
|
||||
where target_id = 'tssh______cg';
|
||||
|
||||
prepare get_session_creds as
|
||||
select credential_static_id, credential_purpose
|
||||
from session_credential_static
|
||||
join session on session_id = public_id
|
||||
where target_id = 'tssh______cg'
|
||||
and session_id = 's1______cora';
|
||||
|
||||
select results_eq('get_target_creds', 'get_session_creds');
|
||||
|
||||
select is(count(*), 3::bigint)
|
||||
from target_static_credential
|
||||
where target_id = 'tssh______cg';
|
||||
|
||||
select is(count(*), 3::bigint)
|
||||
from session_credential_static
|
||||
where session_id = 's1______cora';
|
||||
|
||||
select is(count(*), 1::bigint)
|
||||
from recording_session
|
||||
where session_id = 's1______cora'
|
||||
and public_id = 'sr1_____cora';
|
||||
|
||||
select is(count(*), 3::bigint)
|
||||
from recording_static_credential
|
||||
where recording_id = 'sr1_____cora';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
Reference in new issue
Block a user