* feature (auth): required schema changes for auth ldap method (#2669) chore (auth/ldap): move schema changes to next avail migration number * feature (auth/ldap): define AuthMethod and all its value objects (#2703) * feature (auth/ldap): storage protos * feature (auth/ldap): define AuthMethod and all its value objects * feature (auth/ldap): add repo and reading an auth method (#2718) * feature (auth/ldap): add Repository.CreateAuthMethod(...) and Repository.DeleteAuthMethod(...) (#2724) * feature (auth/ldap): add Repository.UpdateAuthMethod(...) (#2739) * feature (auth/ldap): add Account * feature (auth/ldap): add AuthMethod.EnableGroups * fix (auth/ldap): refactor AuthMethod.oplog to enforce proper constraints * feature (auth/ldap): add Account repo functions * refactor (auth/ldap): remove entry attributes from account Realized the entry attributes could have absolutely anything in them (including binary data) and since we absolutely don't have to have them there's just no reason to take on the risk. * feature (auth/ldap): add AuthMethod.UseTokenGroups * feature (auth/ldap): add Authenticate(...) * refactor (auth/ldap): ensure options take a context as the 1st parameter * feature (auth/ldap): add Account attribute maps * chore (auth/ldap): make fmt deltas * feature (auth/ldap): add managed groups (#2760) * tests (auth/ldap): add missing unit test to Repository.DeleteAccount(...) Add bits to test the delete operation when you're not able to generate oplog metadata * feature (auth/ldap): add managed groups fixup! feature (auth/ldap): add managed groups (#2760) * feature (auth/ldap): service proto definition (#2761) * feature (handlers/authmethods): add handlers for ldap auth method operations (#2794) * feature (auth/ldap): add Account attribute maps * chore (auth/ldap): update cap/ldap to latest version * feature (auth/ldap): add ldap api generation definitions * feature (authmethods): add ldap repo NewService(...) * feature (authmethods/ldap): add proper mask_mapping to protobufs * feature (authmethods): add support to get an ldap auth method * refactor (auth/ldap): export TestGenerateCA(...) * feature (authmethods): add support to create an ldap auth method * feature (authmethods): add support to delete an ldap auth method * feature (authmethods): add support to list ldap auth methods * refactor (auth/ldap): make urls optional for NewAuthMethod(...) * refactor (auth/ldap): export ldap.TestInvalidPem * chore: make fmt changes * fix (auth/ldap): properly handle group search config Add constraints and tests to ensure when an ldap AuthMethod.EnableGroups is true, and UseTokenGroups is false; that there's a GroupDn configured for finding a user's associated groups * feature (authmethods): add support to update an ldap auth methods * chore (db/ldap): tmp mv migrations so there's no conflict with ongoing work * feature (verifier): add ldap auth method to verifier bits * fix (controller): prevent panic when controller stops when there's no listener * feature (authmethods): add support to authenticate via ldap auth methods * chore (migrations): fix whitespace in stmt * chore: fmt fixup * tests (auth/ldap): invalid err msg * feature (cli/authmethods): add support for ldap auth-methods CRUD and authenticate (#2810) * feature (authmethods): add CLI support for ldap auth methods CRUD * tests (api/auth): ldap auth method classification tests * feature (authmethods): add CLI support for ldap auth authenticate * feature (auth/ldap): set request timeouts for ldap server connections * feature (handlers/authmethods): handle u_anon listing properly. * feature (account/handers): ldap account and managed group CRUDL APIs (#2852) * feature (auth/ldap) add repository Listing of ManagedGroupMemberAccount * feature (controller/handlers): add ldapRepoFn to accounts service * feature (auth/ldap) register ldap managed group subtype * feature (account/handlers): ldap account CRUDL APIs * feature (controller/handlers): add ldapRepo to managed groups service * feature (account/handlers): ldap managed group CRUDL APIs * docs (domain): add LDAP accounts, auth-methods and managed groups (#2857) * feature (ldap/cli) add ldap accounts and managed groups CRUDL commands (#2856) * fix (handlers/authmethods): fix ldap authorized actions (#2892) * feature (cli/ldap/authenticate): use primary auth method if none is provided (#2890) * fix (auth/ldap): support setting the state attribute * feature (cli/ldap/authenticate): use primary auth method if none is provided * feature (wh/ldap) add tests for new ldap auth method and accounts (#2919) * refactor (migrations/ldap): mv to correct directory * chore: add copyright headers * fix (api/authmethods/ldap): renumber new LdapAuthMethodAttributes field * fix (auth/ldap): allow the auth method state to be updated (#2951) * chore: update sdk and api versions for llb - this is tmp until merging * tests (managed groups): add required errContains for new test
644 lines
26 KiB
PL/PgSQL
644 lines
26 KiB
PL/PgSQL
-- Copyright (c) HashiCorp, Inc.
|
|
-- SPDX-License-Identifier: MPL-2.0
|
|
|
|
begin;
|
|
|
|
create table auth_ldap_method_state_enm (
|
|
name text primary key
|
|
constraint name_only_predefined_ldap_method_states_allowed
|
|
check (name in ('inactive', 'active-private', 'active-public'))
|
|
);
|
|
comment on table auth_ldap_method_state_enm is
|
|
'auth_ldap_method_state_enm entries enumerate the valid auth ldap method states';
|
|
|
|
-- populate the values of auth_ldap_method_state_enm
|
|
insert into auth_ldap_method_state_enm(name)
|
|
values
|
|
('inactive'),
|
|
('active-private'),
|
|
('active-public');
|
|
|
|
create table auth_ldap_method (
|
|
public_id wt_public_id primary key,
|
|
scope_id wt_scope_id not null,
|
|
name wt_name,
|
|
description wt_description,
|
|
create_time wt_timestamp,
|
|
update_time wt_timestamp,
|
|
version wt_version,
|
|
state text not null
|
|
constraint auth_ldap_method_state_enm_fkey
|
|
references auth_ldap_method_state_enm(name)
|
|
on delete restrict
|
|
on update cascade,
|
|
start_tls bool not null default false,
|
|
insecure_tls bool not null default false,
|
|
discover_dn bool not null default false,
|
|
anon_group_search bool not null default false,
|
|
upn_domain text
|
|
constraint upn_domain_too_short
|
|
check (length(trim(upn_domain)) > 0)
|
|
constraint upn_domain_too_long
|
|
check (length(trim(upn_domain)) < 253),
|
|
enable_groups bool not null default false,
|
|
use_token_groups bool not null default false,
|
|
constraint auth_method_fkey
|
|
foreign key (scope_id, public_id)
|
|
references auth_method (scope_id, public_id)
|
|
on delete cascade
|
|
on update cascade,
|
|
constraint auth_ldap_method_scope_id_name_uq
|
|
unique(scope_id, name),
|
|
constraint auth_ldap_method_scope_id_public_id_uq
|
|
unique(scope_id, public_id)
|
|
);
|
|
comment on table auth_ldap_method is
|
|
'auth_ldap_method entries are the current ldap auth methods configured for '
|
|
'existing scopes';
|
|
|
|
-- auth_ldap_method column triggers
|
|
create trigger insert_auth_method_subtype before insert on auth_ldap_method
|
|
for each row execute procedure insert_auth_method_subtype();
|
|
|
|
create trigger delete_auth_method_subtype after delete on auth_ldap_method
|
|
for each row execute procedure delete_auth_method_subtype();
|
|
|
|
create trigger update_auth_method_subtype before update on auth_ldap_method
|
|
for each row execute procedure update_auth_method_subtype();
|
|
|
|
create trigger update_time_column before update on auth_ldap_method
|
|
for each row execute procedure update_time_column();
|
|
|
|
create trigger immutable_columns before update on auth_ldap_method
|
|
for each row execute procedure immutable_columns('public_id', 'scope_id', 'create_time');
|
|
|
|
create trigger default_create_time_column before insert on auth_ldap_method
|
|
for each row execute procedure default_create_time();
|
|
|
|
create trigger update_version_column after update on auth_ldap_method
|
|
for each row execute procedure update_version_column();
|
|
|
|
-- auth_ldap_url entries are LDAP URLs that specify an LDAP servers to connect
|
|
-- to. Examples: ldap://ldap.myorg.com, ldaps://ldap.myorg.com:636. There must
|
|
-- be at least one and if there's more than one URL configured for an auth
|
|
-- method, the directories will be tried in connection_priority order if there
|
|
-- are errors during the connection process. The URL scheme must be either ldap
|
|
-- or ldaps. The port is optional.If no port is specified, then a default of 389
|
|
-- is used for ldap and a default of 689 is used for ldaps. (see rfc4516 for
|
|
-- more information about LDAP URLs)
|
|
--
|
|
-- Updates will be implemented as a delete + insert with the auth_ldap_method
|
|
-- being used as the root aggregate for auth_ldap_url updates.
|
|
create table auth_ldap_url (
|
|
create_time wt_timestamp,
|
|
ldap_method_id wt_public_id not null
|
|
constraint auth_ldap_method_fkey
|
|
references auth_ldap_method(public_id)
|
|
on delete cascade
|
|
on update cascade,
|
|
url text not null
|
|
constraint url_too_short
|
|
check (length(trim(url)) > 3)
|
|
constraint url_too_long
|
|
check (length(trim(url)) < 4000),
|
|
constraint url_invalid_protocol
|
|
check (url ~ 'ldaps?:\/\/*'),
|
|
connection_priority int not null
|
|
constraint connection_priority_less_than_one
|
|
check(connection_priority >= 1),
|
|
primary key(ldap_method_id, connection_priority)
|
|
);
|
|
comment on table auth_ldap_url is
|
|
'auth_ldap_url entries specify a connection URL an LDAP';
|
|
|
|
create function auth_ldap_url_parent_children() returns trigger
|
|
as $$
|
|
declare
|
|
n integer;
|
|
begin
|
|
if tg_op = 'INSERT' or tg_op = 'UPDATE' then
|
|
select into n count(*) from auth_ldap_url where ldap_method_id = new.ldap_method_id;
|
|
if n < 1 then
|
|
raise exception 'During % of auth_ldap_url: auth_ldap_method id=% must have at least one url, not %',tg_op,new.ldap_method_id,n;
|
|
end if;
|
|
end if;
|
|
if tg_op = 'UPDATE' then
|
|
select into n count(*) from auth_ldap_url where ldap_method_id = old.ldap_method_id;
|
|
if n < 1 then
|
|
raise exception 'During % of %: auth_ldap_method id=% must have at least one url, not %',tg_op,tg_table_name,old.ldap_method_id,n;
|
|
end if;
|
|
end if;
|
|
|
|
return null;
|
|
end;
|
|
$$ language plpgsql;
|
|
comment on function auth_ldap_url_parent_children() is
|
|
'function used on auth_ldap_url after insert/update initially deferred to ensure each '
|
|
'auth_ldap_method has at least one auth_ldap_url. Unfortunately, it cannot be used on '
|
|
'delete since that would make it impossible to delete an ldap auth method, because you '
|
|
'would not be able to remove all of its urls';
|
|
|
|
create constraint trigger auth_ldap_url_children_per_parent_tg
|
|
after insert or update or delete on auth_ldap_url deferrable initially deferred
|
|
for each row execute procedure auth_ldap_url_parent_children();
|
|
|
|
create function auth_ldap_method_children() returns trigger
|
|
as $$
|
|
declare
|
|
n integer;
|
|
begin
|
|
if tg_op = 'INSERT' then
|
|
select into n count(*) from auth_ldap_url where ldap_method_id = new.public_id;
|
|
if n < 1 then
|
|
raise exception 'During % of auth_ldap_method public_id=% must have at least one url, not %',tg_op,new.public_id,n;
|
|
end if;
|
|
-- No need for an UPDATE or DELETE check, as regular referential integrity constraints
|
|
-- and the trigger on `child' will do the job.
|
|
|
|
return null;
|
|
end if;
|
|
end;
|
|
$$ language plpgsql;
|
|
comment on function auth_ldap_method_children() is
|
|
'function used on auth_ldap_method after insert initially deferred to ensure each '
|
|
'auth_ldap_method has at least one auth_ldap_url';
|
|
|
|
create constraint trigger auth_ldap_method_children_tg
|
|
after insert on auth_ldap_method deferrable initially deferred
|
|
for each row execute procedure auth_ldap_method_children();
|
|
|
|
-- auth_ldap_user_entry_search entries specify the required parameters to find a
|
|
-- user entry before attempting to authenticate the user.
|
|
--
|
|
-- Updates will be implemented as a delete + insert with the auth_ldap_method
|
|
-- being used as the root aggregate for auth_ldap_user_entry_search updates.
|
|
create table auth_ldap_user_entry_search (
|
|
create_time wt_timestamp,
|
|
ldap_method_id wt_public_id primary key
|
|
constraint auth_ldap_method_fkey
|
|
references auth_ldap_method(public_id)
|
|
on delete cascade
|
|
on update cascade,
|
|
user_dn text
|
|
constraint user_dn_too_short
|
|
check (length(trim(user_dn)) > 0)
|
|
constraint user_dn_too_long
|
|
check (length(trim(user_dn)) < 1025),
|
|
user_attr text
|
|
constraint user_attr_too_short
|
|
check (length(trim(user_attr)) > 0)
|
|
constraint user_attr_too_long
|
|
check (length(trim(user_attr)) < 1025),
|
|
user_filter text
|
|
constraint user_filter_too_short
|
|
check (length(trim(user_filter)) > 0)
|
|
constraint user_filter_too_long
|
|
check (length(trim(user_filter)) < 2049),
|
|
constraint all_fields_are_not_null
|
|
check (
|
|
not(user_dn, user_attr, user_filter) is null
|
|
)
|
|
);
|
|
comment on table auth_ldap_user_entry_search is
|
|
'auth_ldap_user_entry_search entries specify the required parameters to find '
|
|
'a user entry before attempting to authenticate the user';
|
|
|
|
-- auth_ldap_group_entry_search entries specify the required parameters to find
|
|
-- the groups a user is a member of
|
|
--
|
|
-- Updates will be implemented as a delete + insert with the auth_ldap_method
|
|
-- being used as the root aggregate for auth_ldap_user_entry_search updates.
|
|
create table auth_ldap_group_entry_search (
|
|
create_time wt_timestamp,
|
|
ldap_method_id wt_public_id primary key
|
|
constraint auth_ldap_method_fkey
|
|
references auth_ldap_method(public_id)
|
|
on delete cascade
|
|
on update cascade,
|
|
group_dn text not null -- required
|
|
constraint group_dn_too_short
|
|
check (length(trim(group_dn)) > 0)
|
|
constraint group_dn_too_long
|
|
check (length(trim(group_dn)) < 1025),
|
|
group_attr text
|
|
constraint group_attr_too_short
|
|
check (length(trim(group_attr)) > 0)
|
|
constraint group_attr_too_long
|
|
check (length(trim(group_attr)) < 1025),
|
|
group_filter text
|
|
constraint group_filter_too_short
|
|
check (length(trim(group_filter)) > 0)
|
|
constraint group_filter_too_long
|
|
check (length(trim(group_filter)) < 2049)
|
|
);
|
|
comment on table auth_ldap_group_entry_search is
|
|
'auth_ldap_group_entry_search entries specify the required parameters to find '
|
|
'the groups a user is a member of';
|
|
|
|
create function auth_ldap_method_group_search() returns trigger
|
|
as $$
|
|
declare
|
|
n integer;
|
|
begin
|
|
if new.enable_groups = true and new.use_token_groups = false then
|
|
select into n count(*) from auth_ldap_group_entry_search where ldap_method_id = new.public_id;
|
|
if n < 1 then
|
|
raise exception 'During % of auth_ldap_method public_id=% must have a configured group_dn when enable_groups = true and use_token_groups = false',tg_op,new.public_id;
|
|
end if;
|
|
end if;
|
|
return null;
|
|
end;
|
|
$$ language plpgsql;
|
|
comment on function auth_ldap_method_children() is
|
|
'function used on auth_ldap_method after insert/update initially deferred to ensure each '
|
|
'groups search is properly configured when enable_groups is true and use_token_groups is false';
|
|
|
|
create constraint trigger auth_ldap_method_group_search
|
|
after insert or update on auth_ldap_method deferrable initially deferred
|
|
for each row execute procedure auth_ldap_method_group_search();
|
|
|
|
-- auth_ldap_certificate entries are optional PEM encoded x509 certificates.
|
|
-- Each entry is a single certificate. An ldap auth method may have 0 or more
|
|
-- of these optional x509s. If an auth method has any cert entries, they are
|
|
-- used as trust anchors when connecting to the auth method's ldap provider
|
|
-- (instead of the host system's cert chain).
|
|
create table auth_ldap_certificate (
|
|
create_time wt_timestamp,
|
|
ldap_method_id wt_public_id not null
|
|
constraint auth_ldap_method_fkey
|
|
references auth_ldap_method(public_id)
|
|
on delete cascade
|
|
on update cascade,
|
|
certificate bytea not null
|
|
constraint certificate_must_not_be_empty
|
|
check(length(certificate) > 0),
|
|
primary key(ldap_method_id, certificate)
|
|
);
|
|
comment on table auth_ldap_certificate is
|
|
'auth_ldap_certificate entries are optional PEM encoded x509 certificates. '
|
|
'Each entry is a single certificate. An ldap auth method may have 0 or more '
|
|
'of these optional x509s. If an auth method has any cert entries, they are '
|
|
'used as trust anchors when connecting to the auth methods ldap provider '
|
|
'(instead of the host system cert chain)';
|
|
|
|
create table auth_ldap_client_certificate (
|
|
create_time wt_timestamp,
|
|
ldap_method_id wt_public_id primary key
|
|
constraint auth_ldap_method_fkey
|
|
references auth_ldap_method (public_id)
|
|
on delete cascade
|
|
on update cascade,
|
|
certificate bytea not null -- PEM encoded certificate
|
|
constraint certificate_must_not_be_empty
|
|
check(length(certificate) > 0),
|
|
certificate_key bytea not null -- encrypted PEM encoded private key for certificate
|
|
constraint certificate_key_must_not_be_empty
|
|
check(length(certificate_key) > 0),
|
|
certificate_key_hmac bytea not null
|
|
constraint certificate_key_hmac_must_not_be_empty
|
|
check(length(certificate_key_hmac) > 0),
|
|
key_id text not null
|
|
constraint kms_data_key_version_fkey
|
|
references kms_data_key_version (private_id)
|
|
on delete restrict
|
|
on update cascade
|
|
);
|
|
comment on table auth_ldap_client_certificate is
|
|
'auth_ldap_client_certificate entries contains a client certificate that a '
|
|
'auth_ldap_method uses for mTLS when connecting to an LDAP server. '
|
|
'An auth_ldap_method can have 0 or 1 client certificates.';
|
|
|
|
create table auth_ldap_bind_credential (
|
|
create_time wt_timestamp,
|
|
ldap_method_id wt_public_id primary key
|
|
constraint auth_ldap_method_fkey
|
|
references auth_ldap_method (public_id)
|
|
on delete cascade
|
|
on update cascade,
|
|
dn text not null
|
|
constraint dn_too_short
|
|
check (length(trim(dn)) > 0)
|
|
constraint dn_too_long
|
|
check (length(trim(dn)) < 2049),
|
|
password bytea not null
|
|
constraint password_not_empty
|
|
check(length(password) > 0), -- encrypted password0
|
|
password_hmac bytea not null
|
|
constraint password_hmac_not_empty
|
|
check(length(password_hmac) > 0),
|
|
key_id text not null
|
|
constraint kms_data_key_version_fkey
|
|
references kms_data_key_version (private_id)
|
|
on delete restrict
|
|
on update cascade
|
|
);
|
|
comment on table auth_ldap_bind_credential is
|
|
'auth_ldap_bind_credential entries allow Boundary to bind (aka authenticate) using '
|
|
'the provided credentials when searching for the user entry used to authenticate.';
|
|
|
|
-- auth_ldap_account_attribute_map entries are the optional attribute maps from custom
|
|
-- attributes to the standard attribute of fullname and email. There can be 0 or more
|
|
-- for each parent ldap auth method.
|
|
create table auth_ldap_account_attribute_map (
|
|
create_time wt_timestamp,
|
|
ldap_method_id wt_public_id
|
|
constraint auth_ldap_method_fkey
|
|
references auth_ldap_method(public_id)
|
|
on delete cascade
|
|
on update cascade,
|
|
from_attribute text not null
|
|
constraint from_attribute_must_not_be_empty
|
|
check(length(trim(from_attribute)) > 0)
|
|
constraint from_attribute_must_be_less_than_1024_chars
|
|
check(length(trim(from_attribute)) < 1024),
|
|
to_attribute text not null
|
|
constraint to_attribute_valid_values
|
|
check (lower(to_attribute) in ('fullname', 'email')), -- intentionally case-sensitive matching
|
|
primary key(ldap_method_id, to_attribute)
|
|
);
|
|
comment on table auth_ldap_account_attribute_map is
|
|
'auth_ldap_account_attribute_map entries are the optional attribute maps from custom attributes to '
|
|
'the standard attributes of sub, name and email. There can be 0 or more for each parent ldap auth method.';
|
|
|
|
create trigger default_create_time_column before insert on auth_ldap_account_attribute_map
|
|
for each row execute procedure default_create_time();
|
|
|
|
create trigger immutable_columns before update on auth_ldap_account_attribute_map
|
|
for each row execute procedure immutable_columns('ldap_method_id', 'from_attribute', 'to_attribute', 'create_time');
|
|
|
|
create table auth_ldap_account (
|
|
public_id wt_public_id primary key,
|
|
auth_method_id wt_public_id not null,
|
|
-- NOTE(mgaffney): The scope_id type is not wt_scope_id because the domain
|
|
-- check is executed before the insert trigger which retrieves the scope_id
|
|
-- causing an insert to fail.
|
|
scope_id text not null,
|
|
name wt_name,
|
|
description wt_description,
|
|
create_time wt_timestamp,
|
|
update_time wt_timestamp,
|
|
version wt_version,
|
|
login_name text not null
|
|
constraint login_name_must_be_lowercase
|
|
check(lower(trim(login_name)) = login_name)
|
|
constraint login_name_must_not_be_empty
|
|
check(length(trim(login_name)) > 0),
|
|
email wt_email,
|
|
full_name wt_full_name,
|
|
dn text -- will be null until the first successful authentication
|
|
constraint dn_must_not_be_empty
|
|
check(length(trim(dn)) > 0),
|
|
member_of_groups jsonb -- will be null until the first successful authentication
|
|
constraint member_of_groups_must_not_be_empty
|
|
check(length(trim(member_of_groups::text)) > 0),
|
|
constraint auth_ldap_method_fkey
|
|
foreign key (scope_id, auth_method_id)
|
|
references auth_ldap_method (scope_id, public_id)
|
|
on delete cascade
|
|
on update cascade,
|
|
constraint auth_account_fkey
|
|
foreign key (scope_id, auth_method_id, public_id)
|
|
references auth_account (scope_id, auth_method_id, public_id)
|
|
on delete cascade
|
|
on update cascade,
|
|
constraint auth_ldap_account_auth_method_id_name_uq
|
|
unique(auth_method_id, name),
|
|
constraint auth_ldap_account_auth_method_id_login_name_uq
|
|
unique(auth_method_id, login_name),
|
|
constraint auth_ldap_account_auth_method_id_dn_uq
|
|
unique(auth_method_id, dn),
|
|
constraint auth_ldap_account_auth_method_id_public_id_uq
|
|
unique(auth_method_id, public_id)
|
|
);
|
|
comment on table auth_ldap_account is
|
|
'auth_ldap_account entries are subtypes of auth_account and represent an ldap account.';
|
|
|
|
-- insert_auth_ldap_account_subtype is intended as a before insert
|
|
-- trigger on auth_ldap_account. Its purpose is to insert a base
|
|
-- auth_account for new ldap accounts. It's a bit different than the
|
|
-- standard trigger for this, because it will have conflicting PKs
|
|
-- and we just want to "do nothing" on those conflicts, deferring the
|
|
-- raising on an error to insert into the auth_ldap_account table.
|
|
-- this is all necessary because of we're using predictable public ids
|
|
-- for ldap accounts.
|
|
create or replace function insert_auth_ldap_account_subtype() returns trigger
|
|
as $$
|
|
begin
|
|
select auth_method.scope_id
|
|
into new.scope_id
|
|
from auth_method
|
|
where auth_method.public_id = new.auth_method_id;
|
|
|
|
insert into auth_account
|
|
(public_id, auth_method_id, scope_id)
|
|
values
|
|
(new.public_id, new.auth_method_id, new.scope_id)
|
|
on conflict do nothing;
|
|
|
|
return new;
|
|
end;
|
|
$$ language plpgsql;
|
|
|
|
create trigger insert_auth_ldap_account_subtype before insert on auth_ldap_account
|
|
for each row execute procedure insert_auth_ldap_account_subtype();
|
|
|
|
create trigger delete_auth_account_subtype after delete on auth_ldap_account
|
|
for each row execute procedure delete_auth_account_subtype();
|
|
|
|
create trigger update_time_column before update on auth_ldap_account
|
|
for each row execute procedure update_time_column();
|
|
|
|
create trigger immutable_columns before update on auth_ldap_account
|
|
for each row execute procedure immutable_columns('public_id', 'auth_method_id', 'scope_id', 'create_time', 'login_name');
|
|
|
|
create trigger default_create_time_column before insert on auth_ldap_account
|
|
for each row execute procedure default_create_time();
|
|
|
|
create trigger update_version_column after update on auth_ldap_account
|
|
for each row execute procedure update_version_column();
|
|
|
|
|
|
insert into oplog_ticket (name, version)
|
|
values
|
|
('auth_ldap_method', 1), -- auth_ldap_method is the root aggregate itself and all of its value objects.
|
|
('auth_ldap_account', 1),
|
|
('auth_ldap_managed_group', 1);
|
|
|
|
|
|
-- ldap_auth_method_with_value_obj is useful for reading an ldap auth method
|
|
-- with its associated value objects (urls, certs, search config, etc). The use
|
|
-- of the postgres string_agg(...) to aggregate the url and cert value objects
|
|
-- into a column works because we are only pulling in one column from the
|
|
-- associated tables and that value is part of the primary key and unique. This
|
|
-- view will make things like recursive listing of ldap auth methods fairly
|
|
-- straightforward to implement for the ldap repo. The view also includes an
|
|
-- is_primary_auth_method bool
|
|
create view ldap_auth_method_with_value_obj as
|
|
select
|
|
case when s.primary_auth_method_id is not null then
|
|
true
|
|
else false end
|
|
as is_primary_auth_method,
|
|
am.public_id,
|
|
am.scope_id,
|
|
am.name,
|
|
am.description,
|
|
am.create_time,
|
|
am.update_time,
|
|
am.version,
|
|
am.state,
|
|
am.start_tls,
|
|
am.insecure_tls,
|
|
am.discover_dn,
|
|
am.anon_group_search,
|
|
am.upn_domain,
|
|
am.enable_groups,
|
|
am.use_token_groups,
|
|
-- the string_agg(..) column will be null if there are no associated value objects
|
|
string_agg(distinct url.url, '|') as urls,
|
|
string_agg(distinct cert.certificate, '|') as certs,
|
|
string_agg(distinct concat_ws('=', aam.from_attribute, aam.to_attribute), '|') as account_attribute_map,
|
|
|
|
-- the rest of the fields are zero to one relationships that are stored in
|
|
-- related tables. Since we're outer joining with these tables, we need to
|
|
-- either add them to the group by, use an aggregating func, or handle
|
|
-- multiple rows returning for each auth method. I've chosen to just use
|
|
-- string_agg(...)
|
|
string_agg(distinct uc.user_dn, '|') as user_dn,
|
|
string_agg(distinct uc.user_attr, '|') as user_attr,
|
|
string_agg(distinct uc.user_filter, '|') as user_filter,
|
|
string_agg(distinct gc.group_dn, '|') as group_dn,
|
|
string_agg(distinct gc.group_attr, '|') as group_attr,
|
|
string_agg(distinct gc.group_filter, '|') as group_filter,
|
|
string_agg(distinct cc.certificate_key, '|') as client_certificate_key,
|
|
string_agg(distinct cc.certificate_key_hmac, '|') as client_certificate_key_hmac,
|
|
string_agg(distinct cc.key_id, '|') as client_certificate_key_id,
|
|
string_agg(distinct cc.certificate, '|') as client_certificate_cert,
|
|
string_agg(distinct bc.dn, '|') as bind_dn,
|
|
string_agg(distinct bc.password, '|') as bind_password,
|
|
string_agg(distinct bc.password_hmac, '|') as bind_password_hmac,
|
|
string_agg(distinct bc.key_id, '|') as bind_password_key_id
|
|
from
|
|
auth_ldap_method am
|
|
left outer join iam_scope s on am.public_id = s.primary_auth_method_id
|
|
left outer join auth_ldap_url url on am.public_id = url.ldap_method_id
|
|
left outer join auth_ldap_certificate cert on am.public_id = cert.ldap_method_id
|
|
left outer join auth_ldap_account_attribute_map aam on am.public_id = aam.ldap_method_id
|
|
left outer join auth_ldap_user_entry_search uc on am.public_id = uc.ldap_method_id
|
|
left outer join auth_ldap_group_entry_search gc on am.public_id = gc.ldap_method_id
|
|
left outer join auth_ldap_client_certificate cc on am.public_id = cc.ldap_method_id
|
|
left outer join auth_ldap_bind_credential bc on am.public_id = bc.ldap_method_id
|
|
group by am.public_id, is_primary_auth_method; -- there can be only one public_id + is_primary_auth_method, so group by isn't a problem.
|
|
comment on view ldap_auth_method_with_value_obj is
|
|
'ldap auth method with its associated value objects (urls, certs, search config, etc)';
|
|
|
|
create table auth_ldap_managed_group (
|
|
public_id wt_public_id primary key,
|
|
auth_method_id wt_public_id not null,
|
|
name wt_name,
|
|
description wt_description,
|
|
create_time wt_timestamp,
|
|
update_time wt_timestamp,
|
|
version wt_version,
|
|
group_names jsonb not null
|
|
constraint group_names_must_not_be_empty
|
|
check(length(trim(group_names::text)) > 0),
|
|
constraint auth_ldap_method_fkey
|
|
foreign key (auth_method_id) -- fk1
|
|
references auth_ldap_method (public_id)
|
|
on delete cascade
|
|
on update cascade,
|
|
-- Ensure it relates to an abstract managed group
|
|
constraint auth_managed_group_fkey
|
|
foreign key (auth_method_id, public_id) -- fk2
|
|
references auth_managed_group (auth_method_id, public_id)
|
|
on delete cascade
|
|
on update cascade,
|
|
constraint auth_ldap_managed_group_auth_method_id_name_uq
|
|
unique(auth_method_id, name)
|
|
);
|
|
comment on table auth_ldap_managed_group is
|
|
'auth_ldap_managed_group entries are subtypes of auth_managed_group and represent an ldap managed group.';
|
|
|
|
-- Define the immutable fields of auth_ldap_managed_group
|
|
create trigger immutable_columns before update on auth_ldap_managed_group
|
|
for each row execute procedure immutable_columns('public_id', 'auth_method_id', 'create_time');
|
|
|
|
-- Populate create time on insert
|
|
create trigger default_create_time_column before insert on auth_ldap_managed_group
|
|
for each row execute procedure default_create_time();
|
|
|
|
-- Generate update time on update
|
|
create trigger update_time_column before update on auth_ldap_managed_group
|
|
for each row execute procedure update_time_column();
|
|
|
|
-- Update version when something changes
|
|
create trigger update_version_column after update on auth_ldap_managed_group
|
|
for each row execute procedure update_version_column();
|
|
|
|
-- Add into the base table when inserting into the concrete table
|
|
create trigger insert_managed_group_subtype before insert on auth_ldap_managed_group
|
|
for each row execute procedure insert_managed_group_subtype();
|
|
|
|
-- Ensure that deletions in the ldap subtype result in deletions to the base
|
|
-- table.
|
|
create trigger delete_managed_group_subtype after delete on auth_ldap_managed_group
|
|
for each row execute procedure delete_managed_group_subtype();
|
|
|
|
|
|
-- auth_ldap_managed_group_member_account uses CTEs to expand and "normalize" the jsonb column
|
|
-- containing groups in both the accounts and managed groups, then it joins these
|
|
-- "normalized" expressions into a join table of mangagd group member account entries
|
|
create view auth_ldap_managed_group_member_account as
|
|
with
|
|
account(id, group_name) as (
|
|
select
|
|
a.public_id, ag.group_name
|
|
from
|
|
auth_ldap_account a
|
|
left join jsonb_array_elements(a.member_of_groups) as ag(group_name) on true
|
|
),
|
|
groups (create_time, id, group_name) as (
|
|
select
|
|
g.create_time,
|
|
g.public_id,
|
|
mg.group_name
|
|
from
|
|
auth_ldap_managed_group g
|
|
left join jsonb_array_elements(g.group_names) as mg(group_name) on true
|
|
)
|
|
select distinct
|
|
groups.create_time,
|
|
account.id as member_id,
|
|
groups.id as managed_group_id
|
|
from account, groups
|
|
where account.group_name = groups.group_name;
|
|
comment on view auth_ldap_managed_group_member_account is
|
|
'auth_ldap_managed_group_member_account is the join view for '
|
|
'managed ldap groups and accounts';
|
|
|
|
|
|
-- recreate view defined in postgres/9/03_oidc_managed_group_member.up.sql
|
|
-- so the new view can include both oidc and ldap managed groups
|
|
drop view auth_managed_group_member_account;
|
|
|
|
-- create view with both oidc and ldap managed groups; we can replace this view
|
|
-- to union with other subtype tables as needed in the future.
|
|
create view auth_managed_group_member_account as
|
|
select
|
|
oidc.create_time,
|
|
oidc.managed_group_id,
|
|
oidc.member_id
|
|
from
|
|
auth_oidc_managed_group_member_account oidc
|
|
union
|
|
select
|
|
ldap.create_time,
|
|
ldap.managed_group_id,
|
|
ldap.member_id
|
|
from
|
|
auth_ldap_managed_group_member_account ldap;
|
|
comment on view auth_managed_group_member_account is
|
|
'';
|
|
|
|
commit; |