diff --git a/internal/db/schema/migrations/oss/postgres/70/17_credential_history_views.up.sql b/internal/db/schema/migrations/oss/postgres/70/17_credential_history_views.up.sql new file mode 100644 index 000000000..4594fde3f --- /dev/null +++ b/internal/db/schema/migrations/oss/postgres/70/17_credential_history_views.up.sql @@ -0,0 +1,128 @@ +-- Copyright (c) HashiCorp, Inc. +-- SPDX-License-Identifier: MPL-2.0 + +begin; + +-- Static Credentials +create view credential_static_json_credential_hst_aggregate as +select + rsc.recording_id, + sjc.public_id, + sjc.name, + sjc.description, + sjc.object_hmac, + css.public_id as store_public_id, + css.project_id as store_project_id, + css.name as store_name, + css.description as store_description, + string_agg(distinct rsc.credential_purpose, '|') as purposes +from + credential_static_json_credential_hst as sjc + join recording_static_credential as rsc on sjc.history_id = rsc.credential_static_hst_id + join credential_static_store_hst as css on rsc.credential_static_store_hst_id = css.history_id +group by rsc.recording_id, css.history_id, sjc.history_id; +comment on view credential_static_json_credential_hst_aggregate is + 'credential_static_json_credential_hst_aggregate contains the json credential history data along with its store and purpose data.'; + +create view credential_static_username_password_credential_hst_aggregate as +select + rsc.recording_id, + supc.public_id, + supc.name, + supc.description, + supc.username, + supc.password_hmac, + css.public_id as store_public_id, + css.project_id as store_project_id, + css.name as store_name, + css.description as store_description, + string_agg(distinct rsc.credential_purpose, '|') as purposes +from + credential_static_username_password_credential_hst as supc + left join recording_static_credential as rsc on supc.history_id = rsc.credential_static_hst_id + join credential_static_store_hst as css on rsc.credential_static_store_hst_id = css.history_id +group by supc.history_id, rsc.recording_id, css.history_id; +comment on view credential_static_username_password_credential_hst_aggregate is + 'credential_static_username_password_credential_hst_aggregate contains the username password credential history data along with its store and purpose data.'; + +create view credential_static_ssh_private_key_credential_hst_aggregate as +select + rsc.recording_id, + sspkc.public_id, + sspkc.name, + sspkc.description, + sspkc.username, + sspkc.private_key_hmac, + sspkc.private_key_passphrase_hmac, + css.public_id as store_public_id, + css.project_id as store_project_id, + css.name as store_name, + css.description as store_description, + string_agg(distinct rsc.credential_purpose, '|') as purposes +from credential_static_ssh_private_key_credential_hst as sspkc + left join recording_static_credential as rsc on sspkc.history_id = rsc.credential_static_hst_id + join credential_static_store_hst as css on rsc.credential_static_store_hst_id = css.history_id +group by sspkc.history_id, rsc.recording_id, css.history_id; +comment on view credential_static_ssh_private_key_credential_hst_aggregate is + 'credential_static_ssh_private_key_credential_hst_aggregate contains the ssh private key credential history data along with its store and purpose data.'; + +-- Dynamic Credentials +create view credential_vault_library_hst_aggregate as +select + rdc.recording_id, + vl.public_id, + vl.name, + vl.description, + vl.vault_path, + vl.http_method, + vl.http_request_body, + vl.credential_type, + vsh.public_id as store_public_id, + vsh.project_id as store_project_id, + vsh.name as store_name, + vsh.description as store_description, + vsh.vault_address as store_vault_address, + vsh.namespace as store_namespace, + vsh.tls_server_name as store_tls_server_name, + vsh.tls_skip_verify as store_tls_skip_verify, + vsh.worker_filter as store_worker_filter, + string_agg(distinct rdc.credential_purpose, '|') as purposes +from credential_vault_library_hst as vl + left join recording_dynamic_credential as rdc on vl.history_id = rdc.credential_library_hst_id + join credential_vault_store_hst as vsh on rdc.credential_vault_store_hst_id = vsh.history_id +group by vl.history_id, rdc.recording_id, vsh.history_id; +comment on view credential_vault_library_hst_aggregate is + 'credential_vault_library_hst_aggregate contains the vault library history data along with its store and purpose data.'; + +create view credential_vault_ssh_cert_library_hst_aggregate as +select + rdc.recording_id, + vscl.public_id, + vscl.name, + vscl.description, + vscl.vault_path, + vscl.username, + vscl.key_type, + vscl.key_bits, + vscl.ttl, + vscl.critical_options, + vscl.extensions, + vscl.credential_type, + vsh.public_id as store_public_id, + vsh.project_id as store_project_id, + vsh.name as store_name, + vsh.description as store_description, + vsh.vault_address as store_vault_address, + vsh.namespace as store_namespace, + vsh.tls_server_name as store_tls_server_name, + vsh.tls_skip_verify as store_tls_skip_verify, + vsh.worker_filter as store_worker_filter, + string_agg(distinct rdc.credential_purpose, '|') as purposes +from credential_vault_ssh_cert_library_hst as vscl + left join recording_dynamic_credential as rdc on vscl.history_id = rdc.credential_library_hst_id + join credential_vault_store_hst as vsh on rdc.credential_vault_store_hst_id = vsh.history_id +group by vscl.history_id, rdc.recording_id, vsh.history_id; +comment on view credential_vault_ssh_cert_library_hst_aggregate is + 'credential_vault_ssh_cert_library_hst_aggregate contains the vault library history data along with its store and purpose data.'; + +commit; diff --git a/internal/db/sqltest/tests/recording/recording_dynamic_credentials.sql b/internal/db/sqltest/tests/recording/recording_dynamic_credentials.sql index a626d9923..d71fb10a5 100644 --- a/internal/db/sqltest/tests/recording/recording_dynamic_credentials.sql +++ b/internal/db/sqltest/tests/recording/recording_dynamic_credentials.sql @@ -2,9 +2,11 @@ -- SPDX-License-Identifier: MPL-2.0 begin; - select plan(27); + select plan(31); select has_table('recording_dynamic_credential'); + select has_view('credential_vault_library_hst_aggregate', 'view for aggregate vault library history info does not exist'); + select has_view('credential_vault_ssh_cert_library_hst_aggregate', 'view for aggregate vault ssh cert library history info does not exist'); -- tests a fk column referencing a history table -- add 5 to the plan for each time this function is called @@ -51,6 +53,30 @@ begin; select results_eq('get_target_creds', 'get_session_creds'); + prepare select_recording_vault_libraries as + select recording_id::text, public_id::text, store_public_id::text, purposes::text + from credential_vault_library_hst_aggregate + where recording_id = 'sr1_____cora' + order by public_id; + + select results_eq( + 'select_recording_vault_libraries', + $$VALUES + ('sr1_____cora', 'cvl_______g1', 'cvs__gcolors', 'brokered')$$ + ); + + prepare select_recording_vault_ssh_cert_libraries as + select recording_id::text, public_id::text, store_public_id::text, purposes::text + from credential_vault_ssh_cert_library_hst_aggregate + where recording_id = 'sr1_____cora' + order by public_id; + + select results_eq( + 'select_recording_vault_ssh_cert_libraries', + $$VALUES + ('sr1_____cora', 'cvl__ssh__g1', 'cvs__gcolors', 'injected_application')$$ + ); + select is(count(*), 2::bigint) from target_credential_library where target_id = 'tssh______cg'; diff --git a/internal/db/sqltest/tests/recording/recording_static_credentials.sql b/internal/db/sqltest/tests/recording/recording_static_credentials.sql index 0aa71dc01..5aa04c874 100644 --- a/internal/db/sqltest/tests/recording/recording_static_credentials.sql +++ b/internal/db/sqltest/tests/recording/recording_static_credentials.sql @@ -2,9 +2,12 @@ -- SPDX-License-Identifier: MPL-2.0 begin; - select plan(27); + select plan(33); select has_table('recording_static_credential'); +select has_view('credential_static_json_credential_hst_aggregate', 'view for aggregate static json credential history info does not exist'); +select has_view('credential_static_username_password_credential_hst_aggregate', 'view for aggregate static username password credential history info does not exist'); +select has_view('credential_static_ssh_private_key_credential_hst_aggregate', 'view for aggregate static ssh private key credential history info does not exist'); -- tests a fk column referencing a history table -- add 5 to the plan for each time this function is called @@ -52,6 +55,42 @@ begin; select results_eq('get_target_creds', 'get_session_creds'); + prepare select_recording_static_json_credentials as + select recording_id::text, public_id::text, store_public_id::text, purposes::text + from credential_static_json_credential_hst_aggregate + where recording_id = 'sr1_____cora' + order by public_id; + + select results_eq( + 'select_recording_static_json_credentials', + $$VALUES + ('sr1_____cora', 'csj__gcolors', 'css__gcolors', 'brokered')$$ + ); + + prepare select_recording_static_username_password_credentials as + select recording_id::text, public_id::text, store_public_id::text, purposes::text + from credential_static_username_password_credential_hst_aggregate + where recording_id = 'sr1_____cora' + order by public_id; + + select results_eq( + 'select_recording_static_username_password_credentials', + $$VALUES + ('sr1_____cora', 'csu__gcolors', 'css__gcolors', 'brokered')$$ + ); + + prepare select_recording_static_ssh_private_key_credentials as + select recording_id::text, public_id::text, store_public_id::text, purposes::text + from credential_static_ssh_private_key_credential_hst_aggregate + where recording_id = 'sr1_____cora' + order by public_id; + + select results_eq( + 'select_recording_static_ssh_private_key_credentials', + $$VALUES + ('sr1_____cora', 'cspk_gcolors', 'css__gcolors', 'injected_application')$$ + ); + select is(count(*), 3::bigint) from target_static_credential where target_id = 'tssh______cg';