Enforce auth_account to iam_user plus iam_scope constraints (#137)
This commit is contained in:
1 parent
0a0d37668d
commit
1023c90729
6 files changed
+198
-109
No files matched your search
@@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/watchtower/internal/db"
|
||||
"github.com/hashicorp/watchtower/internal/iam"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -12,12 +13,15 @@ func TestDB_AuthMethodIDTrigger(t *testing.T) {
|
||||
const (
|
||||
createTable = `
|
||||
create table if not exists test_auth_method (
|
||||
auth_method_id wt_public_id primary key
|
||||
auth_method_id wt_public_id primary key,
|
||||
iam_scope_id wt_public_id not null references iam_scope(public_id)
|
||||
);
|
||||
`
|
||||
insert = `
|
||||
insert into test_auth_method (auth_method_id)
|
||||
values ($1);
|
||||
insert into test_auth_method
|
||||
(auth_method_id, iam_scope_id)
|
||||
values
|
||||
($1, $2);
|
||||
`
|
||||
addTriggers = `
|
||||
create trigger
|
||||
@@ -55,8 +59,10 @@ select count(*) from test_auth_method where auth_method_id = $1;
|
||||
_, err = db.Exec(addTriggers)
|
||||
require.NoError(err)
|
||||
|
||||
org, _ := iam.TestScopes(t, conn)
|
||||
|
||||
id := "l1Ocw0TpHn800CekIxIXlmQqRDgFDfYl"
|
||||
_, err = db.Query(insert, id)
|
||||
_, err = db.Query(insert, id, org.GetPublicId())
|
||||
require.NoError(err)
|
||||
|
||||
var count int
|
||||
@@ -75,12 +81,16 @@ func TestDB_AuthAccountIDTrigger(t *testing.T) {
|
||||
const (
|
||||
createTable = `
|
||||
create table if not exists test_auth_account (
|
||||
auth_account_id wt_public_id primary key
|
||||
auth_account_id wt_public_id primary key,
|
||||
auth_method_id wt_public_id not null,
|
||||
iam_scope_id wt_public_id not null
|
||||
);
|
||||
`
|
||||
insert = `
|
||||
insert into test_auth_account (auth_account_id)
|
||||
values ($1);
|
||||
insert into test_auth_account
|
||||
(auth_account_id, auth_method_id, iam_scope_id)
|
||||
values
|
||||
($1, $2, $3);
|
||||
`
|
||||
addTriggers = `
|
||||
create trigger
|
||||
@@ -94,6 +104,12 @@ select count(*) from auth_account where auth_account_id = $1;
|
||||
`
|
||||
testTableQuery = `
|
||||
select count(*) from test_auth_account where auth_account_id = $1;
|
||||
`
|
||||
insertAuthMethod = `
|
||||
insert into auth_method
|
||||
(auth_method_id, iam_scope_id)
|
||||
values
|
||||
($1, $2);
|
||||
`
|
||||
)
|
||||
|
||||
@@ -118,8 +134,13 @@ select count(*) from test_auth_account where auth_account_id = $1;
|
||||
_, err = db.Exec(addTriggers)
|
||||
require.NoError(err)
|
||||
|
||||
org, _ := iam.TestScopes(t, conn)
|
||||
meth_id := "31Ocw0TpHn800CekIxIXlmQqRDgFDfYl"
|
||||
_, err = db.Query(insertAuthMethod, meth_id, org.GetPublicId())
|
||||
require.NoError(err)
|
||||
|
||||
id := "l1Ocw0TpHn800CekIxIXlmQqRDgFDfYl"
|
||||
_, err = db.Query(insert, id)
|
||||
_, err = db.Query(insert, id, meth_id, org.GetPublicId())
|
||||
require.NoError(err)
|
||||
|
||||
var count int
|
||||
|
||||
@@ -330,66 +330,6 @@ insert on db_test_rental
|
||||
|
||||
commit;
|
||||
|
||||
`),
|
||||
},
|
||||
"migrations/04_auth.down.sql": {
|
||||
name: "04_auth.down.sql",
|
||||
bytes: []byte(`
|
||||
begin;
|
||||
|
||||
drop function insert_auth_account_subtype;
|
||||
drop function insert_auth_method_subtype;
|
||||
|
||||
drop table auth_account cascade;
|
||||
drop table auth_method cascade;
|
||||
|
||||
commit;
|
||||
|
||||
`),
|
||||
},
|
||||
"migrations/04_auth.up.sql": {
|
||||
name: "04_auth.up.sql",
|
||||
bytes: []byte(`
|
||||
begin;
|
||||
|
||||
-- base table for auth methods
|
||||
create table auth_method (
|
||||
auth_method_id wt_public_id primary key
|
||||
);
|
||||
|
||||
|
||||
-- base table for auth accounts
|
||||
create table auth_account (
|
||||
auth_account_id wt_public_id primary key
|
||||
);
|
||||
|
||||
|
||||
create or replace function
|
||||
insert_auth_method_subtype()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
insert into auth_method (auth_method_id)
|
||||
values
|
||||
(new.auth_method_id);
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create or replace function
|
||||
insert_auth_account_subtype()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
insert into auth_account (auth_account_id)
|
||||
values
|
||||
(new.auth_account_id);
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
commit;
|
||||
|
||||
`),
|
||||
},
|
||||
"migrations/06_iam.down.sql": {
|
||||
@@ -568,7 +508,12 @@ create table iam_user (
|
||||
description text,
|
||||
scope_id wt_public_id not null references iam_scope_organization(scope_id) on delete cascade on update cascade,
|
||||
unique(name, scope_id),
|
||||
disabled boolean not null default false
|
||||
disabled boolean not null default false,
|
||||
|
||||
-- The order of columns is important for performance. See:
|
||||
-- https://dba.stackexchange.com/questions/58970/enforcing-constraints-two-tables-away/58972#58972
|
||||
-- https://dba.stackexchange.com/questions/27481/is-a-composite-index-also-good-for-queries-on-the-first-field
|
||||
unique(scope_id, public_id)
|
||||
);
|
||||
|
||||
create trigger
|
||||
@@ -646,6 +591,95 @@ insert on iam_group
|
||||
|
||||
commit;
|
||||
|
||||
`),
|
||||
},
|
||||
"migrations/07_auth.down.sql": {
|
||||
name: "07_auth.down.sql",
|
||||
bytes: []byte(`
|
||||
begin;
|
||||
|
||||
drop function insert_auth_account_subtype;
|
||||
drop function insert_auth_method_subtype;
|
||||
|
||||
drop table auth_account cascade;
|
||||
drop table auth_method cascade;
|
||||
|
||||
commit;
|
||||
|
||||
`),
|
||||
},
|
||||
"migrations/07_auth.up.sql": {
|
||||
name: "07_auth.up.sql",
|
||||
bytes: []byte(`
|
||||
begin;
|
||||
|
||||
-- Design influenced by:
|
||||
-- https://dba.stackexchange.com/questions/58970/enforcing-constraints-two-tables-away/58972#58972
|
||||
--
|
||||
-- iam_scope ←───── auth_method
|
||||
-- ↑ ↑
|
||||
-- iam_user ←───── auth_account
|
||||
|
||||
-- base table for auth methods
|
||||
create table auth_method (
|
||||
auth_method_id wt_public_id primary key,
|
||||
iam_scope_id wt_public_id not null
|
||||
references iam_scope(public_id)
|
||||
on delete cascade
|
||||
on update cascade,
|
||||
|
||||
-- The order of columns is important for performance. See:
|
||||
-- https://dba.stackexchange.com/questions/58970/enforcing-constraints-two-tables-away/58972#58972
|
||||
-- https://dba.stackexchange.com/questions/27481/is-a-composite-index-also-good-for-queries-on-the-first-field
|
||||
unique(iam_scope_id, auth_method_id)
|
||||
);
|
||||
|
||||
|
||||
-- base table for auth accounts
|
||||
create table auth_account (
|
||||
auth_account_id wt_public_id primary key,
|
||||
auth_method_id wt_public_id not null,
|
||||
iam_scope_id wt_public_id not null,
|
||||
iam_user_id wt_public_id,
|
||||
foreign key (iam_scope_id, auth_method_id)
|
||||
references auth_method (iam_scope_id, auth_method_id)
|
||||
on delete cascade
|
||||
on update cascade,
|
||||
foreign key (iam_scope_id, iam_user_id)
|
||||
references iam_user (scope_id, public_id)
|
||||
on delete set null
|
||||
on update cascade
|
||||
);
|
||||
|
||||
|
||||
create or replace function
|
||||
insert_auth_method_subtype()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
insert into auth_method
|
||||
(auth_method_id, iam_scope_id)
|
||||
values
|
||||
(new.auth_method_id, new.iam_scope_id);
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create or replace function
|
||||
insert_auth_account_subtype()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
insert into auth_account
|
||||
(auth_account_id, auth_method_id, iam_scope_id)
|
||||
values
|
||||
(new.auth_account_id, new.auth_method_id, new.iam_scope_id);
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
commit;
|
||||
|
||||
`),
|
||||
},
|
||||
"migrations/10_static_host.down.sql": {
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
begin;
|
||||
|
||||
-- base table for auth methods
|
||||
create table auth_method (
|
||||
auth_method_id wt_public_id primary key
|
||||
);
|
||||
|
||||
|
||||
-- base table for auth accounts
|
||||
create table auth_account (
|
||||
auth_account_id wt_public_id primary key
|
||||
);
|
||||
|
||||
|
||||
create or replace function
|
||||
insert_auth_method_subtype()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
insert into auth_method (auth_method_id)
|
||||
values
|
||||
(new.auth_method_id);
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create or replace function
|
||||
insert_auth_account_subtype()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
insert into auth_account (auth_account_id)
|
||||
values
|
||||
(new.auth_account_id);
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
commit;
|
||||
@@ -149,7 +149,12 @@ create table iam_user (
|
||||
description text,
|
||||
scope_id wt_public_id not null references iam_scope_organization(scope_id) on delete cascade on update cascade,
|
||||
unique(name, scope_id),
|
||||
disabled boolean not null default false
|
||||
disabled boolean not null default false,
|
||||
|
||||
-- The order of columns is important for performance. See:
|
||||
-- https://dba.stackexchange.com/questions/58970/enforcing-constraints-two-tables-away/58972#58972
|
||||
-- https://dba.stackexchange.com/questions/27481/is-a-composite-index-also-good-for-queries-on-the-first-field
|
||||
unique(scope_id, public_id)
|
||||
);
|
||||
|
||||
create trigger
|
||||
|
||||
File renamed without changes.
@@ -0,0 +1,68 @@
|
||||
begin;
|
||||
|
||||
-- Design influenced by:
|
||||
-- https://dba.stackexchange.com/questions/58970/enforcing-constraints-two-tables-away/58972#58972
|
||||
--
|
||||
-- iam_scope ←───── auth_method
|
||||
-- ↑ ↑
|
||||
-- iam_user ←───── auth_account
|
||||
|
||||
-- base table for auth methods
|
||||
create table auth_method (
|
||||
auth_method_id wt_public_id primary key,
|
||||
iam_scope_id wt_public_id not null
|
||||
references iam_scope(public_id)
|
||||
on delete cascade
|
||||
on update cascade,
|
||||
|
||||
-- The order of columns is important for performance. See:
|
||||
-- https://dba.stackexchange.com/questions/58970/enforcing-constraints-two-tables-away/58972#58972
|
||||
-- https://dba.stackexchange.com/questions/27481/is-a-composite-index-also-good-for-queries-on-the-first-field
|
||||
unique(iam_scope_id, auth_method_id)
|
||||
);
|
||||
|
||||
|
||||
-- base table for auth accounts
|
||||
create table auth_account (
|
||||
auth_account_id wt_public_id primary key,
|
||||
auth_method_id wt_public_id not null,
|
||||
iam_scope_id wt_public_id not null,
|
||||
iam_user_id wt_public_id,
|
||||
foreign key (iam_scope_id, auth_method_id)
|
||||
references auth_method (iam_scope_id, auth_method_id)
|
||||
on delete cascade
|
||||
on update cascade,
|
||||
foreign key (iam_scope_id, iam_user_id)
|
||||
references iam_user (scope_id, public_id)
|
||||
on delete set null
|
||||
on update cascade
|
||||
);
|
||||
|
||||
|
||||
create or replace function
|
||||
insert_auth_method_subtype()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
insert into auth_method
|
||||
(auth_method_id, iam_scope_id)
|
||||
values
|
||||
(new.auth_method_id, new.iam_scope_id);
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create or replace function
|
||||
insert_auth_account_subtype()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
insert into auth_account
|
||||
(auth_account_id, auth_method_id, iam_scope_id)
|
||||
values
|
||||
(new.auth_account_id, new.auth_method_id, new.iam_scope_id);
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
commit;
|
||||
Reference in new issue
Block a user