Disambiguate auth_account scope_id by adding iam_user_scope_id column (#407)

pull/410/head
Michael Gaffney 6 years ago committed by GitHub
parent c93254c05b
commit f0c84de49c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1252,6 +1252,7 @@ commit;
bytes: []byte(`
begin;
drop function update_iam_user_auth_account;
drop function insert_auth_account_subtype;
drop function insert_auth_method_subtype;
@ -1286,11 +1287,12 @@ begin;
iam_user auth_account
public_id (pk) public_id (pk)
scope_id (fk) fk2 scope_id (fk1,fk2)
auth_method_id (fk1)
iam_user_id (fk2)
public_id (pk) public_id (pk)
scope_id (fk) fk2 scope_id (fk1)
auth_method_id (fk1)
iam_user_scope_id (fk2)
iam_user_id (fk2)
An iam_scope can have 0 to many iam_users.
An iam_scope can have 0 to many auth_methods.
@ -1339,13 +1341,26 @@ begin;
scope_id wt_scope_id
not null,
iam_user_id wt_public_id,
-- The auth_account can only be assigned to an iam_user in the same scope as
-- the auth_method the auth_account belongs to. A separate column for
-- iam_user's scope id is needed because using the scope_id column in the
-- foreign key constraint causes an error when the iam_user is deleted but
-- the auth_account still exists. This is a valid scenario since the
-- lifetime of the auth_account is tied to the auth_method not the iam_user.
iam_user_scope_id wt_scope_id,
constraint user_and_auth_account_in_same_scope
check(
(iam_user_id is null and iam_user_scope_id is null)
or
(iam_user_id is not null and (iam_user_scope_id = scope_id))
),
-- including scope_id in fk1 and fk2 ensures the scope_id of the owning
-- auth_method and the scope_id of the owning iam_user are the same
foreign key (scope_id, auth_method_id) -- fk1
references auth_method (scope_id, public_id)
on delete cascade
on update cascade,
foreign key (scope_id, iam_user_id) -- fk2
foreign key (iam_user_scope_id, iam_user_id) -- fk2
references iam_user (scope_id, public_id)
on delete set null
on update cascade,
@ -1386,6 +1401,36 @@ begin;
end;
$$ language plpgsql;
-- update_iam_user_auth_account is a before update trigger on the auth_account
-- table. If the new.iam_user_id column is different from the old.iam_user_id
-- column, update_iam_user_auth_account retrieves the scope id of the iam user
-- and sets new.iam_user_scope_id to that value. If the new.iam_user_id column
-- is null and the old.iam_user_id column is not null,
-- update_iam_user_auth_account sets the iam_user_scope_id to null.
create or replace function
update_iam_user_auth_account()
returns trigger
as $$
begin
if new.iam_user_id is distinct from old.iam_user_id then
if new.iam_user_id is null then
new.iam_user_scope_id = null;
else
select iam_user.scope_id into new.iam_user_scope_id
from iam_user
where iam_user.public_id = new.iam_user_id;
end if;
end if;
return new;
end;
$$ language plpgsql;
create trigger update_iam_user_auth_account
before update of iam_user_id on auth_account
for each row
execute procedure update_iam_user_auth_account();
commit;
`),
@ -1652,11 +1697,12 @@ begin;
auth_account auth_password_account auth_password_credential
public_id (pk) public_id (pk,fk2) private_id (pk)
scope_id (fk1,fk2) fk2 scope_id (fk1,fk2) fk2 password_method_id (fk1,fk2)
auth_method_id (fk1) auth_method_id (fk1,fk2) password_conf_id (fk1)
iam_user_id (fk2) ... password_account_id (fk2)
public_id (pk) public_id (pk,fk2) private_id (pk)
scope_id (fk1) fk2 scope_id (fk1,fk2) fk2 password_method_id (fk1,fk2)
auth_method_id (fk1) auth_method_id (fk1,fk2) password_conf_id (fk1)
iam_user_scope_id (fk2) ... password_account_id (fk2)
iam_user_id (fk2)
An auth_method is a base type. An auth_password_method is an auth_method
subtype. For every row in auth_password_method there is one row in auth_method

@ -1,5 +1,6 @@
begin;
drop function update_iam_user_auth_account;
drop function insert_auth_account_subtype;
drop function insert_auth_method_subtype;

@ -19,11 +19,12 @@ begin;
iam_user auth_account
public_id (pk) public_id (pk)
scope_id (fk) fk2 scope_id (fk1,fk2)
auth_method_id (fk1)
iam_user_id (fk2)
public_id (pk) public_id (pk)
scope_id (fk) fk2 scope_id (fk1)
auth_method_id (fk1)
iam_user_scope_id (fk2)
iam_user_id (fk2)
An iam_scope can have 0 to many iam_users.
An iam_scope can have 0 to many auth_methods.
@ -72,13 +73,26 @@ begin;
scope_id wt_scope_id
not null,
iam_user_id wt_public_id,
-- The auth_account can only be assigned to an iam_user in the same scope as
-- the auth_method the auth_account belongs to. A separate column for
-- iam_user's scope id is needed because using the scope_id column in the
-- foreign key constraint causes an error when the iam_user is deleted but
-- the auth_account still exists. This is a valid scenario since the
-- lifetime of the auth_account is tied to the auth_method not the iam_user.
iam_user_scope_id wt_scope_id,
constraint user_and_auth_account_in_same_scope
check(
(iam_user_id is null and iam_user_scope_id is null)
or
(iam_user_id is not null and (iam_user_scope_id = scope_id))
),
-- including scope_id in fk1 and fk2 ensures the scope_id of the owning
-- auth_method and the scope_id of the owning iam_user are the same
foreign key (scope_id, auth_method_id) -- fk1
references auth_method (scope_id, public_id)
on delete cascade
on update cascade,
foreign key (scope_id, iam_user_id) -- fk2
foreign key (iam_user_scope_id, iam_user_id) -- fk2
references iam_user (scope_id, public_id)
on delete set null
on update cascade,
@ -119,4 +133,34 @@ begin;
end;
$$ language plpgsql;
-- update_iam_user_auth_account is a before update trigger on the auth_account
-- table. If the new.iam_user_id column is different from the old.iam_user_id
-- column, update_iam_user_auth_account retrieves the scope id of the iam user
-- and sets new.iam_user_scope_id to that value. If the new.iam_user_id column
-- is null and the old.iam_user_id column is not null,
-- update_iam_user_auth_account sets the iam_user_scope_id to null.
create or replace function
update_iam_user_auth_account()
returns trigger
as $$
begin
if new.iam_user_id is distinct from old.iam_user_id then
if new.iam_user_id is null then
new.iam_user_scope_id = null;
else
select iam_user.scope_id into new.iam_user_scope_id
from iam_user
where iam_user.public_id = new.iam_user_id;
end if;
end if;
return new;
end;
$$ language plpgsql;
create trigger update_iam_user_auth_account
before update of iam_user_id on auth_account
for each row
execute procedure update_iam_user_auth_account();
commit;

@ -19,11 +19,12 @@ begin;
auth_account auth_password_account auth_password_credential
public_id (pk) public_id (pk,fk2) private_id (pk)
scope_id (fk1,fk2) fk2 scope_id (fk1,fk2) fk2 password_method_id (fk1,fk2)
auth_method_id (fk1) auth_method_id (fk1,fk2) password_conf_id (fk1)
iam_user_id (fk2) ... password_account_id (fk2)
public_id (pk) public_id (pk,fk2) private_id (pk)
scope_id (fk1) fk2 scope_id (fk1,fk2) fk2 password_method_id (fk1,fk2)
auth_method_id (fk1) auth_method_id (fk1,fk2) password_conf_id (fk1)
iam_user_scope_id (fk2) ... password_account_id (fk2)
iam_user_id (fk2)
An auth_method is a base type. An auth_password_method is an auth_method
subtype. For every row in auth_password_method there is one row in auth_method

Loading…
Cancel
Save