diff --git a/internal/db/schema/migrations/oss/postgres/0/01_domain_types.up.sql b/internal/db/schema/migrations/oss/postgres/0/01_domain_types.up.sql index e637b9426e..aebc3b375a 100644 --- a/internal/db/schema/migrations/oss/postgres/0/01_domain_types.up.sql +++ b/internal/db/schema/migrations/oss/postgres/0/01_domain_types.up.sql @@ -18,7 +18,7 @@ create domain wt_scope_id as text check( length(trim(value)) > 10 or value = 'global' ); --- Comment fixed in 57/01_fix_comments.up.sql +-- Comment fixed in 58/01_fix_comments.up.sql comment on domain wt_scope_id is '"global" or random ID generated with github.com/hashicorp/go-secure-stdlib/base62'; @@ -26,7 +26,7 @@ create domain wt_user_id as text not null check( length(trim(value)) > 10 or value = 'u_anon' or value = 'u_auth' or value = 'u_recovery' ); --- Comment fixed in 57/01_fix_comments.up.sql +-- Comment fixed in 58/01_fix_comments.up.sql comment on domain wt_scope_id is '"u_anon", "u_auth", or random ID generated with github.com/hashicorp/go-secure-stdlib/base62'; @@ -34,7 +34,7 @@ create domain wt_role_id as text not null check( length(trim(value)) > 10 ); --- Comment fixed in 57/01_fix_comments.up.sql +-- Comment fixed in 58/01_fix_comments.up.sql comment on domain wt_scope_id is 'Random ID generated with github.com/hashicorp/go-secure-stdlib/base62'; diff --git a/internal/db/schema/migrations/oss/postgres/0/11_auth_token.up.sql b/internal/db/schema/migrations/oss/postgres/0/11_auth_token.up.sql index 09bdedd035..9ba9a20f34 100644 --- a/internal/db/schema/migrations/oss/postgres/0/11_auth_token.up.sql +++ b/internal/db/schema/migrations/oss/postgres/0/11_auth_token.up.sql @@ -57,7 +57,7 @@ begin; comment on function update_last_access_time() is 'function used in before update triggers to properly set last_access_time columns'; - -- this trigger is deleted in 58/05_mutable_ciphertext_columns.up.sql + -- this trigger is deleted in 56/05_mutable_ciphertext_columns.up.sql create or replace function immutable_auth_token_columns() returns trigger as $$ begin diff --git a/internal/db/schema/migrations/oss/postgres/10/04_vault_credential.up.sql b/internal/db/schema/migrations/oss/postgres/10/04_vault_credential.up.sql index eeb86461aa..3ab64027e4 100644 --- a/internal/db/schema/migrations/oss/postgres/10/04_vault_credential.up.sql +++ b/internal/db/schema/migrations/oss/postgres/10/04_vault_credential.up.sql @@ -190,7 +190,7 @@ begin; create trigger default_create_time_column before insert on credential_vault_token for each row execute procedure default_create_time(); - -- this trigger is updated in 58/05_mutable_ciphertext_columns.up.sql + -- this trigger is updated in 56/05_mutable_ciphertext_columns.up.sql create trigger immutable_columns before update on credential_vault_token for each row execute procedure immutable_columns('token_hmac', 'token', 'store_id','create_time'); diff --git a/internal/db/schema/migrations/oss/postgres/12/01_timestamp_sub_funcs.up.sql b/internal/db/schema/migrations/oss/postgres/12/01_timestamp_sub_funcs.up.sql index e743101b9b..1264faa291 100644 --- a/internal/db/schema/migrations/oss/postgres/12/01_timestamp_sub_funcs.up.sql +++ b/internal/db/schema/migrations/oss/postgres/12/01_timestamp_sub_funcs.up.sql @@ -2,7 +2,7 @@ begin; -- The 'comment on function' statements below are not for the functions in the -- file. They incorrectly override the comments for functions declared in - -- 7/01_functions.up.sql. Fixes are contained in 57/01_fix_comments.up.sql. + -- 7/01_functions.up.sql. Fixes are contained in 58/01_fix_comments.up.sql. create function wt_sub_seconds(sec integer, ts timestamp with time zone) returns timestamp with time zone as $$ diff --git a/internal/db/schema/migrations/oss/postgres/2/04_oidc.up.sql b/internal/db/schema/migrations/oss/postgres/2/04_oidc.up.sql index ef8949ab45..87cf3fbe9e 100644 --- a/internal/db/schema/migrations/oss/postgres/2/04_oidc.up.sql +++ b/internal/db/schema/migrations/oss/postgres/2/04_oidc.up.sql @@ -158,7 +158,7 @@ create table auth_oidc_account ( constraint auth_oidc_account_auth_method_id_public_id_uq unique(auth_method_id, public_id) ); --- Comment fixed in 57/01_fix_comments.up.sql +-- Comment fixed in 58/01_fix_comments.up.sql comment on table auth_oidc_method is 'auth_oidc_account entries are subtypes of auth_account and represent an oidc account.'; diff --git a/internal/db/schema/migrations/oss/postgres/23/01_session_credential.up.sql b/internal/db/schema/migrations/oss/postgres/23/01_session_credential.up.sql index a87bfb27be..aaebcd2daa 100644 --- a/internal/db/schema/migrations/oss/postgres/23/01_session_credential.up.sql +++ b/internal/db/schema/migrations/oss/postgres/23/01_session_credential.up.sql @@ -22,7 +22,7 @@ begin; 'session_credential is a table where each row contains a credential to be used by ' 'by a worker when a connection is established for the session_id.'; - -- this trigger is updated in 58/05_mutable_ciphertext_columns.up.sql + -- this trigger is updated in 56/05_mutable_ciphertext_columns.up.sql create trigger immutable_columns before update on session_credential for each row execute procedure immutable_columns('session_id', 'credential', 'key_id'); diff --git a/internal/db/schema/migrations/oss/postgres/30/04_kms_keys.up.sql b/internal/db/schema/migrations/oss/postgres/30/04_kms_keys.up.sql index 6f23ba1bf7..d2ccccd4dc 100644 --- a/internal/db/schema/migrations/oss/postgres/30/04_kms_keys.up.sql +++ b/internal/db/schema/migrations/oss/postgres/30/04_kms_keys.up.sql @@ -101,7 +101,7 @@ create table kms_data_key_version ( constraint kms_data_key_version_data_key_id_version_uq unique(data_key_id, version) ); --- Comment fixed in 57/01_fix_comments.up.sql +-- Comment fixed in 58/01_fix_comments.up.sql comment on table kms_data_key is 'kms_data_key_version contains versions of a kms_data_key (dek aka data keys)'; diff --git a/internal/db/schema/migrations/oss/postgres/34/03_worker_authentication.up.sql b/internal/db/schema/migrations/oss/postgres/34/03_worker_authentication.up.sql index 447c1d3c79..e2afc5183c 100644 --- a/internal/db/schema/migrations/oss/postgres/34/03_worker_authentication.up.sql +++ b/internal/db/schema/migrations/oss/postgres/34/03_worker_authentication.up.sql @@ -72,7 +72,7 @@ create table worker_auth_ca_certificate( comment on table worker_auth_ca_certificate is 'worker_auth_ca_certificate is a table where each row represents a root certificate for used for worker authentication.'; --- this trigger is updated in 58/05_mutable_ciphertext_columns.up.sql +-- this trigger is updated in 56/05_mutable_ciphertext_columns.up.sql create trigger immutable_columns before update on worker_auth_ca_certificate for each row execute procedure immutable_columns('serial_number', 'certificate', 'not_valid_before', 'not_valid_after', 'public_key', 'private_key', 'key_id', 'state', 'issuing_ca'); @@ -102,7 +102,7 @@ create table worker_auth_authorized( comment on table worker_auth_authorized is 'worker_auth_authorized is a table where each row represents key and cert data associated with an authorized worker.'; --- this trigger is updated in 58/05_mutable_ciphertext_columns.up.sql +-- this trigger is updated in 56/05_mutable_ciphertext_columns.up.sql create trigger immutable_columns before update on worker_auth_authorized for each row execute procedure immutable_columns('worker_key_identifier', 'worker_id', 'worker_signing_pub_key', 'worker_encryption_pub_key', 'controller_encryption_priv_key', 'key_id', 'nonce'); diff --git a/internal/db/schema/migrations/oss/postgres/43/01_session_credentials.up.sql b/internal/db/schema/migrations/oss/postgres/43/01_session_credentials.up.sql index 549fa7b8e2..50659d537e 100644 --- a/internal/db/schema/migrations/oss/postgres/43/01_session_credentials.up.sql +++ b/internal/db/schema/migrations/oss/postgres/43/01_session_credentials.up.sql @@ -13,7 +13,7 @@ begin; add constraint session_credential_session_id_credential_sha256_uq unique(session_id, credential_sha256); - -- this trigger is updated in 58/05_mutable_ciphertext_columns.up.sql + -- this trigger is updated in 56/05_mutable_ciphertext_columns.up.sql drop trigger immutable_columns on session_credential; create trigger immutable_columns before update on session_credential for each row execute procedure immutable_columns('session_id', 'credential', 'key_id', 'credential_sha256'); diff --git a/internal/db/schema/migrations/oss/postgres/44/01_credentials.up.sql b/internal/db/schema/migrations/oss/postgres/44/01_credentials.up.sql index 9de264a92c..d5e7920f54 100644 --- a/internal/db/schema/migrations/oss/postgres/44/01_credentials.up.sql +++ b/internal/db/schema/migrations/oss/postgres/44/01_credentials.up.sql @@ -212,7 +212,7 @@ begin; 'No encrypted data is returned. This view can be used to retrieve data which will be returned external to boundary.'; -- Replaces view from 41/01_worker_filter_vault_cred_store.up.sql - -- Recreated in 58/02_add_data_key_foreign_key_references.up.sql + -- Recreated in 56/02_add_data_key_foreign_key_references.up.sql create view credential_vault_credential_private as select credential.public_id as public_id, credential.library_id as library_id, diff --git a/internal/db/schema/migrations/oss/postgres/44/02_hosts.up.sql b/internal/db/schema/migrations/oss/postgres/44/02_hosts.up.sql index 5d6752c3aa..d2521766d7 100644 --- a/internal/db/schema/migrations/oss/postgres/44/02_hosts.up.sql +++ b/internal/db/schema/migrations/oss/postgres/44/02_hosts.up.sql @@ -71,7 +71,7 @@ begin; -- update views drop view host_plugin_catalog_with_secret; - -- Recreated in 58/02_add_data_key_foreign_key_references.up.sql + -- Recreated in 56/02_add_data_key_foreign_key_references.up.sql create view host_plugin_catalog_with_secret as select hc.public_id, diff --git a/internal/db/schema/migrations/oss/postgres/44/04_sessions.up.sql b/internal/db/schema/migrations/oss/postgres/44/04_sessions.up.sql index ca08979dfb..996cca65ab 100644 --- a/internal/db/schema/migrations/oss/postgres/44/04_sessions.up.sql +++ b/internal/db/schema/migrations/oss/postgres/44/04_sessions.up.sql @@ -12,7 +12,7 @@ begin; ; -- Replaces trigger from 01/50_session.up.sql - -- Replaced in 58/02_add_data_key_foreign_key_references + -- Replaced in 56/02_add_data_key_foreign_key_references create or replace function cancel_session_with_null_fk() returns trigger as $$ begin @@ -60,7 +60,7 @@ begin; $$ language plpgsql; -- Replaces view from 34/04_views.up.sql - -- Replaced in 58/06_add_session_private_key_column + -- Replaced in 56/06_add_session_private_key_column drop view session_list; create view session_list as select diff --git a/internal/db/schema/migrations/oss/postgres/48/01_worker_auth_activation_token.up.sql b/internal/db/schema/migrations/oss/postgres/48/01_worker_auth_activation_token.up.sql index 77c5df4209..0f82c72b60 100644 --- a/internal/db/schema/migrations/oss/postgres/48/01_worker_auth_activation_token.up.sql +++ b/internal/db/schema/migrations/oss/postgres/48/01_worker_auth_activation_token.up.sql @@ -24,7 +24,7 @@ create table worker_auth_server_led_activation_token( comment on table worker_auth_server_led_activation_token is 'worker_auth_server_led_activation_token is a table where each row represents an activation token for a worker. Only one activation token is allowed per worker.'; --- this trigger is updated in 58/05_mutable_ciphertext_columns.up.sql +-- this trigger is updated in 56/05_mutable_ciphertext_columns.up.sql create trigger immutable_columns before update on worker_auth_server_led_activation_token for each row execute procedure immutable_columns('worker_id', 'token_id', 'creation_time_encrypted'); diff --git a/internal/db/schema/migrations/oss/postgres/49/01_vault_credentials.up.sql b/internal/db/schema/migrations/oss/postgres/49/01_vault_credentials.up.sql index 1a2556c9a1..5fe7961233 100644 --- a/internal/db/schema/migrations/oss/postgres/49/01_vault_credentials.up.sql +++ b/internal/db/schema/migrations/oss/postgres/49/01_vault_credentials.up.sql @@ -6,7 +6,7 @@ begin; drop view credential_vault_library_private; drop view credential_vault_store_private; - -- Recreated in 58/02_add_data_key_foreign_key_references.up.sql + -- Recreated in 56/02_add_data_key_foreign_key_references.up.sql create view credential_vault_token_renewal_revocation as with tokens as ( @@ -78,7 +78,7 @@ begin; 'If the Vault token has expired this view will return an empty token_hmac and a token_status of ''expired'' ' 'No encrypted data is returned. This view can be used to retrieve data which will be returned external to boundary.'; - -- Recreated in 58/02_add_data_key_foreign_key_references.up.sql + -- Recreated in 56/02_add_data_key_foreign_key_references.up.sql create view credential_vault_store_client as select store.public_id as public_id, store.project_id as project_id, @@ -107,7 +107,7 @@ begin; 'The view returns the current token for the store, if the Vault token has expired this view will return an empty token_hmac and a token_status of ''expired'' ' 'Each row may contain encrypted data. This view should not be used to retrieve data which will be returned external to boundary.'; - -- Recreated in 58/02_add_data_key_foreign_key_references.up.sql + -- Recreated in 56/02_add_data_key_foreign_key_references.up.sql create view credential_vault_library_issue_credentials as with password_override (library_id, username_attribute, password_attribute) as ( diff --git a/internal/db/schema/migrations/oss/postgres/55/01_worker_auth_create_time.up.sql b/internal/db/schema/migrations/oss/postgres/55/01_worker_auth_create_time.up.sql index eb4da13500..0737594db6 100644 --- a/internal/db/schema/migrations/oss/postgres/55/01_worker_auth_create_time.up.sql +++ b/internal/db/schema/migrations/oss/postgres/55/01_worker_auth_create_time.up.sql @@ -93,7 +93,7 @@ alter table worker_auth_authorized ; drop trigger immutable_columns on worker_auth_authorized; --- this trigger is updated in 58/05_mutable_ciphertext_columns.up.sql +-- this trigger is updated in 56/05_mutable_ciphertext_columns.up.sql create trigger immutable_columns before update on worker_auth_authorized for each row execute function immutable_columns('worker_key_identifier', 'worker_id', 'worker_signing_pub_key', 'worker_encryption_pub_key', 'controller_encryption_priv_key', 'key_id', 'nonce', 'create_time'); diff --git a/internal/db/schema/migrations/oss/postgres/58/01_oplog_key_id_scope_id_truncation.up.sql b/internal/db/schema/migrations/oss/postgres/56/01_oplog_key_id_scope_id_truncation.up.sql similarity index 100% rename from internal/db/schema/migrations/oss/postgres/58/01_oplog_key_id_scope_id_truncation.up.sql rename to internal/db/schema/migrations/oss/postgres/56/01_oplog_key_id_scope_id_truncation.up.sql diff --git a/internal/db/schema/migrations/oss/postgres/58/02_add_data_key_foreign_key_references.up.sql b/internal/db/schema/migrations/oss/postgres/56/02_add_data_key_foreign_key_references.up.sql similarity index 100% rename from internal/db/schema/migrations/oss/postgres/58/02_add_data_key_foreign_key_references.up.sql rename to internal/db/schema/migrations/oss/postgres/56/02_add_data_key_foreign_key_references.up.sql diff --git a/internal/db/schema/migrations/oss/postgres/58/03_create_kms_key_destructions.up.sql b/internal/db/schema/migrations/oss/postgres/56/03_create_kms_key_destructions.up.sql similarity index 100% rename from internal/db/schema/migrations/oss/postgres/58/03_create_kms_key_destructions.up.sql rename to internal/db/schema/migrations/oss/postgres/56/03_create_kms_key_destructions.up.sql diff --git a/internal/db/schema/migrations/oss/postgres/58/04_mutable_root_key_version.up.sql b/internal/db/schema/migrations/oss/postgres/56/04_mutable_root_key_version.up.sql similarity index 100% rename from internal/db/schema/migrations/oss/postgres/58/04_mutable_root_key_version.up.sql rename to internal/db/schema/migrations/oss/postgres/56/04_mutable_root_key_version.up.sql diff --git a/internal/db/schema/migrations/oss/postgres/58/05_mutable_ciphertext_columns.up.sql b/internal/db/schema/migrations/oss/postgres/56/05_mutable_ciphertext_columns.up.sql similarity index 100% rename from internal/db/schema/migrations/oss/postgres/58/05_mutable_ciphertext_columns.up.sql rename to internal/db/schema/migrations/oss/postgres/56/05_mutable_ciphertext_columns.up.sql diff --git a/internal/db/schema/migrations/oss/postgres/58/06_add_session_private_key_column.up.sql b/internal/db/schema/migrations/oss/postgres/56/06_add_session_private_key_column.up.sql similarity index 100% rename from internal/db/schema/migrations/oss/postgres/58/06_add_session_private_key_column.up.sql rename to internal/db/schema/migrations/oss/postgres/56/06_add_session_private_key_column.up.sql diff --git a/internal/db/schema/migrations/oss/postgres/56/01_auth.up.sql b/internal/db/schema/migrations/oss/postgres/57/01_auth.up.sql similarity index 100% rename from internal/db/schema/migrations/oss/postgres/56/01_auth.up.sql rename to internal/db/schema/migrations/oss/postgres/57/01_auth.up.sql diff --git a/internal/db/schema/migrations/oss/postgres/57/01_fix_comments.up.sql b/internal/db/schema/migrations/oss/postgres/58/01_fix_comments.up.sql similarity index 100% rename from internal/db/schema/migrations/oss/postgres/57/01_fix_comments.up.sql rename to internal/db/schema/migrations/oss/postgres/58/01_fix_comments.up.sql diff --git a/internal/db/schema/migrations/oss/postgres/59/01_target_ingress_egress_worker_filters.up.sql b/internal/db/schema/migrations/oss/postgres/59/01_target_ingress_egress_worker_filters.up.sql index 8dbad47b20..a2bd621d3c 100644 --- a/internal/db/schema/migrations/oss/postgres/59/01_target_ingress_egress_worker_filters.up.sql +++ b/internal/db/schema/migrations/oss/postgres/59/01_target_ingress_egress_worker_filters.up.sql @@ -85,7 +85,7 @@ select public_id, 'tcp' as type from target_tcp; --- Replaces view from 58/06_add_session_private_key_column.up.sql +-- Replaces view from 56/06_add_session_private_key_column.up.sql drop view session_list; create view session_list as select @@ -134,4 +134,4 @@ create trigger immutable_columns before update on session for each row execute procedure immutable_columns('public_id', 'certificate', 'expiration_time', 'connection_limit', 'create_time', 'endpoint', 'worker_filter', 'egress_worker_filter', 'ingress_worker_filter'); -commit; \ No newline at end of file +commit; diff --git a/internal/db/schema/migrations/oss/postgres/6/01_oidc.up.sql b/internal/db/schema/migrations/oss/postgres/6/01_oidc.up.sql index 863c94806d..b9e9b747c2 100644 --- a/internal/db/schema/migrations/oss/postgres/6/01_oidc.up.sql +++ b/internal/db/schema/migrations/oss/postgres/6/01_oidc.up.sql @@ -42,7 +42,7 @@ drop view oidc_auth_method_with_value_obj; -- value is part of the primary key and unique. This view will make things like -- recursive listing of oidc auth methods fairly straightforward to implement -- for the oidc repo. The view also includes an is_primary_auth_method bool --- Recreated in 58/02_add_data_key_foreign_key_references.up.sql +-- Recreated in 56/02_add_data_key_foreign_key_references.up.sql create view oidc_auth_method_with_value_obj as select case when s.primary_auth_method_id is not null then diff --git a/internal/db/schema/migrations/oss/postgres/7/01_functions.up.sql b/internal/db/schema/migrations/oss/postgres/7/01_functions.up.sql index 168115498a..f6ad0c9f79 100644 --- a/internal/db/schema/migrations/oss/postgres/7/01_functions.up.sql +++ b/internal/db/schema/migrations/oss/postgres/7/01_functions.up.sql @@ -1,7 +1,7 @@ begin; -- Comments for the functions below were incorrectly overridden in - -- 12/01_timestamp_sub_funcs.up.sql but fixed in 57/01_fix_comments.up.sql. + -- 12/01_timestamp_sub_funcs.up.sql but fixed in 58/01_fix_comments.up.sql. create function wt_add_seconds(sec integer, ts timestamp with time zone) returns timestamp with time zone as $$ diff --git a/internal/db/schema/migrations/oss/postgres_56_01_test.go b/internal/db/schema/migrations/oss/postgres_56_01_test.go index 46d542d2db..c543d059e5 100644 --- a/internal/db/schema/migrations/oss/postgres_56_01_test.go +++ b/internal/db/schema/migrations/oss/postgres_56_01_test.go @@ -2,26 +2,23 @@ package oss_test import ( "context" - "crypto/rand" "testing" - "github.com/hashicorp/boundary/internal/auth/oidc" "github.com/hashicorp/boundary/internal/auth/password" + "github.com/hashicorp/boundary/internal/authtoken" "github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/db/common" "github.com/hashicorp/boundary/internal/db/schema" - "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" "github.com/hashicorp/boundary/internal/types/scope" "github.com/hashicorp/boundary/testing/dbtest" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func TestMigrations_DeleteOrphanedAccounts(t *testing.T) { +func TestMigrations_NewForeignKeys(t *testing.T) { const ( - priorMigration = 55001 - currentMigration = 56001 + priorMigration = 56001 + currentMigration = 56002 ) t.Parallel() @@ -65,182 +62,19 @@ func TestMigrations_DeleteOrphanedAccounts(t *testing.T) { conn, err := db.Open(ctx, dbType, u) require.NoError(t, err) + // Create project wrapper := db.TestWrapper(t) - rw := db.New(conn) kmsCache := kms.TestKms(t, conn, wrapper) - err = kmsCache.CreateKeys(context.Background(), scope.Global.String(), kms.WithRandomReader(rand.Reader)) + err = kmsCache.CreateKeys(ctx, scope.Global.String()) require.NoError(t, err) - // Create the user we will associate accounts with - iamRepo := iam.TestRepo(t, conn, wrapper) - usr, err := iam.NewUser(scope.Global.String()) - require.NoError(t, err) - usr.PublicId = "u_1234567890" - num, err := rw.Exec(ctx, ` -insert into iam_user - (public_id, scope_id) -values - (?, ?) - `, []any{usr.PublicId, scope.Global.String()}) - require.NoError(t, err) - assert.Equal(t, 1, num) - - // Create the accounts we will delete and assert their behavior + // Create a password account + pwam := password.TestAuthMethod(t, conn, "global") + password.TestAccount(t, conn, pwam.PublicId, "user", password.WithPassword("password")) - pwAm1, err := password.NewAuthMethod(scope.Global.String()) - require.NoError(t, err) - pwAm1.PublicId = "ampw_1234567890" - _, err = rw.DoTx(ctx, 0, db.ExpBackoff{}, func(r db.Reader, w db.Writer) error { - _, err := w.Exec(ctx, ` - insert into auth_password_argon2_conf - (private_id, password_method_id) - values - (?, ?) - `, []any{"arg2conf_1234567890", pwAm1.PublicId}) - if err != nil { - return err - } - _, err = w.Exec(ctx, ` - insert into auth_password_method - (public_id, password_conf_id, scope_id) - values - (?, ?, ?) - `, []any{pwAm1.PublicId, "arg2conf_1234567890", pwAm1.ScopeId}) - return err - }) - require.NoError(t, err) - pwAcct1, err := password.NewAccount(pwAm1.GetPublicId(), password.WithLoginName("account1"), password.WithPassword("password")) - require.NoError(t, err) - pwAcct1.PublicId = "acctpw_1234567890" - num, err = rw.Exec(ctx, ` -insert into auth_password_account - (public_id, auth_method_id, scope_id, login_name) -values - (?, ?, ?, ?) - `, []any{pwAcct1.PublicId, pwAm1.PublicId, pwAm1.ScopeId, pwAcct1.LoginName}) - require.NoError(t, err) - assert.Equal(t, 1, num) - - pwAm2, err := password.NewAuthMethod(scope.Global.String()) - require.NoError(t, err) - pwAm2.PublicId = "ampw_0123456789" - _, err = rw.DoTx(ctx, 0, db.ExpBackoff{}, func(r db.Reader, w db.Writer) error { - _, err := w.Exec(ctx, ` - insert into auth_password_argon2_conf - (private_id, password_method_id) - values - (?, ?) - `, []any{"arg2conf_0123456789", pwAm2.PublicId}) - if err != nil { - return err - } - _, err = w.Exec(ctx, ` - insert into auth_password_method - (public_id, password_conf_id, scope_id) - values - (?, ?, ?) - `, []any{pwAm2.PublicId, "arg2conf_0123456789", pwAm2.ScopeId}) - return err - }) - pwAcct2, err := password.NewAccount(pwAm2.GetPublicId(), password.WithLoginName("account2"), password.WithPassword("password")) - require.NoError(t, err) - pwAcct2.PublicId = "acctpw_0123456789" - num, err = rw.Exec(ctx, ` -insert into auth_password_account - (public_id, auth_method_id, scope_id, login_name) -values - (?, ?, ?, ?) - `, []any{pwAcct2.PublicId, pwAm2.PublicId, pwAm2.ScopeId, pwAcct2.LoginName}) - require.NoError(t, err) - assert.Equal(t, 1, num) - - databaseWrapper, err := kmsCache.GetWrapper(context.Background(), scope.Global.String(), kms.KeyPurposeDatabase) - oidcAm1 := oidc.TestAuthMethod(t, conn, databaseWrapper, scope.Global.String(), oidc.InactiveState, "alice_rp1", - "my-dogs-name", oidc.WithIssuer(oidc.TestConvertToUrls(t, "https://alice1.com")[0]), oidc.WithApiUrl(oidc.TestConvertToUrls(t, "https://api1.com")[0])) - oidcAm1.PublicId = "amoidc_1234567890" - num, err = rw.Exec(ctx, ` - insert into auth_oidc_method - (public_id, scope_id, state, key_id) - values - (?, ?, ?, ?) - `, []any{oidcAm1.PublicId, oidcAm1.ScopeId, oidcAm1.OperationalState, oidcAm1.KeyId}) - require.NoError(t, err) - assert.Equal(t, 1, num) - oidcAcct1, err := oidc.NewAccount(ctx, oidcAm1.GetPublicId(), "oidcAcct1") - require.NoError(t, err) - oidcAcct1.PublicId = "acctoidc_0123456789" - num, err = rw.Exec(ctx, ` -insert into auth_oidc_account - (public_id, auth_method_id, scope_id, issuer, subject) -values - (?, ?, ?, ?, ?) - `, []any{oidcAcct1.PublicId, oidcAm1.PublicId, oidcAm1.ScopeId, oidcAm1.Issuer, oidcAcct1.Subject}) - require.NoError(t, err) - assert.Equal(t, 1, num) - - oidcAm2 := oidc.TestAuthMethod(t, conn, databaseWrapper, scope.Global.String(), oidc.InactiveState, "alice_rp2", - "my-dogs-name", oidc.WithIssuer(oidc.TestConvertToUrls(t, "https://alice2.com")[0]), oidc.WithApiUrl(oidc.TestConvertToUrls(t, "https://api2.com")[0])) - oidcAm2.PublicId = "amoidc_0123456789" - num, err = rw.Exec(ctx, ` - insert into auth_oidc_method - (public_id, scope_id, state, key_id) - values - (?, ?, ?, ?) - `, []any{oidcAm2.PublicId, oidcAm2.ScopeId, oidcAm2.OperationalState, oidcAm2.KeyId}) - require.NoError(t, err) - assert.Equal(t, 1, num) - oidcAcct2, err := oidc.NewAccount(ctx, oidcAm2.GetPublicId(), "oidcAcct2") - require.NoError(t, err) - oidcAcct2.PublicId = "acctoidc_1234567890" - num, err = rw.Exec(ctx, ` -insert into auth_oidc_account - (public_id, auth_method_id, scope_id, issuer, subject) -values - (?, ?, ?, ?, ?) - `, []any{oidcAcct2.PublicId, oidcAm2.PublicId, oidcAm2.ScopeId, oidcAm2.Issuer, oidcAcct2.Subject}) - require.NoError(t, err) - assert.Equal(t, 1, num) - - num, err = rw.Exec(ctx, ` -update auth_account set - iam_user_id=? -where - public_id in (?, ?, ?, ?) - `, []any{ - usr.PublicId, - pwAcct1.PublicId, pwAcct2.PublicId, oidcAcct1.PublicId, oidcAcct2.PublicId, - }) - require.NoError(t, err) - assert.Equal(t, 4, num) - usr, accts, err := iamRepo.LookupUser(ctx, usr.GetPublicId()) - require.NoError(t, err) - assert.ElementsMatch(t, []string{ - pwAcct1.GetPublicId(), pwAcct2.GetPublicId(), - oidcAcct1.GetPublicId(), oidcAcct2.GetPublicId(), - }, accts) - - num, err = rw.Exec(ctx, ` -delete from auth_password_account -where - public_id=? - `, []any{pwAcct1.PublicId}) - require.NoError(t, err) - assert.Equal(t, 1, num) - num, err = rw.Exec(ctx, ` -delete from auth_oidc_account -where - public_id=? - `, []any{oidcAcct1.PublicId}) - require.NoError(t, err) - assert.Equal(t, 1, num) - - // pwAcct1 is still listed as an account for this user! oh no! - _, accts, err = iamRepo.LookupUser(ctx, usr.GetPublicId()) - require.NoError(t, err) - assert.ElementsMatch(t, []string{ - pwAcct1.GetPublicId(), pwAcct2.GetPublicId(), - oidcAcct1.GetPublicId(), oidcAcct2.GetPublicId(), - }, accts) + // Create an auth token + tok := authtoken.TestAuthToken(t, conn, kmsCache, "global") + _ = tok // now we're ready for the migration we want to test. m, err = schema.NewManager(ctx, schema.Dialect(dialect), d, schema.WithEditions( @@ -265,31 +99,5 @@ where } require.Equal(t, want, state) - // pwAcct1 is no longer listed as an account for this user. Phew! - _, accts, err = iamRepo.LookupUser(ctx, usr.GetPublicId()) - require.NoError(t, err) - assert.ElementsMatch(t, []string{pwAcct2.GetPublicId(), oidcAcct2.GetPublicId()}, accts) - - num, err = rw.Exec(ctx, ` -delete from auth_password_account -where - public_id=? - `, []any{pwAcct2.PublicId}) - require.NoError(t, err) - assert.Equal(t, 1, num) - _, accts, err = iamRepo.LookupUser(ctx, usr.GetPublicId()) - require.NoError(t, err) - assert.ElementsMatch(t, []string{oidcAcct2.GetPublicId()}, accts) - num, err = rw.Exec(ctx, ` -delete from auth_oidc_account -where - public_id=? - `, []any{oidcAcct2.PublicId}) - require.NoError(t, err) - assert.Equal(t, 1, num) - - // Deleting the account now removes the association with the user - _, accts, err = iamRepo.LookupUser(ctx, usr.GetPublicId()) - require.NoError(t, err) - assert.Empty(t, accts) + // As long as there were no errors, the migration succeeded. } diff --git a/internal/db/schema/migrations/oss/postgres_57_01_test.go b/internal/db/schema/migrations/oss/postgres_57_01_test.go new file mode 100644 index 0000000000..020621b9e7 --- /dev/null +++ b/internal/db/schema/migrations/oss/postgres_57_01_test.go @@ -0,0 +1,295 @@ +package oss_test + +import ( + "context" + "crypto/rand" + "testing" + + "github.com/hashicorp/boundary/internal/auth/oidc" + "github.com/hashicorp/boundary/internal/auth/password" + "github.com/hashicorp/boundary/internal/db" + "github.com/hashicorp/boundary/internal/db/common" + "github.com/hashicorp/boundary/internal/db/schema" + "github.com/hashicorp/boundary/internal/iam" + "github.com/hashicorp/boundary/internal/kms" + "github.com/hashicorp/boundary/internal/types/scope" + "github.com/hashicorp/boundary/testing/dbtest" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestMigrations_DeleteOrphanedAccounts(t *testing.T) { + const ( + priorMigration = 56001 + currentMigration = 57001 + ) + + t.Parallel() + ctx := context.Background() + dialect := dbtest.Postgres + + c, u, _, err := dbtest.StartUsingTemplate(dialect, dbtest.WithTemplate(dbtest.Template1)) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, c()) + }) + d, err := common.SqlOpen(dialect, u) + require.NoError(t, err) + + // migration to the prior migration (before the one we want to test) + m, err := schema.NewManager(ctx, schema.Dialect(dialect), d, schema.WithEditions( + schema.TestCreatePartialEditions(schema.Dialect(dialect), schema.PartialEditions{"oss": priorMigration}), + )) + require.NoError(t, err) + + _, err = m.ApplyMigrations(ctx) + require.NoError(t, err) + state, err := m.CurrentState(ctx) + require.NoError(t, err) + want := &schema.State{ + Initialized: true, + Editions: []schema.EditionState{ + { + Name: "oss", + BinarySchemaVersion: priorMigration, + DatabaseSchemaVersion: priorMigration, + DatabaseSchemaState: schema.Equal, + }, + }, + } + require.Equal(t, want, state) + + // Get a connection + dbType, err := db.StringToDbType(dialect) + require.NoError(t, err) + conn, err := db.Open(ctx, dbType, u) + require.NoError(t, err) + + wrapper := db.TestWrapper(t) + rw := db.New(conn) + kmsCache := kms.TestKms(t, conn, wrapper) + err = kmsCache.CreateKeys(context.Background(), scope.Global.String(), kms.WithRandomReader(rand.Reader)) + require.NoError(t, err) + + // Create the user we will associate accounts with + iamRepo := iam.TestRepo(t, conn, wrapper) + usr, err := iam.NewUser(scope.Global.String()) + require.NoError(t, err) + usr.PublicId = "u_1234567890" + num, err := rw.Exec(ctx, ` +insert into iam_user + (public_id, scope_id) +values + (?, ?) + `, []any{usr.PublicId, scope.Global.String()}) + require.NoError(t, err) + assert.Equal(t, 1, num) + + // Create the accounts we will delete and assert their behavior + + pwAm1, err := password.NewAuthMethod(scope.Global.String()) + require.NoError(t, err) + pwAm1.PublicId = "ampw_1234567890" + _, err = rw.DoTx(ctx, 0, db.ExpBackoff{}, func(r db.Reader, w db.Writer) error { + _, err := w.Exec(ctx, ` + insert into auth_password_argon2_conf + (private_id, password_method_id) + values + (?, ?) + `, []any{"arg2conf_1234567890", pwAm1.PublicId}) + if err != nil { + return err + } + _, err = w.Exec(ctx, ` + insert into auth_password_method + (public_id, password_conf_id, scope_id) + values + (?, ?, ?) + `, []any{pwAm1.PublicId, "arg2conf_1234567890", pwAm1.ScopeId}) + return err + }) + require.NoError(t, err) + pwAcct1, err := password.NewAccount(pwAm1.GetPublicId(), password.WithLoginName("account1"), password.WithPassword("password")) + require.NoError(t, err) + pwAcct1.PublicId = "acctpw_1234567890" + num, err = rw.Exec(ctx, ` +insert into auth_password_account + (public_id, auth_method_id, scope_id, login_name) +values + (?, ?, ?, ?) + `, []any{pwAcct1.PublicId, pwAm1.PublicId, pwAm1.ScopeId, pwAcct1.LoginName}) + require.NoError(t, err) + assert.Equal(t, 1, num) + + pwAm2, err := password.NewAuthMethod(scope.Global.String()) + require.NoError(t, err) + pwAm2.PublicId = "ampw_0123456789" + _, err = rw.DoTx(ctx, 0, db.ExpBackoff{}, func(r db.Reader, w db.Writer) error { + _, err := w.Exec(ctx, ` + insert into auth_password_argon2_conf + (private_id, password_method_id) + values + (?, ?) + `, []any{"arg2conf_0123456789", pwAm2.PublicId}) + if err != nil { + return err + } + _, err = w.Exec(ctx, ` + insert into auth_password_method + (public_id, password_conf_id, scope_id) + values + (?, ?, ?) + `, []any{pwAm2.PublicId, "arg2conf_0123456789", pwAm2.ScopeId}) + return err + }) + pwAcct2, err := password.NewAccount(pwAm2.GetPublicId(), password.WithLoginName("account2"), password.WithPassword("password")) + require.NoError(t, err) + pwAcct2.PublicId = "acctpw_0123456789" + num, err = rw.Exec(ctx, ` +insert into auth_password_account + (public_id, auth_method_id, scope_id, login_name) +values + (?, ?, ?, ?) + `, []any{pwAcct2.PublicId, pwAm2.PublicId, pwAm2.ScopeId, pwAcct2.LoginName}) + require.NoError(t, err) + assert.Equal(t, 1, num) + + databaseWrapper, err := kmsCache.GetWrapper(context.Background(), scope.Global.String(), kms.KeyPurposeDatabase) + oidcAm1 := oidc.TestAuthMethod(t, conn, databaseWrapper, scope.Global.String(), oidc.InactiveState, "alice_rp1", + "my-dogs-name", oidc.WithIssuer(oidc.TestConvertToUrls(t, "https://alice1.com")[0]), oidc.WithApiUrl(oidc.TestConvertToUrls(t, "https://api1.com")[0])) + oidcAm1.PublicId = "amoidc_1234567890" + num, err = rw.Exec(ctx, ` + insert into auth_oidc_method + (public_id, scope_id, state, key_id) + values + (?, ?, ?, ?) + `, []any{oidcAm1.PublicId, oidcAm1.ScopeId, oidcAm1.OperationalState, oidcAm1.KeyId}) + require.NoError(t, err) + assert.Equal(t, 1, num) + oidcAcct1, err := oidc.NewAccount(ctx, oidcAm1.GetPublicId(), "oidcAcct1") + require.NoError(t, err) + oidcAcct1.PublicId = "acctoidc_0123456789" + num, err = rw.Exec(ctx, ` +insert into auth_oidc_account + (public_id, auth_method_id, scope_id, issuer, subject) +values + (?, ?, ?, ?, ?) + `, []any{oidcAcct1.PublicId, oidcAm1.PublicId, oidcAm1.ScopeId, oidcAm1.Issuer, oidcAcct1.Subject}) + require.NoError(t, err) + assert.Equal(t, 1, num) + + oidcAm2 := oidc.TestAuthMethod(t, conn, databaseWrapper, scope.Global.String(), oidc.InactiveState, "alice_rp2", + "my-dogs-name", oidc.WithIssuer(oidc.TestConvertToUrls(t, "https://alice2.com")[0]), oidc.WithApiUrl(oidc.TestConvertToUrls(t, "https://api2.com")[0])) + oidcAm2.PublicId = "amoidc_0123456789" + num, err = rw.Exec(ctx, ` + insert into auth_oidc_method + (public_id, scope_id, state, key_id) + values + (?, ?, ?, ?) + `, []any{oidcAm2.PublicId, oidcAm2.ScopeId, oidcAm2.OperationalState, oidcAm2.KeyId}) + require.NoError(t, err) + assert.Equal(t, 1, num) + oidcAcct2, err := oidc.NewAccount(ctx, oidcAm2.GetPublicId(), "oidcAcct2") + require.NoError(t, err) + oidcAcct2.PublicId = "acctoidc_1234567890" + num, err = rw.Exec(ctx, ` +insert into auth_oidc_account + (public_id, auth_method_id, scope_id, issuer, subject) +values + (?, ?, ?, ?, ?) + `, []any{oidcAcct2.PublicId, oidcAm2.PublicId, oidcAm2.ScopeId, oidcAm2.Issuer, oidcAcct2.Subject}) + require.NoError(t, err) + assert.Equal(t, 1, num) + + num, err = rw.Exec(ctx, ` +update auth_account set + iam_user_id=? +where + public_id in (?, ?, ?, ?) + `, []any{ + usr.PublicId, + pwAcct1.PublicId, pwAcct2.PublicId, oidcAcct1.PublicId, oidcAcct2.PublicId, + }) + require.NoError(t, err) + assert.Equal(t, 4, num) + usr, accts, err := iamRepo.LookupUser(ctx, usr.GetPublicId()) + require.NoError(t, err) + assert.ElementsMatch(t, []string{ + pwAcct1.GetPublicId(), pwAcct2.GetPublicId(), + oidcAcct1.GetPublicId(), oidcAcct2.GetPublicId(), + }, accts) + + num, err = rw.Exec(ctx, ` +delete from auth_password_account +where + public_id=? + `, []any{pwAcct1.PublicId}) + require.NoError(t, err) + assert.Equal(t, 1, num) + num, err = rw.Exec(ctx, ` +delete from auth_oidc_account +where + public_id=? + `, []any{oidcAcct1.PublicId}) + require.NoError(t, err) + assert.Equal(t, 1, num) + + // pwAcct1 is still listed as an account for this user! oh no! + _, accts, err = iamRepo.LookupUser(ctx, usr.GetPublicId()) + require.NoError(t, err) + assert.ElementsMatch(t, []string{ + pwAcct1.GetPublicId(), pwAcct2.GetPublicId(), + oidcAcct1.GetPublicId(), oidcAcct2.GetPublicId(), + }, accts) + + // now we're ready for the migration we want to test. + m, err = schema.NewManager(ctx, schema.Dialect(dialect), d, schema.WithEditions( + schema.TestCreatePartialEditions(schema.Dialect(dialect), schema.PartialEditions{"oss": currentMigration}), + )) + require.NoError(t, err) + + _, err = m.ApplyMigrations(ctx) + require.NoError(t, err) + state, err = m.CurrentState(ctx) + require.NoError(t, err) + want = &schema.State{ + Initialized: true, + Editions: []schema.EditionState{ + { + Name: "oss", + BinarySchemaVersion: currentMigration, + DatabaseSchemaVersion: currentMigration, + DatabaseSchemaState: schema.Equal, + }, + }, + } + require.Equal(t, want, state) + + // pwAcct1 is no longer listed as an account for this user. Phew! + _, accts, err = iamRepo.LookupUser(ctx, usr.GetPublicId()) + require.NoError(t, err) + assert.ElementsMatch(t, []string{pwAcct2.GetPublicId(), oidcAcct2.GetPublicId()}, accts) + + num, err = rw.Exec(ctx, ` +delete from auth_password_account +where + public_id=? + `, []any{pwAcct2.PublicId}) + require.NoError(t, err) + assert.Equal(t, 1, num) + _, accts, err = iamRepo.LookupUser(ctx, usr.GetPublicId()) + require.NoError(t, err) + assert.ElementsMatch(t, []string{oidcAcct2.GetPublicId()}, accts) + num, err = rw.Exec(ctx, ` +delete from auth_oidc_account +where + public_id=? + `, []any{oidcAcct2.PublicId}) + require.NoError(t, err) + assert.Equal(t, 1, num) + + // Deleting the account now removes the association with the user + _, accts, err = iamRepo.LookupUser(ctx, usr.GetPublicId()) + require.NoError(t, err) + assert.Empty(t, accts) +} diff --git a/internal/db/schema/migrations/oss/postgres_58_01_test.go b/internal/db/schema/migrations/oss/postgres_58_01_test.go deleted file mode 100644 index 231aaf3555..0000000000 --- a/internal/db/schema/migrations/oss/postgres_58_01_test.go +++ /dev/null @@ -1,103 +0,0 @@ -package oss_test - -import ( - "context" - "testing" - - "github.com/hashicorp/boundary/internal/auth/password" - "github.com/hashicorp/boundary/internal/authtoken" - "github.com/hashicorp/boundary/internal/db" - "github.com/hashicorp/boundary/internal/db/common" - "github.com/hashicorp/boundary/internal/db/schema" - "github.com/hashicorp/boundary/internal/kms" - "github.com/hashicorp/boundary/internal/types/scope" - "github.com/hashicorp/boundary/testing/dbtest" - "github.com/stretchr/testify/require" -) - -func TestMigrations_NewForeignKeys(t *testing.T) { - const ( - priorMigration = 58001 - currentMigration = 58002 - ) - - t.Parallel() - ctx := context.Background() - dialect := dbtest.Postgres - - c, u, _, err := dbtest.StartUsingTemplate(dialect, dbtest.WithTemplate(dbtest.Template1)) - require.NoError(t, err) - t.Cleanup(func() { - require.NoError(t, c()) - }) - d, err := common.SqlOpen(dialect, u) - require.NoError(t, err) - - // migration to the prior migration (before the one we want to test) - m, err := schema.NewManager(ctx, schema.Dialect(dialect), d, schema.WithEditions( - schema.TestCreatePartialEditions(schema.Dialect(dialect), schema.PartialEditions{"oss": priorMigration}), - )) - require.NoError(t, err) - - _, err = m.ApplyMigrations(ctx) - require.NoError(t, err) - state, err := m.CurrentState(ctx) - require.NoError(t, err) - want := &schema.State{ - Initialized: true, - Editions: []schema.EditionState{ - { - Name: "oss", - BinarySchemaVersion: priorMigration, - DatabaseSchemaVersion: priorMigration, - DatabaseSchemaState: schema.Equal, - }, - }, - } - require.Equal(t, want, state) - - // Get a connection - dbType, err := db.StringToDbType(dialect) - require.NoError(t, err) - conn, err := db.Open(ctx, dbType, u) - require.NoError(t, err) - - // Create project - wrapper := db.TestWrapper(t) - kmsCache := kms.TestKms(t, conn, wrapper) - err = kmsCache.CreateKeys(ctx, scope.Global.String()) - require.NoError(t, err) - - // Create a password account - pwam := password.TestAuthMethod(t, conn, "global") - password.TestAccount(t, conn, pwam.PublicId, "user", password.WithPassword("password")) - - // Create an auth token - tok := authtoken.TestAuthToken(t, conn, kmsCache, "global") - _ = tok - - // now we're ready for the migration we want to test. - m, err = schema.NewManager(ctx, schema.Dialect(dialect), d, schema.WithEditions( - schema.TestCreatePartialEditions(schema.Dialect(dialect), schema.PartialEditions{"oss": currentMigration}), - )) - require.NoError(t, err) - - _, err = m.ApplyMigrations(ctx) - require.NoError(t, err) - state, err = m.CurrentState(ctx) - require.NoError(t, err) - want = &schema.State{ - Initialized: true, - Editions: []schema.EditionState{ - { - Name: "oss", - BinarySchemaVersion: currentMigration, - DatabaseSchemaVersion: currentMigration, - DatabaseSchemaState: schema.Equal, - }, - }, - } - require.Equal(t, want, state) - - // As long as there were no errors, the migration succeeded. -}