Merge branch 'main' into plugin-hostcatalogs
This commit is contained in:
commit
252d64f364
58 files changed
+3496
-1079
No files matched your search
@@ -137,6 +137,11 @@ protobuild:
|
||||
@protoc-go-inject-tag -input=./internal/credential/store/credential.pb.go
|
||||
@protoc-go-inject-tag -input=./internal/credential/vault/store/vault.pb.go
|
||||
|
||||
# these protos, services and openapi artifacts are purely for testing purposes
|
||||
@protoc-go-inject-tag -input=./internal/gen/testing/event/event.pb.go
|
||||
@protoc --proto_path=internal/proto/local --proto_path=internal/proto/third_party --openapiv2_out=json_names_for_fields=false,logtostderr=true,disable_default_errors=true,include_package_in_tags=true,fqn_for_openapi_name=true,allow_merge,merge_file_name=testing:internal/gen/testing/event/. internal/proto/local/testing/event/v1/*.proto
|
||||
|
||||
|
||||
@rm -R ${TMP_DIR}
|
||||
|
||||
protolint:
|
||||
|
||||
@@ -24,6 +24,7 @@ require (
|
||||
github.com/hashicorp/dawdle v0.4.0
|
||||
github.com/hashicorp/dbassert v0.0.0-20200930125617-6218396928df
|
||||
github.com/hashicorp/eventlogger v0.1.0
|
||||
github.com/hashicorp/eventlogger/filters/encrypt v0.1.3
|
||||
github.com/hashicorp/go-bexpr v0.1.9
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2
|
||||
github.com/hashicorp/go-hclog v0.16.2
|
||||
@@ -55,6 +56,7 @@ require (
|
||||
github.com/mattn/go-colorable v0.1.8
|
||||
github.com/mattn/go-isatty v0.0.13 // indirect
|
||||
github.com/mitchellh/cli v1.1.2
|
||||
github.com/mitchellh/copystructure v1.2.0
|
||||
github.com/mitchellh/go-wordwrap v1.0.1
|
||||
github.com/mitchellh/gox v1.0.1
|
||||
github.com/mitchellh/mapstructure v1.4.1
|
||||
|
||||
@@ -33,7 +33,7 @@ func Test_GetOpts(t *testing.T) {
|
||||
t.Run("WithEventerConfig", func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
c := event.EventerConfig{
|
||||
Sinks: []event.SinkConfig{
|
||||
Sinks: []*event.SinkConfig{
|
||||
// not a valid sink, but it doesn't need to be to test the
|
||||
// option is properly supported.
|
||||
{
|
||||
|
||||
@@ -123,7 +123,7 @@ func TestServer_SetupEventing(t *testing.T) {
|
||||
logger: testLogger,
|
||||
lock: testLock,
|
||||
opt: []Option{WithEventerConfig(&event.EventerConfig{
|
||||
Sinks: []event.SinkConfig{
|
||||
Sinks: []*event.SinkConfig{
|
||||
{
|
||||
Format: "invalid-format",
|
||||
},
|
||||
|
||||
@@ -487,10 +487,10 @@ func parseEventing(eventObj *ast.ObjectItem) (*event.EventerConfig, error) {
|
||||
}
|
||||
|
||||
// Append to result
|
||||
result.Sinks = append(result.Sinks, s)
|
||||
result.Sinks = append(result.Sinks, &s)
|
||||
}
|
||||
if len(result.Sinks) == 0 {
|
||||
result.Sinks = []event.SinkConfig{event.DefaultSink()}
|
||||
result.Sinks = []*event.SinkConfig{event.DefaultSink()}
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
@@ -347,7 +347,7 @@ func TestController_EventingConfig(t *testing.T) {
|
||||
wantEventerConfig: &event.EventerConfig{
|
||||
AuditEnabled: true,
|
||||
ObservationsEnabled: false,
|
||||
Sinks: []event.SinkConfig{
|
||||
Sinks: []*event.SinkConfig{
|
||||
event.DefaultSink(),
|
||||
},
|
||||
},
|
||||
@@ -362,7 +362,7 @@ func TestController_EventingConfig(t *testing.T) {
|
||||
wantEventerConfig: &event.EventerConfig{
|
||||
AuditEnabled: false,
|
||||
ObservationsEnabled: true,
|
||||
Sinks: []event.SinkConfig{
|
||||
Sinks: []*event.SinkConfig{
|
||||
event.DefaultSink(),
|
||||
},
|
||||
},
|
||||
@@ -470,7 +470,7 @@ func TestController_EventingConfig(t *testing.T) {
|
||||
wantEventerConfig: &event.EventerConfig{
|
||||
AuditEnabled: false,
|
||||
ObservationsEnabled: true,
|
||||
Sinks: []event.SinkConfig{
|
||||
Sinks: []*event.SinkConfig{
|
||||
{
|
||||
Type: "file",
|
||||
Name: "configured-sink",
|
||||
|
||||
@@ -0,0 +1,449 @@
|
||||
begin;
|
||||
alter table wh_date_dimension
|
||||
rename column id to key;
|
||||
|
||||
alter table wh_time_of_day_dimension
|
||||
rename column id to key;
|
||||
|
||||
alter table wh_host_dimension
|
||||
rename column id to key;
|
||||
|
||||
alter table wh_user_dimension
|
||||
rename column id to key;
|
||||
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column host_id to host_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column user_id to user_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_pending_date_id to session_pending_date_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_pending_time_id to session_pending_time_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_active_date_id to session_active_date_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_active_time_id to session_active_time_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_canceling_date_id to session_canceling_date_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_canceling_time_id to session_canceling_time_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_terminated_date_id to session_terminated_date_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_terminated_time_id to session_terminated_time_key;
|
||||
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column host_id to host_key;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column user_id to user_key;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column connection_authorized_date_id to connection_authorized_date_key;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column connection_authorized_time_id to connection_authorized_time_key;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column connection_connected_date_id to connection_connected_date_key;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column connection_connected_time_id to connection_connected_time_key;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column connection_closed_date_id to connection_closed_date_key;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column connection_closed_time_id to connection_closed_time_key;
|
||||
|
||||
-- rename function from internal/db/schema/migrations/postgres/0/60_wh_domain_types.up.sql
|
||||
alter function wh_dim_id rename to wh_dim_key;
|
||||
|
||||
-- rename domain from internal/db/schema/migrations/postgres/0/60_wh_domain_types.up.sql
|
||||
alter domain wh_dim_id rename to wh_dim_key;
|
||||
|
||||
-- removes unused function from internal/db/schema/migrations/postgres/0/60_wh_domain_types.up.sql
|
||||
drop function wh_current_date_id;
|
||||
|
||||
-- removes unused function from internal/db/schema/migrations/postgres/0/60_wh_domain_types.up.sql
|
||||
drop function wh_current_time_id;
|
||||
|
||||
-- rename function from internal/db/schema/migrations/postgres/0/60_wh_domain_types.up.sql
|
||||
alter function wh_date_id rename to wh_date_key;
|
||||
|
||||
-- rename function from internal/db/schema/migrations/postgres/0/60_wh_domain_types.up.sql
|
||||
alter function wh_time_id rename to wh_time_key;
|
||||
|
||||
-- replaces view from 14/01_wh_user_dimension_oidc.up.sql
|
||||
drop view whx_user_dimension_target;
|
||||
create view whx_user_dimension_target as
|
||||
select key,
|
||||
user_id,
|
||||
user_name,
|
||||
user_description,
|
||||
auth_account_id,
|
||||
auth_account_type,
|
||||
auth_account_name,
|
||||
auth_account_description,
|
||||
auth_account_external_id,
|
||||
auth_account_full_name,
|
||||
auth_account_email,
|
||||
auth_method_id,
|
||||
auth_method_type,
|
||||
auth_method_name,
|
||||
auth_method_description,
|
||||
auth_method_external_id,
|
||||
user_organization_id,
|
||||
user_organization_name,
|
||||
user_organization_description
|
||||
from wh_user_dimension
|
||||
where current_row_indicator = 'Current'
|
||||
;
|
||||
|
||||
-- replaces function from 14/01_wh_user_dimension_oidc.up.sql
|
||||
drop function wh_upsert_user;
|
||||
create function wh_upsert_user(p_user_id wt_user_id, p_auth_token_id wt_public_id)
|
||||
returns wh_dim_key
|
||||
as $$
|
||||
declare
|
||||
src whx_user_dimension_target%rowtype;
|
||||
target whx_user_dimension_target%rowtype;
|
||||
new_row wh_user_dimension%rowtype;
|
||||
acct_id wt_public_id;
|
||||
begin
|
||||
select auth_account_id into strict acct_id
|
||||
from auth_token
|
||||
where public_id = p_auth_token_id;
|
||||
|
||||
select * into target
|
||||
from whx_user_dimension_target as t
|
||||
where t.user_id = p_user_id
|
||||
and t.auth_account_id = acct_id;
|
||||
|
||||
select target.key, t.* into src
|
||||
from whx_user_dimension_source as t
|
||||
where t.user_id = p_user_id
|
||||
and t.auth_account_id = acct_id;
|
||||
|
||||
if src is distinct from target then
|
||||
|
||||
-- expire the current row
|
||||
update wh_user_dimension
|
||||
set current_row_indicator = 'Expired',
|
||||
row_expiration_time = current_timestamp
|
||||
where user_id = p_user_id
|
||||
and auth_account_id = acct_id
|
||||
and current_row_indicator = 'Current';
|
||||
|
||||
-- insert a new row
|
||||
insert into wh_user_dimension (
|
||||
user_id, user_name, user_description,
|
||||
auth_account_id, auth_account_type, auth_account_name, auth_account_description,
|
||||
auth_account_external_id, auth_account_full_name, auth_account_email,
|
||||
auth_method_id, auth_method_type, auth_method_name, auth_method_description,
|
||||
auth_method_external_id,
|
||||
user_organization_id, user_organization_name, user_organization_description,
|
||||
current_row_indicator, row_effective_time, row_expiration_time
|
||||
)
|
||||
select user_id, user_name, user_description,
|
||||
auth_account_id, auth_account_type, auth_account_name, auth_account_description,
|
||||
auth_account_external_id, auth_account_full_name, auth_account_email,
|
||||
auth_method_id, auth_method_type, auth_method_name, auth_method_description,
|
||||
auth_method_external_id,
|
||||
user_organization_id, user_organization_name, user_organization_description,
|
||||
'Current', current_timestamp, 'infinity'::timestamptz
|
||||
from whx_user_dimension_source
|
||||
where user_id = p_user_id
|
||||
and auth_account_id = acct_id
|
||||
returning * into new_row;
|
||||
|
||||
return new_row.key;
|
||||
end if;
|
||||
return target.key;
|
||||
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- replaces view from 0/65_wh_session_dimensions.up.sql
|
||||
drop view whx_host_dimension_target;
|
||||
create view whx_host_dimension_target as
|
||||
select key,
|
||||
host_id,
|
||||
host_type,
|
||||
host_name,
|
||||
host_description,
|
||||
host_address,
|
||||
host_set_id,
|
||||
host_set_type,
|
||||
host_set_name,
|
||||
host_set_description,
|
||||
host_catalog_id,
|
||||
host_catalog_type,
|
||||
host_catalog_name,
|
||||
host_catalog_description,
|
||||
target_id,
|
||||
target_type,
|
||||
target_name,
|
||||
target_description,
|
||||
target_default_port_number,
|
||||
target_session_max_seconds,
|
||||
target_session_connection_limit,
|
||||
project_id,
|
||||
project_name,
|
||||
project_description,
|
||||
host_organization_id,
|
||||
host_organization_name,
|
||||
host_organization_description
|
||||
from wh_host_dimension
|
||||
where current_row_indicator = 'Current'
|
||||
;
|
||||
|
||||
-- replaces function from 0/66_wh_session_dimensions.up.sql
|
||||
drop function wh_upsert_host;
|
||||
create function wh_upsert_host(p_host_id wt_public_id, p_host_set_id wt_public_id, p_target_id wt_public_id)
|
||||
returns wh_dim_key
|
||||
as $$
|
||||
declare
|
||||
src whx_host_dimension_target%rowtype;
|
||||
target whx_host_dimension_target%rowtype;
|
||||
new_row wh_host_dimension%rowtype;
|
||||
begin
|
||||
select * into target
|
||||
from whx_host_dimension_target as t
|
||||
where t.host_id = p_host_id
|
||||
and t.host_set_id = p_host_set_id
|
||||
and t.target_id = p_target_id;
|
||||
|
||||
select target.key, t.* into src
|
||||
from whx_host_dimension_source as t
|
||||
where t.host_id = p_host_id
|
||||
and t.host_set_id = p_host_set_id
|
||||
and t.target_id = p_target_id;
|
||||
|
||||
if src is distinct from target then
|
||||
|
||||
-- expire the current row
|
||||
update wh_host_dimension
|
||||
set current_row_indicator = 'Expired',
|
||||
row_expiration_time = current_timestamp
|
||||
where host_id = p_host_id
|
||||
and host_set_id = p_host_set_id
|
||||
and target_id = p_target_id
|
||||
and current_row_indicator = 'Current';
|
||||
|
||||
-- insert a new row
|
||||
insert into wh_host_dimension (
|
||||
host_id, host_type, host_name, host_description, host_address,
|
||||
host_set_id, host_set_type, host_set_name, host_set_description,
|
||||
host_catalog_id, host_catalog_type, host_catalog_name, host_catalog_description,
|
||||
target_id, target_type, target_name, target_description,
|
||||
target_default_port_number, target_session_max_seconds, target_session_connection_limit,
|
||||
project_id, project_name, project_description,
|
||||
host_organization_id, host_organization_name, host_organization_description,
|
||||
current_row_indicator, row_effective_time, row_expiration_time
|
||||
)
|
||||
select host_id, host_type, host_name, host_description, host_address,
|
||||
host_set_id, host_set_type, host_set_name, host_set_description,
|
||||
host_catalog_id, host_catalog_type, host_catalog_name, host_catalog_description,
|
||||
target_id, target_type, target_name, target_description,
|
||||
target_default_port_number, target_session_max_seconds, target_session_connection_limit,
|
||||
project_id, project_name, project_description,
|
||||
host_organization_id, host_organization_name, host_organization_description,
|
||||
'Current', current_timestamp, 'infinity'::timestamptz
|
||||
from whx_host_dimension_source
|
||||
where host_id = p_host_id
|
||||
and host_set_id = p_host_set_id
|
||||
and target_id = p_target_id
|
||||
returning * into new_row;
|
||||
|
||||
return new_row.key;
|
||||
end if;
|
||||
return target.key;
|
||||
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- replaces function from 0/69_wh_session_facts.up.sql
|
||||
drop trigger wh_insert_session on session;
|
||||
drop function wh_insert_session;
|
||||
create function wh_insert_session()
|
||||
returns trigger
|
||||
as $$
|
||||
declare
|
||||
new_row wh_session_accumulating_fact%rowtype;
|
||||
begin
|
||||
with
|
||||
pending_timestamp (date_dim_key, time_dim_key, ts) as (
|
||||
select wh_date_key(start_time), wh_time_key(start_time), start_time
|
||||
from session_state
|
||||
where session_id = new.public_id
|
||||
and state = 'pending'
|
||||
)
|
||||
insert into wh_session_accumulating_fact (
|
||||
session_id,
|
||||
auth_token_id,
|
||||
host_key,
|
||||
user_key,
|
||||
session_pending_date_key,
|
||||
session_pending_time_key,
|
||||
session_pending_time
|
||||
)
|
||||
select new.public_id,
|
||||
new.auth_token_id,
|
||||
wh_upsert_host(new.host_id, new.host_set_id, new.target_id),
|
||||
wh_upsert_user(new.user_id, new.auth_token_id),
|
||||
pending_timestamp.date_dim_key,
|
||||
pending_timestamp.time_dim_key,
|
||||
pending_timestamp.ts
|
||||
from pending_timestamp
|
||||
returning * into strict new_row;
|
||||
return null;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
create trigger wh_insert_session
|
||||
after insert on session
|
||||
for each row
|
||||
execute function wh_insert_session();
|
||||
|
||||
-- replaces function from 0/69_wh_session_facts.up.sql
|
||||
drop trigger wh_insert_session_connection on session_connection;
|
||||
drop function wh_insert_session_connection;
|
||||
create function wh_insert_session_connection()
|
||||
returns trigger
|
||||
as $$
|
||||
declare
|
||||
new_row wh_session_connection_accumulating_fact%rowtype;
|
||||
begin
|
||||
with
|
||||
authorized_timestamp (date_dim_key, time_dim_key, ts) as (
|
||||
select wh_date_key(start_time), wh_time_key(start_time), start_time
|
||||
from session_connection_state
|
||||
where connection_id = new.public_id
|
||||
and state = 'authorized'
|
||||
),
|
||||
session_dimension (host_dim_key, user_dim_key) as (
|
||||
select host_key, user_key
|
||||
from wh_session_accumulating_fact
|
||||
where session_id = new.session_id
|
||||
)
|
||||
insert into wh_session_connection_accumulating_fact (
|
||||
connection_id,
|
||||
session_id,
|
||||
host_key,
|
||||
user_key,
|
||||
connection_authorized_date_key,
|
||||
connection_authorized_time_key,
|
||||
connection_authorized_time,
|
||||
client_tcp_address,
|
||||
client_tcp_port_number,
|
||||
endpoint_tcp_address,
|
||||
endpoint_tcp_port_number,
|
||||
bytes_up,
|
||||
bytes_down
|
||||
)
|
||||
select new.public_id,
|
||||
new.session_id,
|
||||
session_dimension.host_dim_key,
|
||||
session_dimension.user_dim_key,
|
||||
authorized_timestamp.date_dim_key,
|
||||
authorized_timestamp.time_dim_key,
|
||||
authorized_timestamp.ts,
|
||||
new.client_tcp_address,
|
||||
new.client_tcp_port,
|
||||
new.endpoint_tcp_address,
|
||||
new.endpoint_tcp_port,
|
||||
new.bytes_up,
|
||||
new.bytes_down
|
||||
from authorized_timestamp,
|
||||
session_dimension
|
||||
returning * into strict new_row;
|
||||
perform wh_rollup_connections(new.session_id);
|
||||
return null;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger wh_insert_session_connection
|
||||
after insert on session_connection
|
||||
for each row
|
||||
execute function wh_insert_session_connection();
|
||||
|
||||
-- replaces function from 0/69_wh_session_facts.up.sql
|
||||
drop trigger wh_insert_session_state on session_state;
|
||||
drop function wh_insert_session_state;
|
||||
create function wh_insert_session_state()
|
||||
returns trigger
|
||||
as $$
|
||||
declare
|
||||
date_col text;
|
||||
time_col text;
|
||||
ts_col text;
|
||||
q text;
|
||||
session_row wh_session_accumulating_fact%rowtype;
|
||||
begin
|
||||
if new.state = 'pending' then
|
||||
-- The pending state is the first state which is handled by the
|
||||
-- wh_insert_session trigger. The update statement in this trigger will
|
||||
-- fail for the pending state because the row for the session has not yet
|
||||
-- been inserted into the wh_session_accumulating_fact table.
|
||||
return null;
|
||||
end if;
|
||||
|
||||
date_col = 'session_' || new.state || '_date_key';
|
||||
time_col = 'session_' || new.state || '_time_key';
|
||||
ts_col = 'session_' || new.state || '_time';
|
||||
|
||||
q = format('update wh_session_accumulating_fact
|
||||
set (%I, %I, %I) = (select wh_date_key(%L), wh_time_key(%L), %L::timestamptz)
|
||||
where session_id = %L
|
||||
returning *',
|
||||
date_col, time_col, ts_col,
|
||||
new.start_time, new.start_time, new.start_time,
|
||||
new.session_id);
|
||||
execute q into strict session_row;
|
||||
|
||||
return null;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger wh_insert_session_state
|
||||
after insert on session_state
|
||||
for each row
|
||||
execute function wh_insert_session_state();
|
||||
|
||||
-- replaces function from 0/69_wh_session_facts.up.sql
|
||||
drop trigger wh_insert_session_connection_state on session_connection_state;
|
||||
drop function wh_insert_session_connection_state;
|
||||
create function wh_insert_session_connection_state()
|
||||
returns trigger
|
||||
as $$
|
||||
declare
|
||||
date_col text;
|
||||
time_col text;
|
||||
ts_col text;
|
||||
q text;
|
||||
connection_row wh_session_connection_accumulating_fact%rowtype;
|
||||
begin
|
||||
if new.state = 'authorized' then
|
||||
-- The authorized state is the first state which is handled by the
|
||||
-- wh_insert_session_connection trigger. The update statement in this
|
||||
-- trigger will fail for the authorized state because the row for the
|
||||
-- session connection has not yet been inserted into the
|
||||
-- wh_session_connection_accumulating_fact table.
|
||||
return null;
|
||||
end if;
|
||||
|
||||
date_col = 'connection_' || new.state || '_date_key';
|
||||
time_col = 'connection_' || new.state || '_time_key';
|
||||
ts_col = 'connection_' || new.state || '_time';
|
||||
|
||||
q = format('update wh_session_connection_accumulating_fact
|
||||
set (%I, %I, %I) = (select wh_date_key(%L), wh_time_key(%L), %L::timestamptz)
|
||||
where connection_id = %L
|
||||
returning *',
|
||||
date_col, time_col, ts_col,
|
||||
new.start_time, new.start_time, new.start_time,
|
||||
new.connection_id);
|
||||
execute q into strict connection_row;
|
||||
|
||||
return null;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger wh_insert_session_connection_state
|
||||
after insert on session_connection_state
|
||||
for each row
|
||||
execute function wh_insert_session_connection_state();
|
||||
commit;
|
||||
@@ -0,0 +1,156 @@
|
||||
begin;
|
||||
alter table wh_host_dimension
|
||||
rename column host_organization_id to organization_id;
|
||||
alter table wh_host_dimension
|
||||
rename column host_organization_name to organization_name;
|
||||
alter table wh_host_dimension
|
||||
rename column host_organization_description to organization_description;
|
||||
|
||||
-- replaces view from 0/65_wh_session_dimensions.up.sql
|
||||
drop view whx_host_dimension_source;
|
||||
create view whx_host_dimension_source as
|
||||
select -- id is the first column in the target view
|
||||
h.public_id as host_id,
|
||||
'static host' as host_type,
|
||||
coalesce(h.name, 'None') as host_name,
|
||||
coalesce(h.description, 'None') as host_description,
|
||||
coalesce(h.address, 'Unknown') as host_address,
|
||||
s.public_id as host_set_id,
|
||||
'static host set' as host_set_type,
|
||||
coalesce(s.name, 'None') as host_set_name,
|
||||
coalesce(s.description, 'None') as host_set_description,
|
||||
c.public_id as host_catalog_id,
|
||||
'static host catalog' as host_catalog_type,
|
||||
coalesce(c.name, 'None') as host_catalog_name,
|
||||
coalesce(c.description, 'None') as host_catalog_description,
|
||||
t.public_id as target_id,
|
||||
'tcp target' as target_type,
|
||||
coalesce(t.name, 'None') as target_name,
|
||||
coalesce(t.description, 'None') as target_description,
|
||||
coalesce(t.default_port, 0) as target_default_port_number,
|
||||
t.session_max_seconds as target_session_max_seconds,
|
||||
t.session_connection_limit as target_session_connection_limit,
|
||||
p.public_id as project_id,
|
||||
coalesce(p.name, 'None') as project_name,
|
||||
coalesce(p.description, 'None') as project_description,
|
||||
o.public_id as organization_id,
|
||||
coalesce(o.name, 'None') as organization_name,
|
||||
coalesce(o.description, 'None') as organization_description
|
||||
from static_host as h,
|
||||
static_host_catalog as c,
|
||||
static_host_set_member as m,
|
||||
static_host_set as s,
|
||||
target_host_set as ts,
|
||||
target_tcp as t,
|
||||
iam_scope as p,
|
||||
iam_scope as o
|
||||
where h.catalog_id = c.public_id
|
||||
and h.public_id = m.host_id
|
||||
and s.public_id = m.set_id
|
||||
and t.public_id = ts.target_id
|
||||
and s.public_id = ts.host_set_id
|
||||
and p.public_id = t.scope_id
|
||||
and p.type = 'project'
|
||||
and o.public_id = p.parent_id
|
||||
and o.type = 'org'
|
||||
;
|
||||
|
||||
-- replaces view from 15/01_wh_rename_key_columns.up.sql
|
||||
drop view whx_host_dimension_target;
|
||||
create view whx_host_dimension_target as
|
||||
select key,
|
||||
host_id,
|
||||
host_type,
|
||||
host_name,
|
||||
host_description,
|
||||
host_address,
|
||||
host_set_id,
|
||||
host_set_type,
|
||||
host_set_name,
|
||||
host_set_description,
|
||||
host_catalog_id,
|
||||
host_catalog_type,
|
||||
host_catalog_name,
|
||||
host_catalog_description,
|
||||
target_id,
|
||||
target_type,
|
||||
target_name,
|
||||
target_description,
|
||||
target_default_port_number,
|
||||
target_session_max_seconds,
|
||||
target_session_connection_limit,
|
||||
project_id,
|
||||
project_name,
|
||||
project_description,
|
||||
organization_id,
|
||||
organization_name,
|
||||
organization_description
|
||||
from wh_host_dimension
|
||||
where current_row_indicator = 'Current'
|
||||
;
|
||||
|
||||
-- replaces function from 15/01_wh_rename_key_columns.up.sql
|
||||
drop function wh_upsert_host;
|
||||
create function wh_upsert_host(p_host_id wt_public_id, p_host_set_id wt_public_id, p_target_id wt_public_id)
|
||||
returns wh_dim_key
|
||||
as $$
|
||||
declare
|
||||
src whx_host_dimension_target%rowtype;
|
||||
target whx_host_dimension_target%rowtype;
|
||||
new_row wh_host_dimension%rowtype;
|
||||
begin
|
||||
select * into target
|
||||
from whx_host_dimension_target as t
|
||||
where t.host_id = p_host_id
|
||||
and t.host_set_id = p_host_set_id
|
||||
and t.target_id = p_target_id;
|
||||
|
||||
select target.key, t.* into src
|
||||
from whx_host_dimension_source as t
|
||||
where t.host_id = p_host_id
|
||||
and t.host_set_id = p_host_set_id
|
||||
and t.target_id = p_target_id;
|
||||
|
||||
if src is distinct from target then
|
||||
|
||||
-- expire the current row
|
||||
update wh_host_dimension
|
||||
set current_row_indicator = 'Expired',
|
||||
row_expiration_time = current_timestamp
|
||||
where host_id = p_host_id
|
||||
and host_set_id = p_host_set_id
|
||||
and target_id = p_target_id
|
||||
and current_row_indicator = 'Current';
|
||||
|
||||
-- insert a new row
|
||||
insert into wh_host_dimension (
|
||||
host_id, host_type, host_name, host_description, host_address,
|
||||
host_set_id, host_set_type, host_set_name, host_set_description,
|
||||
host_catalog_id, host_catalog_type, host_catalog_name, host_catalog_description,
|
||||
target_id, target_type, target_name, target_description,
|
||||
target_default_port_number, target_session_max_seconds, target_session_connection_limit,
|
||||
project_id, project_name, project_description,
|
||||
organization_id, organization_name, organization_description,
|
||||
current_row_indicator, row_effective_time, row_expiration_time
|
||||
)
|
||||
select host_id, host_type, host_name, host_description, host_address,
|
||||
host_set_id, host_set_type, host_set_name, host_set_description,
|
||||
host_catalog_id, host_catalog_type, host_catalog_name, host_catalog_description,
|
||||
target_id, target_type, target_name, target_description,
|
||||
target_default_port_number, target_session_max_seconds, target_session_connection_limit,
|
||||
project_id, project_name, project_description,
|
||||
organization_id, organization_name, organization_description,
|
||||
'Current', current_timestamp, 'infinity'::timestamptz
|
||||
from whx_host_dimension_source
|
||||
where host_id = p_host_id
|
||||
and host_set_id = p_host_set_id
|
||||
and target_id = p_target_id
|
||||
returning * into new_row;
|
||||
|
||||
return new_row.key;
|
||||
end if;
|
||||
return target.key;
|
||||
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
commit;
|
||||
@@ -4,7 +4,7 @@ package schema
|
||||
|
||||
func init() {
|
||||
migrationStates["postgres"] = migrationState{
|
||||
binarySchemaVersion: 14001,
|
||||
binarySchemaVersion: 15002,
|
||||
upMigrations: map[int][]byte{
|
||||
1: []byte(`
|
||||
create domain wt_public_id as text
|
||||
@@ -6331,6 +6331,611 @@ alter table wh_user_dimension
|
||||
end if;
|
||||
return target.id;
|
||||
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
`),
|
||||
15001: []byte(`
|
||||
alter table wh_date_dimension
|
||||
rename column id to key;
|
||||
|
||||
alter table wh_time_of_day_dimension
|
||||
rename column id to key;
|
||||
|
||||
alter table wh_host_dimension
|
||||
rename column id to key;
|
||||
|
||||
alter table wh_user_dimension
|
||||
rename column id to key;
|
||||
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column host_id to host_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column user_id to user_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_pending_date_id to session_pending_date_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_pending_time_id to session_pending_time_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_active_date_id to session_active_date_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_active_time_id to session_active_time_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_canceling_date_id to session_canceling_date_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_canceling_time_id to session_canceling_time_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_terminated_date_id to session_terminated_date_key;
|
||||
alter table wh_session_accumulating_fact
|
||||
rename column session_terminated_time_id to session_terminated_time_key;
|
||||
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column host_id to host_key;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column user_id to user_key;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column connection_authorized_date_id to connection_authorized_date_key;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column connection_authorized_time_id to connection_authorized_time_key;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column connection_connected_date_id to connection_connected_date_key;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column connection_connected_time_id to connection_connected_time_key;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column connection_closed_date_id to connection_closed_date_key;
|
||||
alter table wh_session_connection_accumulating_fact
|
||||
rename column connection_closed_time_id to connection_closed_time_key;
|
||||
|
||||
-- rename function from internal/db/schema/migrations/postgres/0/60_wh_domain_types.up.sql
|
||||
alter function wh_dim_id rename to wh_dim_key;
|
||||
|
||||
-- rename domain from internal/db/schema/migrations/postgres/0/60_wh_domain_types.up.sql
|
||||
alter domain wh_dim_id rename to wh_dim_key;
|
||||
|
||||
-- removes unused function from internal/db/schema/migrations/postgres/0/60_wh_domain_types.up.sql
|
||||
drop function wh_current_date_id;
|
||||
|
||||
-- removes unused function from internal/db/schema/migrations/postgres/0/60_wh_domain_types.up.sql
|
||||
drop function wh_current_time_id;
|
||||
|
||||
-- rename function from internal/db/schema/migrations/postgres/0/60_wh_domain_types.up.sql
|
||||
alter function wh_date_id rename to wh_date_key;
|
||||
|
||||
-- rename function from internal/db/schema/migrations/postgres/0/60_wh_domain_types.up.sql
|
||||
alter function wh_time_id rename to wh_time_key;
|
||||
|
||||
-- replaces view from 14/01_wh_user_dimension_oidc.up.sql
|
||||
drop view whx_user_dimension_target;
|
||||
create view whx_user_dimension_target as
|
||||
select key,
|
||||
user_id,
|
||||
user_name,
|
||||
user_description,
|
||||
auth_account_id,
|
||||
auth_account_type,
|
||||
auth_account_name,
|
||||
auth_account_description,
|
||||
auth_account_external_id,
|
||||
auth_account_full_name,
|
||||
auth_account_email,
|
||||
auth_method_id,
|
||||
auth_method_type,
|
||||
auth_method_name,
|
||||
auth_method_description,
|
||||
auth_method_external_id,
|
||||
user_organization_id,
|
||||
user_organization_name,
|
||||
user_organization_description
|
||||
from wh_user_dimension
|
||||
where current_row_indicator = 'Current'
|
||||
;
|
||||
|
||||
-- replaces function from 14/01_wh_user_dimension_oidc.up.sql
|
||||
drop function wh_upsert_user;
|
||||
create function wh_upsert_user(p_user_id wt_user_id, p_auth_token_id wt_public_id)
|
||||
returns wh_dim_key
|
||||
as $$
|
||||
declare
|
||||
src whx_user_dimension_target%rowtype;
|
||||
target whx_user_dimension_target%rowtype;
|
||||
new_row wh_user_dimension%rowtype;
|
||||
acct_id wt_public_id;
|
||||
begin
|
||||
select auth_account_id into strict acct_id
|
||||
from auth_token
|
||||
where public_id = p_auth_token_id;
|
||||
|
||||
select * into target
|
||||
from whx_user_dimension_target as t
|
||||
where t.user_id = p_user_id
|
||||
and t.auth_account_id = acct_id;
|
||||
|
||||
select target.key, t.* into src
|
||||
from whx_user_dimension_source as t
|
||||
where t.user_id = p_user_id
|
||||
and t.auth_account_id = acct_id;
|
||||
|
||||
if src is distinct from target then
|
||||
|
||||
-- expire the current row
|
||||
update wh_user_dimension
|
||||
set current_row_indicator = 'Expired',
|
||||
row_expiration_time = current_timestamp
|
||||
where user_id = p_user_id
|
||||
and auth_account_id = acct_id
|
||||
and current_row_indicator = 'Current';
|
||||
|
||||
-- insert a new row
|
||||
insert into wh_user_dimension (
|
||||
user_id, user_name, user_description,
|
||||
auth_account_id, auth_account_type, auth_account_name, auth_account_description,
|
||||
auth_account_external_id, auth_account_full_name, auth_account_email,
|
||||
auth_method_id, auth_method_type, auth_method_name, auth_method_description,
|
||||
auth_method_external_id,
|
||||
user_organization_id, user_organization_name, user_organization_description,
|
||||
current_row_indicator, row_effective_time, row_expiration_time
|
||||
)
|
||||
select user_id, user_name, user_description,
|
||||
auth_account_id, auth_account_type, auth_account_name, auth_account_description,
|
||||
auth_account_external_id, auth_account_full_name, auth_account_email,
|
||||
auth_method_id, auth_method_type, auth_method_name, auth_method_description,
|
||||
auth_method_external_id,
|
||||
user_organization_id, user_organization_name, user_organization_description,
|
||||
'Current', current_timestamp, 'infinity'::timestamptz
|
||||
from whx_user_dimension_source
|
||||
where user_id = p_user_id
|
||||
and auth_account_id = acct_id
|
||||
returning * into new_row;
|
||||
|
||||
return new_row.key;
|
||||
end if;
|
||||
return target.key;
|
||||
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- replaces view from 0/65_wh_session_dimensions.up.sql
|
||||
drop view whx_host_dimension_target;
|
||||
create view whx_host_dimension_target as
|
||||
select key,
|
||||
host_id,
|
||||
host_type,
|
||||
host_name,
|
||||
host_description,
|
||||
host_address,
|
||||
host_set_id,
|
||||
host_set_type,
|
||||
host_set_name,
|
||||
host_set_description,
|
||||
host_catalog_id,
|
||||
host_catalog_type,
|
||||
host_catalog_name,
|
||||
host_catalog_description,
|
||||
target_id,
|
||||
target_type,
|
||||
target_name,
|
||||
target_description,
|
||||
target_default_port_number,
|
||||
target_session_max_seconds,
|
||||
target_session_connection_limit,
|
||||
project_id,
|
||||
project_name,
|
||||
project_description,
|
||||
host_organization_id,
|
||||
host_organization_name,
|
||||
host_organization_description
|
||||
from wh_host_dimension
|
||||
where current_row_indicator = 'Current'
|
||||
;
|
||||
|
||||
-- replaces function from 0/66_wh_session_dimensions.up.sql
|
||||
drop function wh_upsert_host;
|
||||
create function wh_upsert_host(p_host_id wt_public_id, p_host_set_id wt_public_id, p_target_id wt_public_id)
|
||||
returns wh_dim_key
|
||||
as $$
|
||||
declare
|
||||
src whx_host_dimension_target%rowtype;
|
||||
target whx_host_dimension_target%rowtype;
|
||||
new_row wh_host_dimension%rowtype;
|
||||
begin
|
||||
select * into target
|
||||
from whx_host_dimension_target as t
|
||||
where t.host_id = p_host_id
|
||||
and t.host_set_id = p_host_set_id
|
||||
and t.target_id = p_target_id;
|
||||
|
||||
select target.key, t.* into src
|
||||
from whx_host_dimension_source as t
|
||||
where t.host_id = p_host_id
|
||||
and t.host_set_id = p_host_set_id
|
||||
and t.target_id = p_target_id;
|
||||
|
||||
if src is distinct from target then
|
||||
|
||||
-- expire the current row
|
||||
update wh_host_dimension
|
||||
set current_row_indicator = 'Expired',
|
||||
row_expiration_time = current_timestamp
|
||||
where host_id = p_host_id
|
||||
and host_set_id = p_host_set_id
|
||||
and target_id = p_target_id
|
||||
and current_row_indicator = 'Current';
|
||||
|
||||
-- insert a new row
|
||||
insert into wh_host_dimension (
|
||||
host_id, host_type, host_name, host_description, host_address,
|
||||
host_set_id, host_set_type, host_set_name, host_set_description,
|
||||
host_catalog_id, host_catalog_type, host_catalog_name, host_catalog_description,
|
||||
target_id, target_type, target_name, target_description,
|
||||
target_default_port_number, target_session_max_seconds, target_session_connection_limit,
|
||||
project_id, project_name, project_description,
|
||||
host_organization_id, host_organization_name, host_organization_description,
|
||||
current_row_indicator, row_effective_time, row_expiration_time
|
||||
)
|
||||
select host_id, host_type, host_name, host_description, host_address,
|
||||
host_set_id, host_set_type, host_set_name, host_set_description,
|
||||
host_catalog_id, host_catalog_type, host_catalog_name, host_catalog_description,
|
||||
target_id, target_type, target_name, target_description,
|
||||
target_default_port_number, target_session_max_seconds, target_session_connection_limit,
|
||||
project_id, project_name, project_description,
|
||||
host_organization_id, host_organization_name, host_organization_description,
|
||||
'Current', current_timestamp, 'infinity'::timestamptz
|
||||
from whx_host_dimension_source
|
||||
where host_id = p_host_id
|
||||
and host_set_id = p_host_set_id
|
||||
and target_id = p_target_id
|
||||
returning * into new_row;
|
||||
|
||||
return new_row.key;
|
||||
end if;
|
||||
return target.key;
|
||||
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- replaces function from 0/69_wh_session_facts.up.sql
|
||||
drop trigger wh_insert_session on session;
|
||||
drop function wh_insert_session;
|
||||
create function wh_insert_session()
|
||||
returns trigger
|
||||
as $$
|
||||
declare
|
||||
new_row wh_session_accumulating_fact%rowtype;
|
||||
begin
|
||||
with
|
||||
pending_timestamp (date_dim_key, time_dim_key, ts) as (
|
||||
select wh_date_key(start_time), wh_time_key(start_time), start_time
|
||||
from session_state
|
||||
where session_id = new.public_id
|
||||
and state = 'pending'
|
||||
)
|
||||
insert into wh_session_accumulating_fact (
|
||||
session_id,
|
||||
auth_token_id,
|
||||
host_key,
|
||||
user_key,
|
||||
session_pending_date_key,
|
||||
session_pending_time_key,
|
||||
session_pending_time
|
||||
)
|
||||
select new.public_id,
|
||||
new.auth_token_id,
|
||||
wh_upsert_host(new.host_id, new.host_set_id, new.target_id),
|
||||
wh_upsert_user(new.user_id, new.auth_token_id),
|
||||
pending_timestamp.date_dim_key,
|
||||
pending_timestamp.time_dim_key,
|
||||
pending_timestamp.ts
|
||||
from pending_timestamp
|
||||
returning * into strict new_row;
|
||||
return null;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
create trigger wh_insert_session
|
||||
after insert on session
|
||||
for each row
|
||||
execute function wh_insert_session();
|
||||
|
||||
-- replaces function from 0/69_wh_session_facts.up.sql
|
||||
drop trigger wh_insert_session_connection on session_connection;
|
||||
drop function wh_insert_session_connection;
|
||||
create function wh_insert_session_connection()
|
||||
returns trigger
|
||||
as $$
|
||||
declare
|
||||
new_row wh_session_connection_accumulating_fact%rowtype;
|
||||
begin
|
||||
with
|
||||
authorized_timestamp (date_dim_key, time_dim_key, ts) as (
|
||||
select wh_date_key(start_time), wh_time_key(start_time), start_time
|
||||
from session_connection_state
|
||||
where connection_id = new.public_id
|
||||
and state = 'authorized'
|
||||
),
|
||||
session_dimension (host_dim_key, user_dim_key) as (
|
||||
select host_key, user_key
|
||||
from wh_session_accumulating_fact
|
||||
where session_id = new.session_id
|
||||
)
|
||||
insert into wh_session_connection_accumulating_fact (
|
||||
connection_id,
|
||||
session_id,
|
||||
host_key,
|
||||
user_key,
|
||||
connection_authorized_date_key,
|
||||
connection_authorized_time_key,
|
||||
connection_authorized_time,
|
||||
client_tcp_address,
|
||||
client_tcp_port_number,
|
||||
endpoint_tcp_address,
|
||||
endpoint_tcp_port_number,
|
||||
bytes_up,
|
||||
bytes_down
|
||||
)
|
||||
select new.public_id,
|
||||
new.session_id,
|
||||
session_dimension.host_dim_key,
|
||||
session_dimension.user_dim_key,
|
||||
authorized_timestamp.date_dim_key,
|
||||
authorized_timestamp.time_dim_key,
|
||||
authorized_timestamp.ts,
|
||||
new.client_tcp_address,
|
||||
new.client_tcp_port,
|
||||
new.endpoint_tcp_address,
|
||||
new.endpoint_tcp_port,
|
||||
new.bytes_up,
|
||||
new.bytes_down
|
||||
from authorized_timestamp,
|
||||
session_dimension
|
||||
returning * into strict new_row;
|
||||
perform wh_rollup_connections(new.session_id);
|
||||
return null;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger wh_insert_session_connection
|
||||
after insert on session_connection
|
||||
for each row
|
||||
execute function wh_insert_session_connection();
|
||||
|
||||
-- replaces function from 0/69_wh_session_facts.up.sql
|
||||
drop trigger wh_insert_session_state on session_state;
|
||||
drop function wh_insert_session_state;
|
||||
create function wh_insert_session_state()
|
||||
returns trigger
|
||||
as $$
|
||||
declare
|
||||
date_col text;
|
||||
time_col text;
|
||||
ts_col text;
|
||||
q text;
|
||||
session_row wh_session_accumulating_fact%rowtype;
|
||||
begin
|
||||
if new.state = 'pending' then
|
||||
-- The pending state is the first state which is handled by the
|
||||
-- wh_insert_session trigger. The update statement in this trigger will
|
||||
-- fail for the pending state because the row for the session has not yet
|
||||
-- been inserted into the wh_session_accumulating_fact table.
|
||||
return null;
|
||||
end if;
|
||||
|
||||
date_col = 'session_' || new.state || '_date_key';
|
||||
time_col = 'session_' || new.state || '_time_key';
|
||||
ts_col = 'session_' || new.state || '_time';
|
||||
|
||||
q = format('update wh_session_accumulating_fact
|
||||
set (%I, %I, %I) = (select wh_date_key(%L), wh_time_key(%L), %L::timestamptz)
|
||||
where session_id = %L
|
||||
returning *',
|
||||
date_col, time_col, ts_col,
|
||||
new.start_time, new.start_time, new.start_time,
|
||||
new.session_id);
|
||||
execute q into strict session_row;
|
||||
|
||||
return null;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger wh_insert_session_state
|
||||
after insert on session_state
|
||||
for each row
|
||||
execute function wh_insert_session_state();
|
||||
|
||||
-- replaces function from 0/69_wh_session_facts.up.sql
|
||||
drop trigger wh_insert_session_connection_state on session_connection_state;
|
||||
drop function wh_insert_session_connection_state;
|
||||
create function wh_insert_session_connection_state()
|
||||
returns trigger
|
||||
as $$
|
||||
declare
|
||||
date_col text;
|
||||
time_col text;
|
||||
ts_col text;
|
||||
q text;
|
||||
connection_row wh_session_connection_accumulating_fact%rowtype;
|
||||
begin
|
||||
if new.state = 'authorized' then
|
||||
-- The authorized state is the first state which is handled by the
|
||||
-- wh_insert_session_connection trigger. The update statement in this
|
||||
-- trigger will fail for the authorized state because the row for the
|
||||
-- session connection has not yet been inserted into the
|
||||
-- wh_session_connection_accumulating_fact table.
|
||||
return null;
|
||||
end if;
|
||||
|
||||
date_col = 'connection_' || new.state || '_date_key';
|
||||
time_col = 'connection_' || new.state || '_time_key';
|
||||
ts_col = 'connection_' || new.state || '_time';
|
||||
|
||||
q = format('update wh_session_connection_accumulating_fact
|
||||
set (%I, %I, %I) = (select wh_date_key(%L), wh_time_key(%L), %L::timestamptz)
|
||||
where connection_id = %L
|
||||
returning *',
|
||||
date_col, time_col, ts_col,
|
||||
new.start_time, new.start_time, new.start_time,
|
||||
new.connection_id);
|
||||
execute q into strict connection_row;
|
||||
|
||||
return null;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger wh_insert_session_connection_state
|
||||
after insert on session_connection_state
|
||||
for each row
|
||||
execute function wh_insert_session_connection_state();
|
||||
`),
|
||||
15002: []byte(`
|
||||
alter table wh_host_dimension
|
||||
rename column host_organization_id to organization_id;
|
||||
alter table wh_host_dimension
|
||||
rename column host_organization_name to organization_name;
|
||||
alter table wh_host_dimension
|
||||
rename column host_organization_description to organization_description;
|
||||
|
||||
-- replaces view from 0/65_wh_session_dimensions.up.sql
|
||||
drop view whx_host_dimension_source;
|
||||
create view whx_host_dimension_source as
|
||||
select -- id is the first column in the target view
|
||||
h.public_id as host_id,
|
||||
'static host' as host_type,
|
||||
coalesce(h.name, 'None') as host_name,
|
||||
coalesce(h.description, 'None') as host_description,
|
||||
coalesce(h.address, 'Unknown') as host_address,
|
||||
s.public_id as host_set_id,
|
||||
'static host set' as host_set_type,
|
||||
coalesce(s.name, 'None') as host_set_name,
|
||||
coalesce(s.description, 'None') as host_set_description,
|
||||
c.public_id as host_catalog_id,
|
||||
'static host catalog' as host_catalog_type,
|
||||
coalesce(c.name, 'None') as host_catalog_name,
|
||||
coalesce(c.description, 'None') as host_catalog_description,
|
||||
t.public_id as target_id,
|
||||
'tcp target' as target_type,
|
||||
coalesce(t.name, 'None') as target_name,
|
||||
coalesce(t.description, 'None') as target_description,
|
||||
coalesce(t.default_port, 0) as target_default_port_number,
|
||||
t.session_max_seconds as target_session_max_seconds,
|
||||
t.session_connection_limit as target_session_connection_limit,
|
||||
p.public_id as project_id,
|
||||
coalesce(p.name, 'None') as project_name,
|
||||
coalesce(p.description, 'None') as project_description,
|
||||
o.public_id as organization_id,
|
||||
coalesce(o.name, 'None') as organization_name,
|
||||
coalesce(o.description, 'None') as organization_description
|
||||
from static_host as h,
|
||||
static_host_catalog as c,
|
||||
static_host_set_member as m,
|
||||
static_host_set as s,
|
||||
target_host_set as ts,
|
||||
target_tcp as t,
|
||||
iam_scope as p,
|
||||
iam_scope as o
|
||||
where h.catalog_id = c.public_id
|
||||
and h.public_id = m.host_id
|
||||
and s.public_id = m.set_id
|
||||
and t.public_id = ts.target_id
|
||||
and s.public_id = ts.host_set_id
|
||||
and p.public_id = t.scope_id
|
||||
and p.type = 'project'
|
||||
and o.public_id = p.parent_id
|
||||
and o.type = 'org'
|
||||
;
|
||||
|
||||
-- replaces view from 15/01_wh_rename_key_columns.up.sql
|
||||
drop view whx_host_dimension_target;
|
||||
create view whx_host_dimension_target as
|
||||
select key,
|
||||
host_id,
|
||||
host_type,
|
||||
host_name,
|
||||
host_description,
|
||||
host_address,
|
||||
host_set_id,
|
||||
host_set_type,
|
||||
host_set_name,
|
||||
host_set_description,
|
||||
host_catalog_id,
|
||||
host_catalog_type,
|
||||
host_catalog_name,
|
||||
host_catalog_description,
|
||||
target_id,
|
||||
target_type,
|
||||
target_name,
|
||||
target_description,
|
||||
target_default_port_number,
|
||||
target_session_max_seconds,
|
||||
target_session_connection_limit,
|
||||
project_id,
|
||||
project_name,
|
||||
project_description,
|
||||
organization_id,
|
||||
organization_name,
|
||||
organization_description
|
||||
from wh_host_dimension
|
||||
where current_row_indicator = 'Current'
|
||||
;
|
||||
|
||||
-- replaces function from 15/01_wh_rename_key_columns.up.sql
|
||||
drop function wh_upsert_host;
|
||||
create function wh_upsert_host(p_host_id wt_public_id, p_host_set_id wt_public_id, p_target_id wt_public_id)
|
||||
returns wh_dim_key
|
||||
as $$
|
||||
declare
|
||||
src whx_host_dimension_target%rowtype;
|
||||
target whx_host_dimension_target%rowtype;
|
||||
new_row wh_host_dimension%rowtype;
|
||||
begin
|
||||
select * into target
|
||||
from whx_host_dimension_target as t
|
||||
where t.host_id = p_host_id
|
||||
and t.host_set_id = p_host_set_id
|
||||
and t.target_id = p_target_id;
|
||||
|
||||
select target.key, t.* into src
|
||||
from whx_host_dimension_source as t
|
||||
where t.host_id = p_host_id
|
||||
and t.host_set_id = p_host_set_id
|
||||
and t.target_id = p_target_id;
|
||||
|
||||
if src is distinct from target then
|
||||
|
||||
-- expire the current row
|
||||
update wh_host_dimension
|
||||
set current_row_indicator = 'Expired',
|
||||
row_expiration_time = current_timestamp
|
||||
where host_id = p_host_id
|
||||
and host_set_id = p_host_set_id
|
||||
and target_id = p_target_id
|
||||
and current_row_indicator = 'Current';
|
||||
|
||||
-- insert a new row
|
||||
insert into wh_host_dimension (
|
||||
host_id, host_type, host_name, host_description, host_address,
|
||||
host_set_id, host_set_type, host_set_name, host_set_description,
|
||||
host_catalog_id, host_catalog_type, host_catalog_name, host_catalog_description,
|
||||
target_id, target_type, target_name, target_description,
|
||||
target_default_port_number, target_session_max_seconds, target_session_connection_limit,
|
||||
project_id, project_name, project_description,
|
||||
organization_id, organization_name, organization_description,
|
||||
current_row_indicator, row_effective_time, row_expiration_time
|
||||
)
|
||||
select host_id, host_type, host_name, host_description, host_address,
|
||||
host_set_id, host_set_type, host_set_name, host_set_description,
|
||||
host_catalog_id, host_catalog_type, host_catalog_name, host_catalog_description,
|
||||
target_id, target_type, target_name, target_description,
|
||||
target_default_port_number, target_session_max_seconds, target_session_connection_limit,
|
||||
project_id, project_name, project_description,
|
||||
organization_id, organization_name, organization_description,
|
||||
'Current', current_timestamp, 'infinity'::timestamptz
|
||||
from whx_host_dimension_source
|
||||
where host_id = p_host_id
|
||||
and host_set_id = p_host_set_id
|
||||
and target_id = p_target_id
|
||||
returning * into new_row;
|
||||
|
||||
return new_row.key;
|
||||
end if;
|
||||
return target.key;
|
||||
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
`),
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
begin;
|
||||
-- Add organizations
|
||||
insert into iam_scope
|
||||
(parent_id, type, public_id, name)
|
||||
values
|
||||
('global', 'org', 'o_____colors', 'Colors R Us');
|
||||
|
||||
-- Add projects to the organizations
|
||||
insert into iam_scope
|
||||
(parent_id, type, public_id, name)
|
||||
values
|
||||
('o_____colors', 'project', 'p____bcolors', 'Blue Color Mill'),
|
||||
('o_____colors', 'project', 'p____rcolors', 'Red Color Mill');
|
||||
|
||||
-- Add global users
|
||||
insert into iam_user
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
('global', 'u_______gary', 'Gary'),
|
||||
('global', 'u_______gina', 'Gina'),
|
||||
('global', 'u______nancy', 'Nancy');
|
||||
|
||||
-- Add organization users
|
||||
insert into iam_user
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
('o_____colors', 'u______clare', 'Clare'),
|
||||
('o_____colors', 'u______cindy', 'Cindy'),
|
||||
('o_____colors', 'u______carly', 'Carly'),
|
||||
('o_____colors', 'u______ciara', 'Ciara');
|
||||
|
||||
insert into iam_group
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
('global', 'g___gg-group', 'Global Group'),
|
||||
('o_____colors', 'g___oc-group', 'Colors R Us Group'),
|
||||
('p____bcolors', 'g___cb-group', 'Blue Color Group'),
|
||||
('p____rcolors', 'g___cr-group', 'Red Color Group');
|
||||
|
||||
insert into iam_group_member_user
|
||||
(group_id, member_id)
|
||||
values
|
||||
('g___gg-group', 'u_______gary'),
|
||||
('g___oc-group', 'u______clare'),
|
||||
('g___cb-group', 'u______cindy'),
|
||||
('g___cr-group', 'u______carly');
|
||||
|
||||
insert into iam_role
|
||||
(scope_id, grant_scope_id, public_id, name)
|
||||
values
|
||||
('p____bcolors', 'p____bcolors', 'r_pp_bc__mix', 'Color Mixer'),
|
||||
('p____rcolors', 'p____rcolors', 'r_pp_rc__mix', 'Color Mixer'),
|
||||
('o_____colors', 'p____bcolors', 'r_op_bc__art', 'Blue Color Artist'),
|
||||
('o_____colors', 'p____rcolors', 'r_op_rc__art', 'Red Color Artist'),
|
||||
('o_____colors', 'o_____colors', 'r_oo_____art', 'Color Artist'),
|
||||
('global', 'o_____colors', 'r_go____name', 'Color Namer'),
|
||||
('global', 'p____bcolors', 'r_gp____spec', 'Blue Color Inspector'),
|
||||
('global', 'global', 'r_gg_____buy', 'Purchaser'),
|
||||
('global', 'global', 'r_gg____shop', 'Shopper');
|
||||
|
||||
insert into iam_role_grant
|
||||
(role_id, canonical_grant, raw_grant)
|
||||
values
|
||||
('r_gg_____buy', 'type=*;action=purchase', 'purchase anything'),
|
||||
('r_gg____shop', 'type=*;action=view', 'view anything'),
|
||||
('r_go____name', 'type=color;action=name', 'name colors'),
|
||||
('r_gp____spec', 'type=color;action=inspect', 'inspect colors'),
|
||||
('r_oo_____art', 'type=color;action=create', 'create color'),
|
||||
('r_op_bc__art', 'type=color;action=create', 'create color'),
|
||||
('r_op_rc__art', 'type=color;action=create', 'create color'),
|
||||
('r_pp_bc__mix', 'type=color;action=mix', 'mix color'),
|
||||
('r_pp_rc__mix', 'type=color;action=mix', 'mix color');
|
||||
|
||||
insert into iam_group_role
|
||||
(role_id, principal_id)
|
||||
values
|
||||
('r_op_rc__art', 'g___oc-group'), -- color
|
||||
('r_pp_bc__mix', 'g___cb-group'), -- color
|
||||
('r_pp_rc__mix', 'g___cr-group'); -- color
|
||||
|
||||
insert into iam_user_role
|
||||
(role_id, principal_id)
|
||||
values
|
||||
('r_go____name', 'u_______gary'),
|
||||
('r_gp____spec', 'u_______gina'),
|
||||
('r_gg_____buy', 'u_auth'),
|
||||
('r_gg____shop', 'u_anon');
|
||||
|
||||
insert into auth_password_conf
|
||||
(password_method_id, private_id)
|
||||
values
|
||||
('apm___colors', 'apmc__colors');
|
||||
|
||||
|
||||
-- Add password auth method to organizations
|
||||
insert into auth_password_method
|
||||
(scope_id, public_id, password_conf_id, name)
|
||||
values
|
||||
('o_____colors', 'apm___colors', 'apmc__colors', 'Colors Auth Password');
|
||||
|
||||
insert into auth_password_account
|
||||
(auth_method_id, public_id, login_name)
|
||||
values
|
||||
('apm___colors', 'apa____clare', 'clare'),
|
||||
('apm___colors', 'apa____cindy', 'cindy'),
|
||||
('apm___colors', 'apa____carly', 'carly'),
|
||||
('apm___colors', 'apa____ciara', 'ciara');
|
||||
|
||||
update auth_account set iam_user_id = 'u______clare' where public_id = 'apa____clare';
|
||||
update auth_account set iam_user_id = 'u______cindy' where public_id = 'apa____cindy';
|
||||
update auth_account set iam_user_id = 'u______carly' where public_id = 'apa____carly';
|
||||
update auth_account set iam_user_id = 'u______ciara' where public_id = 'apa____ciara';
|
||||
|
||||
insert into static_host_catalog
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
('p____bcolors', 'c___cb-sthcl', 'Blue Color Static Catalog'),
|
||||
('p____rcolors', 'c___cr-sthcl', 'Red Color Static Catalog');
|
||||
|
||||
insert into auth_token
|
||||
(key_id, auth_account_id, public_id, token)
|
||||
values
|
||||
('key', 'apa____clare', 'tok____clare', 'tok____clare'::bytea);
|
||||
|
||||
insert into static_host
|
||||
(catalog_id, public_id, address)
|
||||
values
|
||||
('c___cb-sthcl', 'h_____cb__01', '1.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__02', '2.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__03', '3.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__04', '4.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__05', '5.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__06', '6.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__07', '7.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__08', '8.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__09', '9.blue.color'),
|
||||
|
||||
('c___cr-sthcl', 'h_____cr__01', '1.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__02', '2.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__03', '3.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__04', '4.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__05', '5.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__06', '6.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__07', '7.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__08', '8.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__09', '9.red.color');
|
||||
|
||||
insert into static_host_set
|
||||
(catalog_id, public_id, name)
|
||||
values
|
||||
('c___cb-sthcl', 's___1cb-sths', 'Blue Color Static Set 1'),
|
||||
('c___cb-sthcl', 's___2cb-sths', 'Blue Color Static Set 2'),
|
||||
('c___cr-sthcl', 's___1cr-sths', 'Red Color Static Set 1'),
|
||||
('c___cr-sthcl', 's___2cr-sths', 'Red Color Static Set 2');
|
||||
|
||||
insert
|
||||
into static_host_set_member
|
||||
( host_id, set_id, catalog_id)
|
||||
select h.public_id, s.public_id, s.catalog_id
|
||||
from static_host as h,
|
||||
static_host_set as s
|
||||
where h.catalog_id = s.catalog_id;
|
||||
|
||||
insert into target_tcp
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
('p____bcolors', 't_________cb', 'Blue Color Target'),
|
||||
('p____rcolors', 't_________cr', 'Red Color Target');
|
||||
|
||||
insert into target_host_set
|
||||
(target_id, host_set_id)
|
||||
values
|
||||
('t_________cb', 's___1cb-sths'),
|
||||
('t_________cb', 's___2cb-sths'),
|
||||
('t_________cr', 's___1cr-sths'),
|
||||
('t_________cr', 's___2cr-sths');
|
||||
|
||||
insert into session
|
||||
( scope_id , target_id , host_set_id , host_id , user_id , auth_token_id , certificate , endpoint , public_id)
|
||||
values
|
||||
('p____bcolors' , 't_________cb' , 's___1cb-sths' , 'h_____cb__01' , 'u______clare' , 'tok____clare' , 'abc'::bytea , 'ep1' , 's1_____clare');
|
||||
|
||||
insert into session_connection
|
||||
(session_id, public_id)
|
||||
values
|
||||
('s1_____clare', 'sc1_____clare');
|
||||
commit;
|
||||
@@ -1,216 +0,0 @@
|
||||
begin;
|
||||
-- _wtt_load_colors_iam populates all iam_ tables for the colors persona.
|
||||
-- iam does not depend on any other aggregates, but others depend on it,
|
||||
-- as such is it should be first in the list.
|
||||
create function _wtt_load_colors_iam()
|
||||
returns void
|
||||
as $$
|
||||
begin
|
||||
-- Add organizations
|
||||
insert into iam_scope
|
||||
(parent_id, type, public_id, name)
|
||||
values
|
||||
('global', 'org', 'o_____colors', 'Colors R Us');
|
||||
|
||||
-- Add projects to the organizations
|
||||
insert into iam_scope
|
||||
(parent_id, type, public_id, name)
|
||||
values
|
||||
('o_____colors', 'project', 'p____bcolors', 'Blue Color Mill'),
|
||||
('o_____colors', 'project', 'p____rcolors', 'Red Color Mill');
|
||||
|
||||
-- Add global users
|
||||
insert into iam_user
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
('global', 'u_______gary', 'Gary'),
|
||||
('global', 'u_______gina', 'Gina'),
|
||||
('global', 'u______nancy', 'Nancy');
|
||||
|
||||
-- Add organization users
|
||||
insert into iam_user
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
('o_____colors', 'u______clare', 'Clare'),
|
||||
('o_____colors', 'u______cindy', 'Cindy'),
|
||||
('o_____colors', 'u______carly', 'Carly'),
|
||||
('o_____colors', 'u______ciara', 'Ciara');
|
||||
|
||||
insert into iam_group
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
('global', 'g___gg-group', 'Global Group'),
|
||||
('o_____colors', 'g___oc-group', 'Colors R Us Group'),
|
||||
('p____bcolors', 'g___cb-group', 'Blue Color Group'),
|
||||
('p____rcolors', 'g___cr-group', 'Red Color Group');
|
||||
|
||||
insert into iam_group_member_user
|
||||
(group_id, member_id)
|
||||
values
|
||||
('g___gg-group', 'u_______gary'),
|
||||
('g___oc-group', 'u______clare'),
|
||||
('g___cb-group', 'u______cindy'),
|
||||
('g___cr-group', 'u______carly');
|
||||
|
||||
insert into iam_role
|
||||
(scope_id, grant_scope_id, public_id, name)
|
||||
values
|
||||
('p____bcolors', 'p____bcolors', 'r_pp_bc__mix', 'Color Mixer'),
|
||||
('p____rcolors', 'p____rcolors', 'r_pp_rc__mix', 'Color Mixer'),
|
||||
('o_____colors', 'p____bcolors', 'r_op_bc__art', 'Blue Color Artist'),
|
||||
('o_____colors', 'p____rcolors', 'r_op_rc__art', 'Red Color Artist'),
|
||||
('o_____colors', 'o_____colors', 'r_oo_____art', 'Color Artist'),
|
||||
('global', 'o_____colors', 'r_go____name', 'Color Namer'),
|
||||
('global', 'p____bcolors', 'r_gp____spec', 'Blue Color Inspector'),
|
||||
('global', 'global', 'r_gg_____buy', 'Purchaser'),
|
||||
('global', 'global', 'r_gg____shop', 'Shopper');
|
||||
|
||||
insert into iam_role_grant
|
||||
(role_id, canonical_grant, raw_grant)
|
||||
values
|
||||
('r_gg_____buy', 'type=*;action=purchase', 'purchase anything'),
|
||||
('r_gg____shop', 'type=*;action=view', 'view anything'),
|
||||
('r_go____name', 'type=color;action=name', 'name colors'),
|
||||
('r_gp____spec', 'type=color;action=inspect', 'inspect colors'),
|
||||
('r_oo_____art', 'type=color;action=create', 'create color'),
|
||||
('r_op_bc__art', 'type=color;action=create', 'create color'),
|
||||
('r_op_rc__art', 'type=color;action=create', 'create color'),
|
||||
('r_pp_bc__mix', 'type=color;action=mix', 'mix color'),
|
||||
('r_pp_rc__mix', 'type=color;action=mix', 'mix color');
|
||||
|
||||
insert into iam_group_role
|
||||
(role_id, principal_id)
|
||||
values
|
||||
('r_op_rc__art', 'g___oc-group'), -- color
|
||||
('r_pp_bc__mix', 'g___cb-group'), -- color
|
||||
('r_pp_rc__mix', 'g___cr-group'); -- color
|
||||
|
||||
insert into iam_user_role
|
||||
(role_id, principal_id)
|
||||
values
|
||||
('r_go____name', 'u_______gary'),
|
||||
('r_gp____spec', 'u_______gina'),
|
||||
('r_gg_____buy', 'u_auth'),
|
||||
('r_gg____shop', 'u_anon');
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- _wtt_load_kms populates all kms_ tables for the colors persona.
|
||||
-- kms depends on iam.
|
||||
create function _wtt_load_colors_kms()
|
||||
returns void
|
||||
as $$
|
||||
begin
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- _wtt_load_colors_auth populates all auth_ tables for the colors persona.
|
||||
-- auth depends on iam, and kms.
|
||||
create function _wtt_load_colors_auth()
|
||||
returns void
|
||||
as $$
|
||||
begin
|
||||
insert into auth_password_conf
|
||||
(password_method_id, private_id)
|
||||
values
|
||||
('apm___colors', 'apmc__colors');
|
||||
|
||||
|
||||
-- Add password auth method to organizations
|
||||
insert into auth_password_method
|
||||
(scope_id, public_id, password_conf_id, name)
|
||||
values
|
||||
('o_____colors', 'apm___colors', 'apmc__colors', 'Colors Auth Password');
|
||||
|
||||
insert into auth_password_account
|
||||
(auth_method_id, public_id, login_name)
|
||||
values
|
||||
('apm___colors', 'apa____clare', 'clare'),
|
||||
('apm___colors', 'apa____cindy', 'cindy'),
|
||||
('apm___colors', 'apa____carly', 'carly'),
|
||||
('apm___colors', 'apa____ciara', 'ciara');
|
||||
|
||||
update auth_account set iam_user_id = 'u______clare' where public_id = 'apa____clare';
|
||||
update auth_account set iam_user_id = 'u______cindy' where public_id = 'apa____cindy';
|
||||
update auth_account set iam_user_id = 'u______carly' where public_id = 'apa____carly';
|
||||
update auth_account set iam_user_id = 'u______ciara' where public_id = 'apa____ciara';
|
||||
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- _wtt_load_colors_hosts populates all host_ tables for the colors persona.
|
||||
-- hosts depend on iam.
|
||||
create function _wtt_load_colors_hosts()
|
||||
returns void
|
||||
as $$
|
||||
begin
|
||||
insert into static_host_catalog
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
('p____bcolors', 'c___cb-sthcl', 'Blue Color Static Catalog'),
|
||||
('p____rcolors', 'c___cr-sthcl', 'Red Color Static Catalog');
|
||||
|
||||
insert into static_host
|
||||
(catalog_id, public_id, address)
|
||||
values
|
||||
('c___cb-sthcl', 'h_____cb__01', '1.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__02', '2.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__03', '3.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__04', '4.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__05', '5.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__06', '6.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__07', '7.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__08', '8.blue.color'),
|
||||
('c___cb-sthcl', 'h_____cb__09', '9.blue.color'),
|
||||
|
||||
('c___cr-sthcl', 'h_____cr__01', '1.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__02', '2.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__03', '3.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__04', '4.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__05', '5.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__06', '6.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__07', '7.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__08', '8.red.color'),
|
||||
('c___cr-sthcl', 'h_____cr__09', '9.red.color');
|
||||
|
||||
insert into static_host_set
|
||||
(catalog_id, public_id, name)
|
||||
values
|
||||
('c___cb-sthcl', 's___1cb-sths', 'Blue Color Static Set 1'),
|
||||
('c___cb-sthcl', 's___2cb-sths', 'Blue Color Static Set 2'),
|
||||
('c___cr-sthcl', 's___1cr-sths', 'Red Color Static Set 1'),
|
||||
('c___cr-sthcl', 's___2cr-sths', 'Red Color Static Set 2');
|
||||
|
||||
insert
|
||||
into static_host_set_member
|
||||
( host_id, set_id, catalog_id)
|
||||
select h.public_id, s.public_id, s.catalog_id
|
||||
from static_host as h,
|
||||
static_host_set as s
|
||||
where h.catalog_id = s.catalog_id;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- _wtt_load_colors_targets populates all target_ tables for the colors persona.
|
||||
-- targets depend on iam, auth, hosts.
|
||||
create function _wtt_load_colors_targets()
|
||||
returns void
|
||||
as $$
|
||||
begin
|
||||
insert into target_tcp
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
('p____bcolors', 't_________cb', 'Blue Color Target'),
|
||||
('p____rcolors', 't_________cr', 'Red Color Target');
|
||||
|
||||
insert into target_host_set
|
||||
(target_id, host_set_id)
|
||||
values
|
||||
('t_________cb', 's___1cb-sths'),
|
||||
('t_________cb', 's___2cb-sths'),
|
||||
('t_________cr', 's___1cr-sths'),
|
||||
('t_________cr', 's___2cr-sths');
|
||||
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
commit;
|
||||
File renamed without changes.
@@ -20,12 +20,12 @@ begin;
|
||||
('o_____widget', 'project', 'p____swidget', 'Small Widget Factory');
|
||||
|
||||
-- Add global users
|
||||
insert into iam_user
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
('global', 'u_______gary', 'Gary'),
|
||||
('global', 'u_______gina', 'Gina'),
|
||||
('global', 'u______nancy', 'Nancy');
|
||||
-- insert into iam_user
|
||||
-- (scope_id, public_id, name)
|
||||
-- values
|
||||
-- ('global', 'u_______gary', 'Gary'),
|
||||
-- ('global', 'u_______gina', 'Gina'),
|
||||
-- ('global', 'u______nancy', 'Nancy');
|
||||
|
||||
-- Add organization users
|
||||
insert into iam_user
|
||||
@@ -39,7 +39,7 @@ begin;
|
||||
insert into iam_group
|
||||
(scope_id, public_id, name)
|
||||
values
|
||||
('global', 'g___gg-group', 'Global Group'),
|
||||
-- ('global', 'g___gg-group', 'Global Group'),
|
||||
('o_____widget', 'g___ow-group', 'Widget Inc Group'),
|
||||
('p____bwidget', 'g___wb-group', 'Big Widget Group'),
|
||||
('p____swidget', 'g___ws-group', 'Small Widget Group');
|
||||
@@ -47,7 +47,7 @@ begin;
|
||||
insert into iam_group_member_user
|
||||
(group_id, member_id)
|
||||
values
|
||||
('g___gg-group', 'u_______gary'),
|
||||
-- ('g___gg-group', 'u_______gary'),
|
||||
('g___ow-group', 'u_____walter'),
|
||||
('g___wb-group', 'u_____warren'),
|
||||
('g___ws-group', 'u_____waylon');
|
||||
@@ -55,18 +55,18 @@ begin;
|
||||
insert into iam_role
|
||||
(scope_id, grant_scope_id, public_id, name)
|
||||
values
|
||||
-- ('global', 'global', 'r_gg_____buy', 'Purchaser'),
|
||||
-- ('global', 'global', 'r_gg____shop', 'Shopper'),
|
||||
('p____bwidget', 'p____bwidget', 'r_pp_bw__bld', 'Widget Builder'),
|
||||
('p____swidget', 'p____swidget', 'r_pp_sw__bld', 'Widget Builder'),
|
||||
('o_____widget', 'p____swidget', 'r_op_sw__eng', 'Small Widget Engineer'),
|
||||
('o_____widget', 'o_____widget', 'r_oo_____eng', 'Widget Engineer'),
|
||||
('global', 'global', 'r_gg_____buy', 'Purchaser'),
|
||||
('global', 'global', 'r_gg____shop', 'Shopper');
|
||||
('o_____widget', 'o_____widget', 'r_oo_____eng', 'Widget Engineer');
|
||||
|
||||
insert into iam_role_grant
|
||||
(role_id, canonical_grant, raw_grant)
|
||||
values
|
||||
('r_gg_____buy', 'type=*;action=purchase', 'purchase anything'),
|
||||
('r_gg____shop', 'type=*;action=view', 'view anything'),
|
||||
-- ('r_gg_____buy', 'type=*;action=purchase', 'purchase anything'),
|
||||
-- ('r_gg____shop', 'type=*;action=view', 'view anything'),
|
||||
('r_oo_____eng', 'type=widget;action=design', 'design widget'),
|
||||
('r_op_sw__eng', 'type=widget;action=design', 'design widget'),
|
||||
('r_op_sw__eng', 'type=widget;action=tune', 'tune widget'),
|
||||
@@ -81,11 +81,11 @@ begin;
|
||||
('r_pp_bw__bld', 'g___wb-group'), -- widget
|
||||
('r_pp_sw__bld', 'g___ws-group'); -- widget
|
||||
|
||||
insert into iam_user_role
|
||||
(role_id, principal_id)
|
||||
values
|
||||
('r_gg_____buy', 'u_auth'),
|
||||
('r_gg____shop', 'u_anon');
|
||||
-- insert into iam_user_role
|
||||
-- (role_id, principal_id)
|
||||
-- values
|
||||
-- ('r_gg_____buy', 'u_auth'),
|
||||
-- ('r_gg____shop', 'u_anon');
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
@@ -234,7 +234,8 @@ begin;
|
||||
select h.public_id, s.public_id, s.catalog_id
|
||||
from static_host as h,
|
||||
static_host_set as s
|
||||
where h.catalog_id = s.catalog_id;
|
||||
where h.catalog_id = s.catalog_id
|
||||
and h.address like '%.widget';
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
|
||||
@@ -4,15 +4,15 @@ begin;
|
||||
|
||||
-- invalid or missing args
|
||||
select throws_ok($$select wtt_load('unknown', 'iam')$$);
|
||||
select throws_ok($$select wtt_load('colors', 'unknown')$$);
|
||||
select throws_ok($$select wtt_load('colors')$$);
|
||||
select throws_ok($$select wtt_load('widgets', 'unknown')$$);
|
||||
select throws_ok($$select wtt_load('widgets')$$);
|
||||
select throws_ok($$select wtt_load()$$);
|
||||
|
||||
-- incorrect order since auth depends on iam
|
||||
select throws_ok($$select wtt_load('colors', 'auth', 'iam')$$);
|
||||
select throws_ok($$select wtt_load('widgets', 'auth', 'iam')$$);
|
||||
|
||||
-- missing a dependancy, auth depends on iam
|
||||
select throws_ok($$select wtt_load('colors', 'auth')$$);
|
||||
select throws_ok($$select wtt_load('widgets', 'auth')$$);
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@@ -1,7 +0,0 @@
|
||||
-- wtt_load_colors tests the wtt_load test helper function for the colors persona.
|
||||
begin;
|
||||
select plan(1);
|
||||
select lives_ok($$select wtt_load('colors', 'iam', 'kms', 'auth', 'hosts', 'targets')$$);
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@@ -0,0 +1,45 @@
|
||||
-- session_multiple_sessions tests the wh_host_dimesion when
|
||||
-- multiple sessions are created using the same user and auth method.
|
||||
begin;
|
||||
select plan(4);
|
||||
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets');
|
||||
|
||||
-- ensure no existing dimensions
|
||||
select is(count(*), 0::bigint) from wh_host_dimension where organization_id = 'o_____widget';
|
||||
|
||||
-- insert first session, should result in a new user dimension
|
||||
insert into session
|
||||
( scope_id , target_id , host_set_id , host_id , user_id , auth_token_id , certificate , endpoint , public_id)
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____walter' , 'tok___walter' , 'abc'::bytea , 'ep1' , 's1____walter');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_host_dimension where organization_id = 'o_____widget';
|
||||
|
||||
-- another session with:
|
||||
-- * same user
|
||||
-- * same auth
|
||||
-- * same host
|
||||
-- should not result in a new user dimension
|
||||
insert into session
|
||||
( scope_id , target_id , host_set_id , host_id , user_id , auth_token_id , certificate , endpoint , public_id)
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____walter' , 'tok___walter' , 'abc'::bytea , 'ep1' , 's2____walter');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_host_dimension where organization_id = 'o_____widget';
|
||||
|
||||
-- another session with:
|
||||
-- * different user
|
||||
-- * same auth
|
||||
-- * same host
|
||||
-- should not result in a new user dimension
|
||||
insert into session
|
||||
( scope_id , target_id , host_set_id , host_id , user_id , auth_token_id , certificate , endpoint , public_id)
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____warren' , 'tok___warren' , 'abc'::bytea , 'ep1' , 's3____walter');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_host_dimension where organization_id = 'o_____widget';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
-- session_update tests the wh_host_dimesion when
|
||||
-- a session is inserted and then updated.
|
||||
begin;
|
||||
select plan(3);
|
||||
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets');
|
||||
|
||||
-- ensure no existing dimensions
|
||||
select is(count(*), 0::bigint) from wh_host_dimension where organization_id = 'o_____widget';
|
||||
|
||||
-- insert first session, should result in a new user dimension
|
||||
insert into session
|
||||
( scope_id , target_id , host_set_id , host_id , user_id , auth_token_id , certificate , endpoint , public_id)
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____walter' , 'tok___walter' , 'abc'::bytea , 'ep1' , 's1____walter');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_host_dimension where organization_id = 'o_____widget';
|
||||
|
||||
-- update session, should not impact wh_host_dimension
|
||||
update session set
|
||||
version = 2
|
||||
where
|
||||
public_id = 's1____walter';
|
||||
|
||||
select is(count(*), 1::bigint) from wh_host_dimension where organization_id = 'o_____widget';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@@ -0,0 +1,22 @@
|
||||
-- source tests the whx_host_dimension_source view.
|
||||
begin;
|
||||
select plan(1);
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets');
|
||||
|
||||
-- auth_password_account
|
||||
select is(s.*, row(
|
||||
'h_____wb__01', 'static host', 'None', 'None', '1.big.widget',
|
||||
's___2wb-sths', 'static host set', 'Big Widget Static Set 2', 'None',
|
||||
'c___wb-sthcl', 'static host catalog', 'Big Widget Static Catalog', 'None',
|
||||
't_________wb', 'tcp target', 'Big Widget Target', 'None', 0, 28800, 1,
|
||||
'p____bwidget', 'Big Widget Factory', 'None',
|
||||
'o_____widget', 'Widget Inc', 'None'
|
||||
)::whx_host_dimension_source)
|
||||
from whx_host_dimension_source as s
|
||||
where s.host_id = 'h_____wb__01'
|
||||
and s.host_set_id = 's___2wb-sths'
|
||||
and s.target_id = 't_________wb';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
-- target tests teh whx_host_dimension_target view.
|
||||
begin;
|
||||
select plan(2);
|
||||
|
||||
select is_empty($$
|
||||
select * from whx_host_dimension_target
|
||||
where host_id = 'h_____wb__01'
|
||||
and host_set_id = 's___2wb-sths'
|
||||
and target_id = 't_________wb';
|
||||
$$);
|
||||
|
||||
insert into wh_host_dimension
|
||||
(
|
||||
key,
|
||||
host_id, host_type, host_name, host_description, host_address,
|
||||
host_set_id, host_set_type, host_set_name, host_set_description,
|
||||
host_catalog_id, host_catalog_type, host_catalog_name, host_catalog_description,
|
||||
target_id, target_type, target_name, target_description, target_default_port_number, target_session_max_seconds, target_session_connection_limit,
|
||||
project_id, project_name, project_description,
|
||||
organization_id, organization_name, organization_description,
|
||||
current_row_indicator, row_effective_time, row_expiration_time
|
||||
)
|
||||
values
|
||||
(
|
||||
'whd_____1',
|
||||
'h_____wb__01', 'static host', 'None', 'None', '1.big.widget',
|
||||
's___2wb-sths', 'static host set', 'Big Widget Static Set 2', 'None',
|
||||
'c___wb-sthcl', 'static host catalog', 'Big Widget Static Catalog', 'None',
|
||||
't_________wb', 'tcp target', 'Big Widget Target', 'None', 0, 28800, 1,
|
||||
'p____bwidget', 'Big Widget Factory', 'None',
|
||||
'o_____widget', 'Widget Inc', 'None',
|
||||
'Expired', '2021-07-21T11:01'::timestamptz, '2021-07-21T12:01'::timestamptz
|
||||
),
|
||||
(
|
||||
'whd_____2',
|
||||
'h_____wb__01', 'static host', 'None', 'None', '1.big.widget',
|
||||
's___2wb-sths', 'static host set', 'Big Widget Static Set 2', 'None',
|
||||
'c___wb-sthcl', 'static host catalog', 'Big Widget Static Catalog', 'None',
|
||||
't_________wb', 'tcp target', 'Big Widget Target', 'None', 0, 28800, 1,
|
||||
'p____bwidget', 'Big Widget Factory', 'None',
|
||||
'o_____widget', 'Widget Inc', 'None',
|
||||
'Current', '2021-07-21T12:01'::timestamptz, 'infinity'::timestamptz
|
||||
);
|
||||
|
||||
select is(t.*, row(
|
||||
'whd_____2',
|
||||
'h_____wb__01', 'static host', 'None', 'None', '1.big.widget',
|
||||
's___2wb-sths', 'static host set', 'Big Widget Static Set 2', 'None',
|
||||
'c___wb-sthcl', 'static host catalog', 'Big Widget Static Catalog', 'None',
|
||||
't_________wb', 'tcp target', 'Big Widget Target', 'None', 0, 28800, 1,
|
||||
'p____bwidget', 'Big Widget Factory', 'None',
|
||||
'o_____widget', 'Widget Inc', 'None'
|
||||
)::whx_host_dimension_target)
|
||||
from whx_host_dimension_target as t
|
||||
where t.host_id = 'h_____wb__01'
|
||||
and t.host_set_id = 's___2wb-sths'
|
||||
and t.target_id = 't_________wb';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
-- insert tests that a wh_session_accumulating_fact is created when
|
||||
-- a session is created.
|
||||
begin;
|
||||
select plan(2);
|
||||
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets');
|
||||
|
||||
select is(count(*), 0::bigint) from wh_session_accumulating_fact where session_id = 's1____walter';
|
||||
|
||||
-- insert first session, should result in a new wh_session_accumulating_fact
|
||||
insert into session
|
||||
( scope_id , target_id , host_set_id , host_id , user_id , auth_token_id , certificate , endpoint , public_id)
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____walter' , 'tok___walter' , 'abc'::bytea , 'ep1' , 's1____walter');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_session_accumulating_fact where session_id = 's1____walter';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@@ -0,0 +1,24 @@
|
||||
begin;
|
||||
select plan(8);
|
||||
|
||||
select is(count(*), 1::bigint) from wh_session_accumulating_fact where session_id = 's1_____clare';
|
||||
select is(total_bytes_up, null) from wh_session_accumulating_fact where session_id = 's1_____clare';
|
||||
select is(total_bytes_down, null) from wh_session_accumulating_fact where session_id = 's1_____clare';
|
||||
select is(session_terminated_time, 'infinity'::wh_timestamp) from wh_session_accumulating_fact where session_id = 's1_____clare';
|
||||
|
||||
update session_connection set
|
||||
bytes_up = 10,
|
||||
bytes_down = 5,
|
||||
closed_reason = 'closed by end-user'
|
||||
where public_id = 'sc1_____clare';
|
||||
update session set
|
||||
termination_reason = 'closed by end-user'
|
||||
where public_id = 's1_____clare';
|
||||
|
||||
select is(count(*), 1::bigint) from wh_session_accumulating_fact;
|
||||
select is(total_bytes_up, 10::wh_bytes_transmitted) from wh_session_accumulating_fact where session_id = 's1_____clare';
|
||||
select is(total_bytes_down, 5::wh_bytes_transmitted) from wh_session_accumulating_fact where session_id = 's1_____clare';
|
||||
select is(session_terminated_time, now()::wh_timestamp) from wh_session_accumulating_fact where session_id = 's1_____clare';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@@ -0,0 +1,23 @@
|
||||
-- insert tests that a wh_session_connection_accumulating_fact is created when
|
||||
-- a connection is established.
|
||||
begin;
|
||||
select plan(2);
|
||||
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets');
|
||||
|
||||
select is(count(*), 0::bigint) from wh_session_connection_accumulating_fact where connection_id = 'sc1____walter';
|
||||
|
||||
insert into session
|
||||
( scope_id , target_id , host_set_id , host_id , user_id , auth_token_id , certificate , endpoint , public_id)
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____walter' , 'tok___walter' , 'abc'::bytea , 'ep1' , 's1____walter');
|
||||
|
||||
insert into session_connection
|
||||
(session_id, public_id)
|
||||
values
|
||||
('s1____walter', 'sc1____walter');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_session_connection_accumulating_fact where connection_id = 'sc1____walter';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@@ -0,0 +1,21 @@
|
||||
begin;
|
||||
select plan(8);
|
||||
|
||||
select is(count(*), 1::bigint) from wh_session_connection_accumulating_fact where connection_id = 'sc1_____clare';
|
||||
select is(bytes_up, null) from wh_session_connection_accumulating_fact where connection_id = 'sc1_____clare';
|
||||
select is(bytes_down, null) from wh_session_connection_accumulating_fact where connection_id = 'sc1_____clare';
|
||||
select is(connection_closed_time, 'infinity'::wh_timestamp) from wh_session_connection_accumulating_fact where connection_id = 'sc1_____clare';
|
||||
|
||||
update session_connection set
|
||||
bytes_up = 10,
|
||||
bytes_down = 5,
|
||||
closed_reason = 'closed by end-user'
|
||||
where public_id = 'sc1_____clare';
|
||||
|
||||
select is(count(*), 1::bigint) from wh_session_connection_accumulating_fact;
|
||||
select is(bytes_up, 10::wh_bytes_transmitted) from wh_session_connection_accumulating_fact where connection_id = 'sc1_____clare';
|
||||
select is(bytes_down, 5::wh_bytes_transmitted) from wh_session_connection_accumulating_fact where connection_id = 'sc1_____clare';
|
||||
select is(connection_closed_time, now()::wh_timestamp) from wh_session_connection_accumulating_fact where connection_id = 'sc1_____clare';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@@ -6,12 +6,12 @@ begin;
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets');
|
||||
|
||||
-- ensure no existing dimensions
|
||||
select is(count(*), 0::bigint) from wh_user_dimension;
|
||||
select is(count(*), 0::bigint) from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select lives_ok($$select wh_upsert_user('u_____walter', 'tok___walter')$$);
|
||||
|
||||
-- upsert should insert a user_dimension
|
||||
select is(count(*), 1::bigint) from wh_user_dimension;
|
||||
select is(count(*), 1::bigint) from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@@ -6,11 +6,11 @@ begin;
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets');
|
||||
|
||||
-- ensure no existing dimensions
|
||||
select is(count(*), 0::bigint) from wh_user_dimension;
|
||||
select is(count(*), 0::bigint) from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
insert into wh_user_dimension
|
||||
(
|
||||
id,
|
||||
key,
|
||||
user_id, user_name, user_description,
|
||||
auth_account_id, auth_account_type, auth_account_name, auth_account_description,
|
||||
auth_account_external_id, auth_account_full_name, auth_account_email,
|
||||
@@ -34,8 +34,8 @@ begin;
|
||||
select lives_ok($$select wh_upsert_user('u_____walter', 'tok___walter')$$);
|
||||
|
||||
-- upsert should insert a user_dimension
|
||||
select is(count(*), 2::bigint) from wh_user_dimension;
|
||||
select is(count(*), 1::bigint) from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(count(*), 2::bigint) from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(count(*), 1::bigint) from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@@ -6,7 +6,7 @@ begin;
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets');
|
||||
|
||||
-- ensure no existing dimensions
|
||||
select is(count(*), 0::bigint) from wh_user_dimension;
|
||||
select is(count(*), 0::bigint) from wh_user_dimension where user_organization_id = 'o_____widget';
|
||||
|
||||
-- insert first session, should result in a new user dimension
|
||||
insert into session
|
||||
@@ -14,30 +14,30 @@ begin;
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____walter' , 'oidc__walter' , 'abc'::bytea , 'ep1' , 's1____walter');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_user_dimension;
|
||||
select is(user_id, 'u_____walter') from wh_user_dimension;
|
||||
select is(user_name, 'Walter') from wh_user_dimension;
|
||||
select is(user_description, 'None') from wh_user_dimension;
|
||||
select is(count(*), 1::bigint) from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_id, 'u_____walter') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_name, 'Walter') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_description, 'None') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select is(auth_account_id, 'aoa___walter') from wh_user_dimension;
|
||||
select is(auth_account_type, 'oidc auth account') from wh_user_dimension;
|
||||
select is(auth_account_name, 'walter account') from wh_user_dimension;
|
||||
select is(auth_account_description, 'Walter OIDC Account') from wh_user_dimension;
|
||||
select is(auth_account_external_id, 'sub___walter') from wh_user_dimension;
|
||||
select is(auth_account_full_name, 'Walter') from wh_user_dimension;
|
||||
select is(auth_account_email, 'walter@widget.test') from wh_user_dimension;
|
||||
select is(auth_account_id, 'aoa___walter') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_type, 'oidc auth account') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_name, 'walter account') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_description, 'Walter OIDC Account') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_external_id, 'sub___walter') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_full_name, 'Walter') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_email, 'walter@widget.test') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select is(auth_method_id, 'aom___widget') from wh_user_dimension;
|
||||
select is(auth_method_type, 'oidc auth method') from wh_user_dimension;
|
||||
select is(auth_method_name, 'Widget OIDC') from wh_user_dimension;
|
||||
select is(auth_method_description, 'None') from wh_user_dimension;
|
||||
select is(auth_method_external_id, 'https://oidc.widget.test') from wh_user_dimension;
|
||||
select is(auth_method_id, 'aom___widget') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_method_type, 'oidc auth method') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_method_name, 'Widget OIDC') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_method_description, 'None') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_method_external_id, 'https://oidc.widget.test') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select is(user_organization_id, 'o_____widget') from wh_user_dimension;
|
||||
select is(user_organization_name, 'Widget Inc') from wh_user_dimension;
|
||||
select is(user_organization_description, 'None') from wh_user_dimension;
|
||||
select is(user_organization_id, 'o_____widget') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_organization_name, 'Widget Inc') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_organization_description, 'None') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select is(current_row_indicator, 'Current') from wh_user_dimension;
|
||||
select is(current_row_indicator, 'Current') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
-- insert session without full name or email
|
||||
insert into session
|
||||
|
||||
@@ -7,7 +7,7 @@ begin;
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets');
|
||||
|
||||
-- ensure no existing dimensions
|
||||
select is(count(*), 0::bigint) from wh_user_dimension;
|
||||
select is(count(*), 0::bigint) from wh_user_dimension where user_organization_id = 'o_____widget';
|
||||
|
||||
-- insert first session, should result in a new user dimension
|
||||
insert into session
|
||||
@@ -15,30 +15,30 @@ begin;
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____walter' , 'tok___walter' , 'abc'::bytea , 'ep1' , 's1____walter');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_user_dimension;
|
||||
select is(user_id, 'u_____walter') from wh_user_dimension;
|
||||
select is(user_name, 'Walter') from wh_user_dimension;
|
||||
select is(user_description, 'None') from wh_user_dimension;
|
||||
select is(count(*), 1::bigint) from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_id, 'u_____walter') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_name, 'Walter') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_description, 'None') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select is(auth_account_id, 'apa___walter') from wh_user_dimension;
|
||||
select is(auth_account_type, 'password auth account') from wh_user_dimension;
|
||||
select is(auth_account_name, 'None') from wh_user_dimension;
|
||||
select is(auth_account_description, 'None') from wh_user_dimension;
|
||||
select is(auth_account_external_id, 'Not Applicable') from wh_user_dimension;
|
||||
select is(auth_account_full_name, 'Not Applicable') from wh_user_dimension;
|
||||
select is(auth_account_email, 'Not Applicable') from wh_user_dimension;
|
||||
select is(auth_account_id, 'apa___walter') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_type, 'password auth account') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_name, 'None') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_description, 'None') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_external_id, 'Not Applicable') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_full_name, 'Not Applicable') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_email, 'Not Applicable') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select is(auth_method_id, 'apm___widget') from wh_user_dimension;
|
||||
select is(auth_method_type, 'password auth method') from wh_user_dimension;
|
||||
select is(auth_method_name, 'Widget Auth Password') from wh_user_dimension;
|
||||
select is(auth_method_description, 'None') from wh_user_dimension;
|
||||
select is(auth_method_external_id, 'Not Applicable') from wh_user_dimension;
|
||||
select is(auth_method_id, 'apm___widget') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_method_type, 'password auth method') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_method_name, 'Widget Auth Password') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_method_description, 'None') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_method_external_id, 'Not Applicable') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select is(user_organization_id, 'o_____widget') from wh_user_dimension;
|
||||
select is(user_organization_name, 'Widget Inc') from wh_user_dimension;
|
||||
select is(user_organization_description, 'None') from wh_user_dimension;
|
||||
select is(user_organization_id, 'o_____widget') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_organization_name, 'Widget Inc') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_organization_description, 'None') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select is(current_row_indicator, 'Current') from wh_user_dimension;
|
||||
select is(current_row_indicator, 'Current') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
-- change auth description
|
||||
update auth_password_account set
|
||||
@@ -56,29 +56,29 @@ begin;
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____walter' , 'tok___walter' , 'abc'::bytea , 'ep1' , 's2____walter');
|
||||
|
||||
select is(count(*), 2::bigint) from wh_user_dimension;
|
||||
select is(count(*), 2::bigint) from wh_user_dimension where user_organization_id = 'o_____widget';
|
||||
|
||||
select is(user_id, 'u_____walter') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(user_name, 'Walter') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(user_description, 'None') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(user_id, 'u_____walter') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
select is(user_name, 'Walter') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
select is(user_description, 'None') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
|
||||
select is(auth_account_id, 'apa___walter') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(auth_account_type, 'password auth account') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(auth_account_name, 'None') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(auth_account_description, 'Walter Password Account') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(auth_account_external_id, 'Not Applicable') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(auth_account_full_name, 'Not Applicable') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(auth_account_email, 'Not Applicable') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(auth_account_id, 'apa___walter') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
select is(auth_account_type, 'password auth account') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
select is(auth_account_name, 'None') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
select is(auth_account_description, 'Walter Password Account') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
select is(auth_account_external_id, 'Not Applicable') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
select is(auth_account_full_name, 'Not Applicable') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
select is(auth_account_email, 'Not Applicable') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
|
||||
select is(auth_method_id, 'apm___widget') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(auth_method_type, 'password auth method') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(auth_method_name, 'Widget Auth Password') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(auth_method_description, 'None') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(auth_method_external_id, 'Not Applicable') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(auth_method_id, 'apm___widget') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
select is(auth_method_type, 'password auth method') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
select is(auth_method_name, 'Widget Auth Password') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
select is(auth_method_description, 'None') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
select is(auth_method_external_id, 'Not Applicable') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
|
||||
select is(user_organization_id, 'o_____widget') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(user_organization_name, 'Widget Inc') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(user_organization_description, 'None') from wh_user_dimension where current_row_indicator = 'Current';
|
||||
select is(user_organization_id, 'o_____widget') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
select is(user_organization_name, 'Widget Inc') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
select is(user_organization_description, 'None') from wh_user_dimension where user_id = 'u_____walter' and current_row_indicator = 'Current';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@@ -6,7 +6,7 @@ begin;
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets');
|
||||
|
||||
-- ensure no existing dimensions
|
||||
select is(count(*), 0::bigint) from wh_user_dimension;
|
||||
select is(count(*), 0::bigint) from wh_user_dimension where user_organization_id = 'o_____widget';
|
||||
|
||||
-- insert first session, should result in a new user dimension
|
||||
insert into session
|
||||
@@ -14,30 +14,30 @@ begin;
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____walter' , 'tok___walter' , 'abc'::bytea , 'ep1' , 's1____walter');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_user_dimension;
|
||||
select is(user_id, 'u_____walter') from wh_user_dimension;
|
||||
select is(user_name, 'Walter') from wh_user_dimension;
|
||||
select is(user_description, 'None') from wh_user_dimension;
|
||||
select is(count(*), 1::bigint) from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_id, 'u_____walter') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_name, 'Walter') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_description, 'None') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select is(auth_account_id, 'apa___walter') from wh_user_dimension;
|
||||
select is(auth_account_type, 'password auth account') from wh_user_dimension;
|
||||
select is(auth_account_name, 'None') from wh_user_dimension;
|
||||
select is(auth_account_description, 'None') from wh_user_dimension;
|
||||
select is(auth_account_external_id, 'Not Applicable') from wh_user_dimension;
|
||||
select is(auth_account_full_name, 'Not Applicable') from wh_user_dimension;
|
||||
select is(auth_account_email, 'Not Applicable') from wh_user_dimension;
|
||||
select is(auth_account_id, 'apa___walter') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_type, 'password auth account') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_name, 'None') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_description, 'None') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_external_id, 'Not Applicable') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_full_name, 'Not Applicable') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_account_email, 'Not Applicable') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select is(auth_method_id, 'apm___widget') from wh_user_dimension;
|
||||
select is(auth_method_type, 'password auth method') from wh_user_dimension;
|
||||
select is(auth_method_name, 'Widget Auth Password') from wh_user_dimension;
|
||||
select is(auth_method_description, 'None') from wh_user_dimension;
|
||||
select is(auth_method_external_id, 'Not Applicable') from wh_user_dimension;
|
||||
select is(auth_method_id, 'apm___widget') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_method_type, 'password auth method') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_method_name, 'Widget Auth Password') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_method_description, 'None') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(auth_method_external_id, 'Not Applicable') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select is(user_organization_id, 'o_____widget') from wh_user_dimension;
|
||||
select is(user_organization_name, 'Widget Inc') from wh_user_dimension;
|
||||
select is(user_organization_description, 'None') from wh_user_dimension;
|
||||
select is(user_organization_id, 'o_____widget') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_organization_name, 'Widget Inc') from wh_user_dimension where user_id = 'u_____walter';
|
||||
select is(user_organization_description, 'None') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select is(current_row_indicator, 'Current') from wh_user_dimension;
|
||||
select is(current_row_indicator, 'Current') from wh_user_dimension where user_id = 'u_____walter';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@@ -6,7 +6,7 @@ begin;
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets');
|
||||
|
||||
-- ensure no existing dimensions
|
||||
select is(count(*), 0::bigint) from wh_user_dimension;
|
||||
select is(count(*), 0::bigint) from wh_user_dimension where user_organization_id = 'o_____widget';
|
||||
|
||||
-- insert first session, should result in a new user dimension
|
||||
insert into session
|
||||
@@ -14,7 +14,7 @@ begin;
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____walter' , 'tok___walter' , 'abc'::bytea , 'ep1' , 's1____walter');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_user_dimension;
|
||||
select is(count(*), 1::bigint) from wh_user_dimension where user_organization_id = 'o_____widget';
|
||||
|
||||
-- another session with:
|
||||
-- * same user
|
||||
@@ -26,7 +26,7 @@ begin;
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____walter' , 'tok___walter' , 'abc'::bytea , 'ep1' , 's2____walter');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_user_dimension;
|
||||
select is(count(*), 1::bigint) from wh_user_dimension where user_organization_id = 'o_____widget';
|
||||
|
||||
-- another session with:
|
||||
-- * same user
|
||||
@@ -38,7 +38,7 @@ begin;
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__02' , 'u_____walter' , 'tok___walter' , 'abc'::bytea , 'ep1' , 's3____walter');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_user_dimension;
|
||||
select is(count(*), 1::bigint) from wh_user_dimension where user_organization_id = 'o_____widget';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
+19
-19
@@ -7,7 +7,7 @@ begin;
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets');
|
||||
|
||||
-- ensure no existing dimensions
|
||||
select is(count(*), 0::bigint) from wh_user_dimension;
|
||||
select is(count(*), 0::bigint) from wh_user_dimension where user_organization_id = 'o_____widget';
|
||||
|
||||
-- insert first session, should result in a new user dimension
|
||||
insert into session
|
||||
@@ -15,7 +15,7 @@ begin;
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____walter' , 'tok___walter' , 'abc'::bytea , 'ep1' , 's1____walter');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_user_dimension;
|
||||
select is(count(*), 1::bigint) from wh_user_dimension where user_organization_id = 'o_____widget';
|
||||
|
||||
-- another session with:
|
||||
-- * same user
|
||||
@@ -27,28 +27,28 @@ begin;
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____walter' , 'tok1__walter' , 'abc'::bytea , 'ep1' , 's4____walter');
|
||||
|
||||
select is(count(*), 2::bigint) from wh_user_dimension;
|
||||
select is(count(*), 1::bigint) from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(count(*), 2::bigint) from wh_user_dimension where user_organization_id = 'o_____widget';
|
||||
select is(count(*), 1::bigint) from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
|
||||
select is(user_id, 'u_____walter') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(user_name, 'Walter') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(user_description, 'None') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(user_id, 'u_____walter') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
select is(user_name, 'Walter') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
select is(user_description, 'None') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
|
||||
select is(auth_account_id, 'apa1__walter') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(auth_account_type, 'password auth account') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(auth_account_name, 'None') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(auth_account_description, 'None') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(auth_account_id, 'apa1__walter') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
select is(auth_account_type, 'password auth account') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
select is(auth_account_name, 'None') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
select is(auth_account_description, 'None') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
|
||||
select is(auth_method_id, 'apm1__widget') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(auth_method_type, 'password auth method') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(auth_method_name, 'Widget Auth Password 1') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(auth_method_description, 'None') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(auth_method_id, 'apm1__widget') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
select is(auth_method_type, 'password auth method') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
select is(auth_method_name, 'Widget Auth Password 1') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
select is(auth_method_description, 'None') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
|
||||
select is(user_organization_id, 'o_____widget') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(user_organization_name, 'Widget Inc') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(user_organization_description, 'None') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(user_organization_id, 'o_____widget') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
select is(user_organization_name, 'Widget Inc') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
select is(user_organization_description, 'None') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
|
||||
select is(current_row_indicator, 'Current') from wh_user_dimension where auth_account_id = 'apa1__walter';
|
||||
select is(current_row_indicator, 'Current') from wh_user_dimension where user_id = 'u_____walter' and auth_account_id = 'apa1__walter';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
|
||||
@@ -6,7 +6,7 @@ begin;
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets');
|
||||
|
||||
-- ensure no existing dimensions
|
||||
select is(count(*), 0::bigint) from wh_user_dimension;
|
||||
select is(count(*), 0::bigint) from wh_user_dimension where user_organization_id = 'o_____widget';
|
||||
|
||||
-- insert first session, should result in a new user dimension
|
||||
insert into session
|
||||
@@ -14,7 +14,7 @@ begin;
|
||||
values
|
||||
('p____bwidget' , 't_________wb' , 's___1wb-sths' , 'h_____wb__01' , 'u_____walter' , 'tok___walter' , 'abc'::bytea , 'ep1' , 's1____walter');
|
||||
|
||||
select is(count(*), 1::bigint) from wh_user_dimension;
|
||||
select is(count(*), 1::bigint) from wh_user_dimension where user_organization_id = 'o_____widget';
|
||||
|
||||
-- update session, should not impact wh_user_dimension
|
||||
update session set
|
||||
@@ -22,7 +22,7 @@ begin;
|
||||
where
|
||||
public_id = 's1____walter';
|
||||
|
||||
select is(count(*), 1::bigint) from wh_user_dimension;
|
||||
select is(count(*), 1::bigint) from wh_user_dimension where user_organization_id = 'o_____widget';
|
||||
|
||||
select * from finish();
|
||||
rollback;
|
||||
@@ -1,4 +1,4 @@
|
||||
-- source tests teh whx_user_dimension_source view.
|
||||
-- source tests the whx_user_dimension_source view.
|
||||
begin;
|
||||
select plan(5);
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets');
|
||||
|
||||
@@ -6,7 +6,7 @@ begin;
|
||||
|
||||
insert into wh_user_dimension
|
||||
(
|
||||
id,
|
||||
key,
|
||||
user_id, user_name, user_description,
|
||||
auth_account_id, auth_account_type, auth_account_name, auth_account_description,
|
||||
auth_account_external_id, auth_account_full_name, auth_account_email,
|
||||
|
||||
@@ -0,0 +1,299 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.15.8
|
||||
// source: testing/event/v1/event.proto
|
||||
|
||||
package event
|
||||
|
||||
import (
|
||||
_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type TestAuthenticateRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// The ID of the Auth Method in the system that should be used for authentication.
|
||||
// @inject_tag: `class:"public"`
|
||||
AuthMethodId string `protobuf:"bytes,1,opt,name=auth_method_id,proto3" json:"auth_method_id,omitempty" class:"public"`
|
||||
// This can be "cookie" or "token". If not provided, "token" will be used. "cookie" activates a split-cookie method where the token is split partially between http-only and regular cookies in order
|
||||
// to keep it safe from rogue JS in the browser.
|
||||
// @inject_tag: `class:"public"`
|
||||
TokenType string `protobuf:"bytes,2,opt,name=token_type,proto3" json:"token_type,omitempty" class:"public"`
|
||||
// Attributes are passed to the Auth Method; the valid keys and values depend on the type of Auth Method as well as the command.
|
||||
Attributes *structpb.Struct `protobuf:"bytes,4,opt,name=attributes,proto3" json:"attributes,omitempty"`
|
||||
// The command to perform.
|
||||
// @inject_tag: `class:"public"`
|
||||
Command string `protobuf:"bytes,5,opt,name=command,proto3" json:"command,omitempty" class:"public"`
|
||||
}
|
||||
|
||||
func (x *TestAuthenticateRequest) Reset() {
|
||||
*x = TestAuthenticateRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_testing_event_v1_event_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *TestAuthenticateRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*TestAuthenticateRequest) ProtoMessage() {}
|
||||
|
||||
func (x *TestAuthenticateRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_testing_event_v1_event_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use TestAuthenticateRequest.ProtoReflect.Descriptor instead.
|
||||
func (*TestAuthenticateRequest) Descriptor() ([]byte, []int) {
|
||||
return file_testing_event_v1_event_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *TestAuthenticateRequest) GetAuthMethodId() string {
|
||||
if x != nil {
|
||||
return x.AuthMethodId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *TestAuthenticateRequest) GetTokenType() string {
|
||||
if x != nil {
|
||||
return x.TokenType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *TestAuthenticateRequest) GetAttributes() *structpb.Struct {
|
||||
if x != nil {
|
||||
return x.Attributes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *TestAuthenticateRequest) GetCommand() string {
|
||||
if x != nil {
|
||||
return x.Command
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type TestAuthenticateResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Valid keys and values depend on the type of Auth Method as well as the command.
|
||||
Attributes *structpb.Struct `protobuf:"bytes,4,opt,name=attributes,proto3" json:"attributes,omitempty"`
|
||||
// The command that was performed.
|
||||
// @inject_tag: `class:"public"`
|
||||
Command string `protobuf:"bytes,5,opt,name=command,proto3" json:"command,omitempty" class:"public"`
|
||||
}
|
||||
|
||||
func (x *TestAuthenticateResponse) Reset() {
|
||||
*x = TestAuthenticateResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_testing_event_v1_event_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *TestAuthenticateResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*TestAuthenticateResponse) ProtoMessage() {}
|
||||
|
||||
func (x *TestAuthenticateResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_testing_event_v1_event_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use TestAuthenticateResponse.ProtoReflect.Descriptor instead.
|
||||
func (*TestAuthenticateResponse) Descriptor() ([]byte, []int) {
|
||||
return file_testing_event_v1_event_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *TestAuthenticateResponse) GetAttributes() *structpb.Struct {
|
||||
if x != nil {
|
||||
return x.Attributes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *TestAuthenticateResponse) GetCommand() string {
|
||||
if x != nil {
|
||||
return x.Command
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_testing_event_v1_event_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_testing_event_v1_event_proto_rawDesc = []byte{
|
||||
0x0a, 0x1c, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2f,
|
||||
0x76, 0x31, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10,
|
||||
0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31,
|
||||
0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||
0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61,
|
||||
0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e,
|
||||
0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb4, 0x01, 0x0a,
|
||||
0x17, 0x54, 0x65, 0x73, 0x74, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68,
|
||||
0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x69, 0x64,
|
||||
0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65,
|
||||
0x12, 0x37, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0a, 0x61,
|
||||
0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d,
|
||||
0x6d, 0x61, 0x6e, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d,
|
||||
0x61, 0x6e, 0x64, 0x22, 0x8b, 0x01, 0x0a, 0x18, 0x54, 0x65, 0x73, 0x74, 0x41, 0x75, 0x74, 0x68,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x37, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0a, 0x61,
|
||||
0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d,
|
||||
0x6d, 0x61, 0x6e, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d,
|
||||
0x61, 0x6e, 0x64, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52,
|
||||
0x04, 0x69, 0x74, 0x65, 0x6d, 0x52, 0x0a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x74, 0x79, 0x70,
|
||||
0x65, 0x32, 0x89, 0x02, 0x0a, 0x15, 0x54, 0x65, 0x73, 0x74, 0x41, 0x75, 0x74, 0x68, 0x4d, 0x65,
|
||||
0x74, 0x68, 0x6f, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xef, 0x01, 0x0a, 0x10,
|
||||
0x54, 0x65, 0x73, 0x74, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65,
|
||||
0x12, 0x29, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x74, 0x65,
|
||||
0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54,
|
||||
0x65, 0x73, 0x74, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x83, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33,
|
||||
0x22, 0x2e, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2d, 0x6d, 0x65, 0x74, 0x68, 0x6f,
|
||||
0x64, 0x73, 0x2f, 0x7b, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f,
|
||||
0x69, 0x64, 0x7d, 0x3a, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65,
|
||||
0x3a, 0x01, 0x2a, 0x92, 0x41, 0x47, 0x12, 0x45, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x63, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x61,
|
||||
0x6e, 0x20, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x65, 0x74, 0x72,
|
||||
0x69, 0x65, 0x76, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2e, 0x42, 0x40, 0x5a,
|
||||
0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68,
|
||||
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x74, 0x65, 0x73, 0x74,
|
||||
0x69, 0x6e, 0x67, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x62,
|
||||
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_testing_event_v1_event_proto_rawDescOnce sync.Once
|
||||
file_testing_event_v1_event_proto_rawDescData = file_testing_event_v1_event_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_testing_event_v1_event_proto_rawDescGZIP() []byte {
|
||||
file_testing_event_v1_event_proto_rawDescOnce.Do(func() {
|
||||
file_testing_event_v1_event_proto_rawDescData = protoimpl.X.CompressGZIP(file_testing_event_v1_event_proto_rawDescData)
|
||||
})
|
||||
return file_testing_event_v1_event_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_testing_event_v1_event_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_testing_event_v1_event_proto_goTypes = []interface{}{
|
||||
(*TestAuthenticateRequest)(nil), // 0: testing.event.v1.TestAuthenticateRequest
|
||||
(*TestAuthenticateResponse)(nil), // 1: testing.event.v1.TestAuthenticateResponse
|
||||
(*structpb.Struct)(nil), // 2: google.protobuf.Struct
|
||||
}
|
||||
var file_testing_event_v1_event_proto_depIdxs = []int32{
|
||||
2, // 0: testing.event.v1.TestAuthenticateRequest.attributes:type_name -> google.protobuf.Struct
|
||||
2, // 1: testing.event.v1.TestAuthenticateResponse.attributes:type_name -> google.protobuf.Struct
|
||||
0, // 2: testing.event.v1.TestAuthMethodService.TestAuthenticate:input_type -> testing.event.v1.TestAuthenticateRequest
|
||||
1, // 3: testing.event.v1.TestAuthMethodService.TestAuthenticate:output_type -> testing.event.v1.TestAuthenticateResponse
|
||||
3, // [3:4] is the sub-list for method output_type
|
||||
2, // [2:3] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_testing_event_v1_event_proto_init() }
|
||||
func file_testing_event_v1_event_proto_init() {
|
||||
if File_testing_event_v1_event_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_testing_event_v1_event_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*TestAuthenticateRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_testing_event_v1_event_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*TestAuthenticateResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_testing_event_v1_event_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_testing_event_v1_event_proto_goTypes,
|
||||
DependencyIndexes: file_testing_event_v1_event_proto_depIdxs,
|
||||
MessageInfos: file_testing_event_v1_event_proto_msgTypes,
|
||||
}.Build()
|
||||
File_testing_event_v1_event_proto = out.File
|
||||
file_testing_event_v1_event_proto_rawDesc = nil
|
||||
file_testing_event_v1_event_proto_goTypes = nil
|
||||
file_testing_event_v1_event_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
||||
// source: testing/event/v1/event.proto
|
||||
|
||||
/*
|
||||
Package event is a reverse proxy.
|
||||
|
||||
It translates gRPC into RESTful JSON APIs.
|
||||
*/
|
||||
package event
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// Suppress "imported and not used" errors
|
||||
var _ codes.Code
|
||||
var _ io.Reader
|
||||
var _ status.Status
|
||||
var _ = runtime.String
|
||||
var _ = utilities.NewDoubleArray
|
||||
var _ = metadata.Join
|
||||
|
||||
func request_TestAuthMethodService_TestAuthenticate_0(ctx context.Context, marshaler runtime.Marshaler, client TestAuthMethodServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq TestAuthenticateRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["auth_method_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "auth_method_id")
|
||||
}
|
||||
|
||||
protoReq.AuthMethodId, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "auth_method_id", err)
|
||||
}
|
||||
|
||||
msg, err := client.TestAuthenticate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_TestAuthMethodService_TestAuthenticate_0(ctx context.Context, marshaler runtime.Marshaler, server TestAuthMethodServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq TestAuthenticateRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["auth_method_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "auth_method_id")
|
||||
}
|
||||
|
||||
protoReq.AuthMethodId, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "auth_method_id", err)
|
||||
}
|
||||
|
||||
msg, err := server.TestAuthenticate(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterTestAuthMethodServiceHandlerServer registers the http handlers for service TestAuthMethodService to "mux".
|
||||
// UnaryRPC :call TestAuthMethodServiceServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterTestAuthMethodServiceHandlerFromEndpoint instead.
|
||||
func RegisterTestAuthMethodServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server TestAuthMethodServiceServer) error {
|
||||
|
||||
mux.Handle("POST", pattern_TestAuthMethodService_TestAuthenticate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/testing.event.v1.TestAuthMethodService/TestAuthenticate")
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_TestAuthMethodService_TestAuthenticate_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_TestAuthMethodService_TestAuthenticate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterTestAuthMethodServiceHandlerFromEndpoint is same as RegisterTestAuthMethodServiceHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterTestAuthMethodServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterTestAuthMethodServiceHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterTestAuthMethodServiceHandler registers the http handlers for service TestAuthMethodService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterTestAuthMethodServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||
return RegisterTestAuthMethodServiceHandlerClient(ctx, mux, NewTestAuthMethodServiceClient(conn))
|
||||
}
|
||||
|
||||
// RegisterTestAuthMethodServiceHandlerClient registers the http handlers for service TestAuthMethodService
|
||||
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "TestAuthMethodServiceClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "TestAuthMethodServiceClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "TestAuthMethodServiceClient" to call the correct interceptors.
|
||||
func RegisterTestAuthMethodServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client TestAuthMethodServiceClient) error {
|
||||
|
||||
mux.Handle("POST", pattern_TestAuthMethodService_TestAuthenticate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/testing.event.v1.TestAuthMethodService/TestAuthenticate")
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_TestAuthMethodService_TestAuthenticate_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_TestAuthMethodService_TestAuthenticate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_TestAuthMethodService_TestAuthenticate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "auth-methods", "auth_method_id"}, "authenticate"))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_TestAuthMethodService_TestAuthenticate_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
@@ -0,0 +1,105 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
|
||||
package event
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
// TestAuthMethodServiceClient is the client API for TestAuthMethodService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type TestAuthMethodServiceClient interface {
|
||||
// TestAuthenticate validates credentials provided and returns an Auth Token.
|
||||
// Deprecated: use AuthenticateLogin instead.
|
||||
TestAuthenticate(ctx context.Context, in *TestAuthenticateRequest, opts ...grpc.CallOption) (*TestAuthenticateResponse, error)
|
||||
}
|
||||
|
||||
type testAuthMethodServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewTestAuthMethodServiceClient(cc grpc.ClientConnInterface) TestAuthMethodServiceClient {
|
||||
return &testAuthMethodServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *testAuthMethodServiceClient) TestAuthenticate(ctx context.Context, in *TestAuthenticateRequest, opts ...grpc.CallOption) (*TestAuthenticateResponse, error) {
|
||||
out := new(TestAuthenticateResponse)
|
||||
err := c.cc.Invoke(ctx, "/testing.event.v1.TestAuthMethodService/TestAuthenticate", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// TestAuthMethodServiceServer is the server API for TestAuthMethodService service.
|
||||
// All implementations must embed UnimplementedTestAuthMethodServiceServer
|
||||
// for forward compatibility
|
||||
type TestAuthMethodServiceServer interface {
|
||||
// TestAuthenticate validates credentials provided and returns an Auth Token.
|
||||
// Deprecated: use AuthenticateLogin instead.
|
||||
TestAuthenticate(context.Context, *TestAuthenticateRequest) (*TestAuthenticateResponse, error)
|
||||
mustEmbedUnimplementedTestAuthMethodServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedTestAuthMethodServiceServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedTestAuthMethodServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedTestAuthMethodServiceServer) TestAuthenticate(context.Context, *TestAuthenticateRequest) (*TestAuthenticateResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method TestAuthenticate not implemented")
|
||||
}
|
||||
func (UnimplementedTestAuthMethodServiceServer) mustEmbedUnimplementedTestAuthMethodServiceServer() {}
|
||||
|
||||
// UnsafeTestAuthMethodServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to TestAuthMethodServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeTestAuthMethodServiceServer interface {
|
||||
mustEmbedUnimplementedTestAuthMethodServiceServer()
|
||||
}
|
||||
|
||||
func RegisterTestAuthMethodServiceServer(s grpc.ServiceRegistrar, srv TestAuthMethodServiceServer) {
|
||||
s.RegisterService(&TestAuthMethodService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _TestAuthMethodService_TestAuthenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(TestAuthenticateRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TestAuthMethodServiceServer).TestAuthenticate(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/testing.event.v1.TestAuthMethodService/TestAuthenticate",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TestAuthMethodServiceServer).TestAuthenticate(ctx, req.(*TestAuthenticateRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// TestAuthMethodService_ServiceDesc is the grpc.ServiceDesc for TestAuthMethodService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var TestAuthMethodService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "testing.event.v1.TestAuthMethodService",
|
||||
HandlerType: (*TestAuthMethodServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "TestAuthenticate",
|
||||
Handler: _TestAuthMethodService_TestAuthenticate_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "testing/event/v1/event.proto",
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package event
|
||||
|
||||
import "github.com/hashicorp/eventlogger/filters/encrypt"
|
||||
|
||||
// Tags implements the encrypt.Taggable interface which allows
|
||||
// TestEventAuthenRequest Attributes to be classified for the encrypt filter.
|
||||
func (req *TestAuthenticateRequest) Tags() ([]encrypt.PointerTag, error) {
|
||||
var tags []encrypt.PointerTag
|
||||
|
||||
if req.Attributes != nil {
|
||||
tags = append(tags, encrypt.PointerTag{
|
||||
Pointer: "/Attributes/Fields/password",
|
||||
Classification: encrypt.SecretClassification,
|
||||
Filter: encrypt.RedactOperation,
|
||||
})
|
||||
}
|
||||
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
// Tags implements the encrypt.Taggable interface which allows
|
||||
// TestEventAuthenResponse Attributes to be classified for the encrypt filter.
|
||||
func (req *TestAuthenticateResponse) Tags() ([]encrypt.PointerTag, error) {
|
||||
|
||||
var tags []encrypt.PointerTag
|
||||
|
||||
if req.Attributes != nil {
|
||||
tags = append(tags, encrypt.PointerTag{
|
||||
Pointer: "/Attributes/Fields/token",
|
||||
Classification: encrypt.SecretClassification,
|
||||
Filter: encrypt.RedactOperation,
|
||||
})
|
||||
}
|
||||
|
||||
return tags, nil
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "testing/event/v1/event.proto",
|
||||
"version": "version not set"
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "TestAuthMethodService"
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"paths": {
|
||||
"/v1/auth-methods/{auth_method_id}:authenticate": {
|
||||
"post": {
|
||||
"summary": "Authenticate a user to an scope and retrieve an authentication token.",
|
||||
"operationId": "TestAuthMethodService_TestAuthenticate",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/testing.event.v1.TestAuthenticateResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "auth_method_id",
|
||||
"description": "The ID of the Auth Method in the system that should be used for authentication.\n@inject_tag: `class:\"public\"`",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/testing.event.v1.TestAuthenticateRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"testing.event.v1.TestAuthMethodService"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"google.protobuf.NullValue": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"NULL_VALUE"
|
||||
],
|
||||
"default": "NULL_VALUE",
|
||||
"description": "`NullValue` is a singleton enumeration to represent the null value for the\n`Value` type union.\n\n The JSON representation for `NullValue` is JSON `null`.\n\n - NULL_VALUE: Null value."
|
||||
},
|
||||
"testing.event.v1.TestAuthenticateRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"auth_method_id": {
|
||||
"type": "string",
|
||||
"title": "The ID of the Auth Method in the system that should be used for authentication.\n@inject_tag: `class:\"public\"`"
|
||||
},
|
||||
"token_type": {
|
||||
"type": "string",
|
||||
"title": "This can be \"cookie\" or \"token\". If not provided, \"token\" will be used. \"cookie\" activates a split-cookie method where the token is split partially between http-only and regular cookies in order\nto keep it safe from rogue JS in the browser.\n@inject_tag: `class:\"public\"`"
|
||||
},
|
||||
"attributes": {
|
||||
"type": "object",
|
||||
"description": "Attributes are passed to the Auth Method; the valid keys and values depend on the type of Auth Method as well as the command."
|
||||
},
|
||||
"command": {
|
||||
"type": "string",
|
||||
"title": "The command to perform.\n@inject_tag: `class:\"public\"`"
|
||||
}
|
||||
}
|
||||
},
|
||||
"testing.event.v1.TestAuthenticateResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"attributes": {
|
||||
"type": "object",
|
||||
"description": "Valid keys and values depend on the type of Auth Method as well as the command."
|
||||
},
|
||||
"command": {
|
||||
"type": "string",
|
||||
"title": "The command that was performed.\n@inject_tag: `class:\"public\"`"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package event
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
wrapping "github.com/hashicorp/go-kms-wrapping"
|
||||
)
|
||||
|
||||
// AuditConfig defines the configuration required for audit events sinks
|
||||
type AuditConfig struct {
|
||||
// FilterOverrides provide an optional a set of overrides for the
|
||||
// FilterOperations to be applied to DataClassifications.
|
||||
FilterOverrides AuditFilterOperations `hcl:"audit_filter_overrides"`
|
||||
|
||||
// wrapper to use for audit event crypto operations.
|
||||
wrapper wrapping.Wrapper
|
||||
}
|
||||
|
||||
// NewAuditConfig creates a new config starting with the DefaultAuditConfig()
|
||||
// and applying options. Supported options are: WithWrapper and
|
||||
// WithFilterOperations.
|
||||
func NewAuditConfig(opt ...Option) (*AuditConfig, error) {
|
||||
const op = "event.NewAuditConfig"
|
||||
opts := getOpts(opt...)
|
||||
c := DefaultAuditConfig()
|
||||
if opts.withAuditWrapper != nil {
|
||||
c.wrapper = opts.withAuditWrapper
|
||||
}
|
||||
if opts.withFilterOperations != nil {
|
||||
c.FilterOverrides = opts.withFilterOperations
|
||||
}
|
||||
if err := c.Validate(); err != nil {
|
||||
return nil, fmt.Errorf("%s: invalid configuration: %w", op, err)
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Validate the AuditConfig
|
||||
func (ac *AuditConfig) Validate() error {
|
||||
const op = "event.(AuditConfig).Validate"
|
||||
|
||||
// validate overrides first so all other checks can assert that they are
|
||||
// valid.
|
||||
if err := ac.FilterOverrides.Validate(); err != nil {
|
||||
return fmt.Errorf("%s: %w", op, err)
|
||||
}
|
||||
|
||||
if ac.wrapper == nil {
|
||||
for _, filterOperation := range ac.FilterOverrides {
|
||||
switch filterOperation {
|
||||
case EncryptOperation, HmacSha256Operation:
|
||||
return fmt.Errorf("%s: missing wrapper and %s filter operation requires a wrapper: %w", op, filterOperation, ErrInvalidParameter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultAuditConfig specifies a default AuditConfig. The default config will
|
||||
// redact both sensitive and secret classifications, so by default a wrapper is
|
||||
// not required.
|
||||
func DefaultAuditConfig() *AuditConfig {
|
||||
return &AuditConfig{
|
||||
FilterOverrides: DefaultAuditFilterOperations(),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package event
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDefaultAuditConfig(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
got := DefaultAuditConfig()
|
||||
want := &AuditConfig{
|
||||
FilterOverrides: DefaultAuditFilterOperations(),
|
||||
}
|
||||
assert.Equal(want, got)
|
||||
}
|
||||
|
||||
func TestAuditConfig_Validate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
ac *AuditConfig
|
||||
wantIsError error
|
||||
wantErrContains string
|
||||
}{
|
||||
{
|
||||
name: "invalid-classification-override",
|
||||
ac: &AuditConfig{
|
||||
FilterOverrides: AuditFilterOperations{
|
||||
"invalid-classification": RedactOperation,
|
||||
},
|
||||
},
|
||||
wantIsError: ErrInvalidParameter,
|
||||
wantErrContains: "invalid filter override classification (invalid-classification)",
|
||||
},
|
||||
{
|
||||
name: "invalid-operation-override",
|
||||
ac: &AuditConfig{
|
||||
FilterOverrides: AuditFilterOperations{
|
||||
SensitiveClassification: "invalid-operation",
|
||||
},
|
||||
},
|
||||
wantIsError: ErrInvalidParameter,
|
||||
wantErrContains: "invalid filter override operation (invalid-operation)",
|
||||
},
|
||||
{
|
||||
name: "missing-wrapper-with-hmac-filter",
|
||||
ac: &AuditConfig{
|
||||
FilterOverrides: AuditFilterOperations{
|
||||
SensitiveClassification: HmacSha256Operation,
|
||||
},
|
||||
},
|
||||
wantIsError: ErrInvalidParameter,
|
||||
wantErrContains: "hmac-sha256 filter operation requires a wrapper",
|
||||
},
|
||||
{
|
||||
name: "missing-wrapper-with-encrypt-filter",
|
||||
ac: &AuditConfig{
|
||||
FilterOverrides: AuditFilterOperations{
|
||||
SensitiveClassification: EncryptOperation,
|
||||
},
|
||||
},
|
||||
wantIsError: ErrInvalidParameter,
|
||||
wantErrContains: "encrypt filter operation requires a wrapper",
|
||||
},
|
||||
{
|
||||
name: "valid-default",
|
||||
ac: DefaultAuditConfig(),
|
||||
},
|
||||
{
|
||||
name: "valid-with-required-wrapper-for-encrypt",
|
||||
ac: &AuditConfig{
|
||||
wrapper: testWrapper(t),
|
||||
FilterOverrides: AuditFilterOperations{
|
||||
SensitiveClassification: EncryptOperation,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "valid-with-required-wrapper-for-hmac",
|
||||
ac: &AuditConfig{
|
||||
wrapper: testWrapper(t),
|
||||
FilterOverrides: AuditFilterOperations{
|
||||
SensitiveClassification: HmacSha256Operation,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
err := tt.ac.Validate()
|
||||
if tt.wantIsError != nil {
|
||||
require.Error(err)
|
||||
if tt.wantErrContains != "" {
|
||||
assert.Contains(err.Error(), tt.wantErrContains)
|
||||
}
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewAuditConfig(t *testing.T) {
|
||||
wrapper := testWrapper(t)
|
||||
filterOps := AuditFilterOperations{
|
||||
SensitiveClassification: EncryptOperation,
|
||||
SecretClassification: EncryptOperation,
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
opts []Option
|
||||
want *AuditConfig
|
||||
wantIsError error
|
||||
wantErrContains string
|
||||
}{
|
||||
{
|
||||
name: "missing-required-wrapper",
|
||||
opts: []Option{WithFilterOperations(filterOps)},
|
||||
wantIsError: ErrInvalidParameter,
|
||||
wantErrContains: "missing wrapper",
|
||||
},
|
||||
{
|
||||
name: "valid-default",
|
||||
want: DefaultAuditConfig(),
|
||||
},
|
||||
{
|
||||
name: "valid-with-all-opts",
|
||||
opts: []Option{WithAuditWrapper(wrapper), WithFilterOperations(filterOps)},
|
||||
want: &AuditConfig{
|
||||
FilterOverrides: filterOps,
|
||||
wrapper: wrapper,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
got, err := NewAuditConfig(tt.opts...)
|
||||
if tt.wantIsError != nil {
|
||||
require.Error(err)
|
||||
if tt.wantErrContains != "" {
|
||||
assert.Contains(err.Error(), tt.wantErrContains)
|
||||
}
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.Equal(tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -11,15 +11,12 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/wrappers"
|
||||
pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services"
|
||||
"github.com/hashicorp/boundary/internal/host/static"
|
||||
pbs "github.com/hashicorp/boundary/internal/gen/testing/event"
|
||||
"github.com/hashicorp/boundary/internal/observability/event"
|
||||
"github.com/hashicorp/boundary/internal/types/scope"
|
||||
pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hosts"
|
||||
"github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/scopes"
|
||||
"github.com/hashicorp/eventlogger/filters/encrypt"
|
||||
"github.com/hashicorp/eventlogger/formatter_filters/cloudevents"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/mitchellh/copystructure"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
@@ -584,7 +581,7 @@ func Test_DefaultEventerConfig(t *testing.T) {
|
||||
AuditEnabled: false,
|
||||
ObservationsEnabled: true,
|
||||
SysEventsEnabled: true,
|
||||
Sinks: []event.SinkConfig{event.DefaultSink()},
|
||||
Sinks: []*event.SinkConfig{event.DefaultSink()},
|
||||
}, event.DefaultEventerConfig())
|
||||
})
|
||||
}
|
||||
@@ -657,39 +654,46 @@ func Test_WriteAudit(t *testing.T) {
|
||||
ctx, err = event.NewRequestInfoContext(ctx, info)
|
||||
require.NoError(t, err)
|
||||
|
||||
testAuth := &event.Auth{}
|
||||
testReq := &event.Request{
|
||||
Operation: "POST",
|
||||
Endpoint: "/v1/hosts",
|
||||
Details: &pbs.CreateHostRequest{Item: &pb.Host{
|
||||
HostCatalogId: "hc_1234567890",
|
||||
Name: &wrappers.StringValue{Value: "name"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: "static",
|
||||
Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{
|
||||
"address": structpb.NewStringValue("123.456.789"),
|
||||
}},
|
||||
}},
|
||||
}
|
||||
testAuthorizedActions := []string{"no-op", "read", "update", "delete"}
|
||||
|
||||
testResp := &event.Response{
|
||||
StatusCode: 200,
|
||||
Details: &pbs.CreateHostResponse{
|
||||
Uri: fmt.Sprintf("hosts/%s_", static.HostPrefix),
|
||||
Item: &pb.Host{
|
||||
HostCatalogId: "hc_1234567890",
|
||||
Scope: &scopes.ScopeInfo{Id: "proj_1234567890", Type: scope.Project.String(), ParentScopeId: "org_1234567890"},
|
||||
Name: &wrappers.StringValue{Value: "name"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: "static",
|
||||
Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{
|
||||
"address": structpb.NewStringValue("123.456.789"),
|
||||
}},
|
||||
AuthorizedActions: testAuthorizedActions,
|
||||
testAuth := &event.Auth{
|
||||
AuthTokenId: "test_auth_token_id",
|
||||
UserEmail: "test_user_email",
|
||||
UserName: "test_user_name",
|
||||
UserInfo: &event.UserInfo{
|
||||
UserId: "test_user_id",
|
||||
AuthAccountId: "test_auth_account_id",
|
||||
},
|
||||
GrantsInfo: &event.GrantsInfo{
|
||||
Grants: []event.GrantsPair{
|
||||
{
|
||||
Grant: "test_grant",
|
||||
ScopeId: "test_grant_scope_id",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
testReq := &event.Request{
|
||||
Operation: "POST",
|
||||
Endpoint: "/v1/hosts",
|
||||
Details: &pbs.TestAuthenticateRequest{
|
||||
AuthMethodId: "test_1234567890",
|
||||
TokenType: "test-cookie",
|
||||
Command: "test-command",
|
||||
Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{
|
||||
"password": structpb.NewStringValue("fido"),
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
testResp := &event.Response{
|
||||
StatusCode: 200,
|
||||
Details: &pbs.TestAuthenticateResponse{
|
||||
Command: "test-command",
|
||||
Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{
|
||||
"token": structpb.NewStringValue("test-token"),
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
auditOpts [][]event.Option
|
||||
@@ -745,13 +749,40 @@ func Test_WriteAudit(t *testing.T) {
|
||||
ctx: context.Background(),
|
||||
auditOpts: [][]event.Option{
|
||||
{
|
||||
event.WithAuth(testAuth),
|
||||
event.WithRequest(testReq),
|
||||
event.WithAuth(
|
||||
func() *event.Auth {
|
||||
dup, err := copystructure.Copy(testAuth)
|
||||
require.NoError(t, err)
|
||||
return dup.(*event.Auth)
|
||||
}(),
|
||||
),
|
||||
event.WithRequest(
|
||||
func() *event.Request {
|
||||
dup, err := copystructure.Copy(testReq)
|
||||
require.NoError(t, err)
|
||||
return dup.(*event.Request)
|
||||
}(),
|
||||
),
|
||||
},
|
||||
},
|
||||
wantAudit: &testAudit{
|
||||
Auth: testAuth,
|
||||
Request: testReq,
|
||||
Auth: func() *event.Auth {
|
||||
dup, err := copystructure.Copy(testAuth)
|
||||
require.NoError(t, err)
|
||||
dup.(*event.Auth).UserEmail = encrypt.RedactedData
|
||||
dup.(*event.Auth).UserName = encrypt.RedactedData
|
||||
return dup.(*event.Auth)
|
||||
}(),
|
||||
Request: func() *event.Request {
|
||||
dup, err := copystructure.Copy(testReq)
|
||||
require.NoError(t, err)
|
||||
dup.(*event.Request).Details.(*pbs.TestAuthenticateRequest).Attributes = &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"password": structpb.NewStringValue(encrypt.RedactedData),
|
||||
},
|
||||
}
|
||||
return dup.(*event.Request)
|
||||
}(),
|
||||
},
|
||||
setup: func() error {
|
||||
return event.InitSysEventer(testLogger, testLock, "use-syseventer", event.WithEventerConfig(&c.EventerConfig))
|
||||
@@ -774,8 +805,23 @@ func Test_WriteAudit(t *testing.T) {
|
||||
},
|
||||
},
|
||||
wantAudit: &testAudit{
|
||||
Auth: testAuth,
|
||||
Request: testReq,
|
||||
Auth: func() *event.Auth {
|
||||
dup, err := copystructure.Copy(testAuth)
|
||||
require.NoError(t, err)
|
||||
dup.(*event.Auth).UserEmail = encrypt.RedactedData
|
||||
dup.(*event.Auth).UserName = encrypt.RedactedData
|
||||
return dup.(*event.Auth)
|
||||
}(),
|
||||
Request: func() *event.Request {
|
||||
dup, err := copystructure.Copy(testReq)
|
||||
require.NoError(t, err)
|
||||
dup.(*event.Request).Details.(*pbs.TestAuthenticateRequest).Attributes = &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"password": structpb.NewStringValue(encrypt.RedactedData),
|
||||
},
|
||||
}
|
||||
return dup.(*event.Request)
|
||||
}(),
|
||||
},
|
||||
setup: func() error {
|
||||
return event.InitSysEventer(testLogger, testLock, "use-syseventer", event.WithEventerConfig(&c.EventerConfig))
|
||||
@@ -796,10 +842,34 @@ func Test_WriteAudit(t *testing.T) {
|
||||
},
|
||||
},
|
||||
wantAudit: &testAudit{
|
||||
Id: "411",
|
||||
Auth: testAuth,
|
||||
Request: testReq,
|
||||
Response: testResp,
|
||||
Id: "411",
|
||||
Auth: func() *event.Auth {
|
||||
dup, err := copystructure.Copy(testAuth)
|
||||
require.NoError(t, err)
|
||||
dup.(*event.Auth).UserEmail = encrypt.RedactedData
|
||||
dup.(*event.Auth).UserName = encrypt.RedactedData
|
||||
return dup.(*event.Auth)
|
||||
}(),
|
||||
Request: func() *event.Request {
|
||||
dup, err := copystructure.Copy(testReq)
|
||||
require.NoError(t, err)
|
||||
dup.(*event.Request).Details.(*pbs.TestAuthenticateRequest).Attributes = &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"password": structpb.NewStringValue(encrypt.RedactedData),
|
||||
},
|
||||
}
|
||||
return dup.(*event.Request)
|
||||
}(),
|
||||
Response: func() *event.Response {
|
||||
dup, err := copystructure.Copy(testResp)
|
||||
require.NoError(t, err)
|
||||
dup.(*event.Response).Details.(*pbs.TestAuthenticateResponse).Attributes = &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"token": structpb.NewStringValue(encrypt.RedactedData),
|
||||
},
|
||||
}
|
||||
return dup.(*event.Response)
|
||||
}(),
|
||||
},
|
||||
auditSinkFileName: c.AllEvents.Name(),
|
||||
},
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package event
|
||||
|
||||
import "fmt"
|
||||
|
||||
// DataClassification defines a data classification (public, sensitive, secret, etc)
|
||||
type DataClassification string
|
||||
|
||||
const (
|
||||
UnknownClassification DataClassification = "unknown"
|
||||
|
||||
// PublicClassification declares a field as public data. No filter
|
||||
// operations are ever performed on public data.
|
||||
PublicClassification DataClassification = "public"
|
||||
|
||||
// SensitiveClassification declares a field as sensitive data. By default,
|
||||
// sensitive data is encrypted unless there are AuditConfig.FilterOverrides
|
||||
SensitiveClassification DataClassification = "sensitive"
|
||||
|
||||
// SecretClassification declares a field as secret data. By default,
|
||||
// secret data is redacted unless there are AuditConfig.FilterOverrides
|
||||
SecretClassification DataClassification = "secret"
|
||||
)
|
||||
|
||||
// Validate the DataClassification
|
||||
func (dc DataClassification) Validate() error {
|
||||
const op = "event.(DataClassification).Validate"
|
||||
switch dc {
|
||||
case PublicClassification, SensitiveClassification, SecretClassification:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("%s: invalid data classification '%s': %w", op, dc, ErrInvalidParameter)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package event
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDataClassification_Validate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
c DataClassification
|
||||
wantIsErr error
|
||||
wantErrContains string
|
||||
}{
|
||||
{name: "invalid........", c: "invalid", wantIsErr: ErrInvalidParameter, wantErrContains: "invalid data classification 'invalid'"},
|
||||
{name: "invalid-unknown", c: UnknownClassification, wantIsErr: ErrInvalidParameter, wantErrContains: "invalid data classification 'unknown'"},
|
||||
{name: "valid-sensitive", c: SensitiveClassification},
|
||||
{name: "valid-public...", c: PublicClassification},
|
||||
{name: "valid-secret...", c: SecretClassification},
|
||||
{name: "valid-unknown..", c: SecretClassification},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
err := tt.c.Validate()
|
||||
if tt.wantIsErr != nil {
|
||||
require.Error(err)
|
||||
assert.ErrorIs(err, tt.wantIsErr)
|
||||
if tt.wantErrContains != "" {
|
||||
assert.Contains(err.Error(), tt.wantErrContains)
|
||||
}
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -12,16 +12,16 @@ type (
|
||||
// RequestInfo defines the fields captured about a Boundary request.
|
||||
type RequestInfo struct {
|
||||
EventId string `json:"-"`
|
||||
Id string `json:"id,omitempty"`
|
||||
Method string `json:"method,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
PublicId string `json:"public_id,omitempty"`
|
||||
Id string `json:"id,omitempty" class:"public"`
|
||||
Method string `json:"method,omitempty" class:"public"`
|
||||
Path string `json:"path,omitempty" class:"public"`
|
||||
PublicId string `json:"public_id,omitempty" class:"public"`
|
||||
}
|
||||
|
||||
// UserInfo defines the fields captured about a user for a Boundary request.
|
||||
type UserInfo struct {
|
||||
UserId string `json:"id,omitempty"`
|
||||
AuthAccountId string `json:"auth_account_id,omitempty"`
|
||||
UserId string `json:"id,omitempty" class:"public"`
|
||||
AuthAccountId string `json:"auth_account_id,omitempty" class:"public"`
|
||||
}
|
||||
|
||||
type GrantsInfo struct {
|
||||
@@ -29,23 +29,22 @@ type GrantsInfo struct {
|
||||
}
|
||||
|
||||
type GrantsPair struct {
|
||||
Grant string `json:"grant,omitempty"`
|
||||
ScopeId string `json:"scope_id,omitempty"`
|
||||
Grant string `json:"grant,omitempty" class:"public"`
|
||||
ScopeId string `json:"scope_id,omitempty" class:"public"`
|
||||
}
|
||||
|
||||
type Auth struct {
|
||||
// AccessorId is a std audit field == auth_token public_id
|
||||
AccessorId string `json:"accessor_id"`
|
||||
UserInfo *UserInfo `json:"user_info,omitempty"` // boundary field
|
||||
GrantsInfo *GrantsInfo `json:"grants_info,omitempty"`
|
||||
UserEmail string `json:"email,omitempty"`
|
||||
UserName string `json:"name,omitempty"`
|
||||
AuthTokenId string `json:"auth_token_id" class:"public"`
|
||||
UserInfo *UserInfo `json:"user_info,omitempty"` // boundary field
|
||||
GrantsInfo *GrantsInfo `json:"grants_info,omitempty"`
|
||||
UserEmail string `json:"email,omitempty" class:"sensitive"`
|
||||
UserName string `json:"name,omitempty" class:"sensitive"`
|
||||
}
|
||||
|
||||
type Request struct {
|
||||
Operation string `json:"operation"` // std audit field
|
||||
Endpoint string `json:"endpoint"` // std audit field
|
||||
Details proto.Message `json:"details"` // boundary field
|
||||
Operation string `json:"operation,omitempty" class:"public"` // std audit field
|
||||
Endpoint string `json:"endpoint,omitempty" class:"public"` // std audit field
|
||||
Details proto.Message `json:"details,omitempty"` // boundary field
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/eventlogger"
|
||||
"github.com/hashicorp/eventlogger/filters/encrypt"
|
||||
"github.com/hashicorp/eventlogger/filters/gated"
|
||||
"github.com/hashicorp/eventlogger/formatter_filters/cloudevents"
|
||||
"github.com/hashicorp/eventlogger/sinks/writer"
|
||||
@@ -68,11 +69,12 @@ type Eventer struct {
|
||||
}
|
||||
|
||||
type pipeline struct {
|
||||
eventType Type
|
||||
fmtId eventlogger.NodeID
|
||||
sinkId eventlogger.NodeID
|
||||
gateId eventlogger.NodeID
|
||||
sinkConfig SinkConfig
|
||||
eventType Type
|
||||
fmtId eventlogger.NodeID
|
||||
sinkId eventlogger.NodeID
|
||||
gateId eventlogger.NodeID
|
||||
encryptFilterId eventlogger.NodeID
|
||||
sinkConfig *SinkConfig
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -136,7 +138,7 @@ func SysEventer() *Eventer {
|
||||
}
|
||||
|
||||
// NewEventer creates a new Eventer using the config. Supports options:
|
||||
// WithNow, WithSerializationLock, WithBroker
|
||||
// WithNow, WithSerializationLock, WithBroker, WithAuditWrapper
|
||||
func NewEventer(log hclog.Logger, serializationLock *sync.Mutex, serverName string, c EventerConfig, opt ...Option) (*Eventer, error) {
|
||||
const op = "event.NewEventer"
|
||||
if log == nil {
|
||||
@@ -192,7 +194,7 @@ func NewEventer(log hclog.Logger, serializationLock *sync.Mutex, serverName stri
|
||||
allSinkFilenames := map[string]bool{}
|
||||
|
||||
for _, s := range c.Sinks {
|
||||
fmtId, fmtNode, err := newFmtFilterNode(serverName, s)
|
||||
fmtId, fmtNode, err := newFmtFilterNode(serverName, *s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: %w", op, err)
|
||||
}
|
||||
@@ -259,11 +261,38 @@ func NewEventer(log hclog.Logger, serializationLock *sync.Mutex, serverName stri
|
||||
}
|
||||
}
|
||||
if addToAudit {
|
||||
var fop AuditFilterOperations
|
||||
if s.AuditConfig != nil {
|
||||
fop = s.AuditConfig.FilterOverrides
|
||||
}
|
||||
s.AuditConfig, err = NewAuditConfig(WithAuditWrapper(opts.withAuditWrapper), WithFilterOperations(fop))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: %w", op, err)
|
||||
}
|
||||
encryptFilter := &encrypt.Filter{
|
||||
Wrapper: opts.withAuditWrapper,
|
||||
}
|
||||
if len(s.AuditConfig.FilterOverrides) > 0 {
|
||||
overrides := encrypt.DefaultFilterOperations()
|
||||
for k, v := range s.AuditConfig.FilterOverrides {
|
||||
overrides[encrypt.DataClassification(k)] = encrypt.FilterOperation(v)
|
||||
}
|
||||
encryptFilter.FilterOperationOverrides = overrides
|
||||
}
|
||||
id, err := NewId("encrypt-audit")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: %w", op, err)
|
||||
}
|
||||
encryptFilterId := eventlogger.NodeID(id)
|
||||
if err := b.RegisterNode(encryptFilterId, encryptFilter); err != nil {
|
||||
return nil, fmt.Errorf("%s: %w", op, err)
|
||||
}
|
||||
auditPipelines = append(auditPipelines, pipeline{
|
||||
eventType: AuditType,
|
||||
fmtId: fmtId,
|
||||
sinkId: sinkId,
|
||||
sinkConfig: s,
|
||||
eventType: AuditType,
|
||||
fmtId: fmtId,
|
||||
sinkId: sinkId,
|
||||
encryptFilterId: encryptFilterId,
|
||||
sinkConfig: s,
|
||||
})
|
||||
}
|
||||
if addToObservation {
|
||||
@@ -322,7 +351,8 @@ func NewEventer(log hclog.Logger, serializationLock *sync.Mutex, serverName stri
|
||||
err = e.broker.RegisterPipeline(eventlogger.Pipeline{
|
||||
EventType: eventlogger.EventType(p.eventType),
|
||||
PipelineID: eventlogger.PipelineID(pipeId),
|
||||
NodeIDs: []eventlogger.NodeID{p.gateId, p.fmtId, p.sinkId},
|
||||
// order of nodes is important! gate (aggregate), then filter/format, then encrypt, then write to sink
|
||||
NodeIDs: []eventlogger.NodeID{p.gateId, p.encryptFilterId, p.fmtId, p.sinkId},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: failed to register audit pipeline: %w", op, err)
|
||||
@@ -352,7 +382,8 @@ func NewEventer(log hclog.Logger, serializationLock *sync.Mutex, serverName stri
|
||||
err = e.broker.RegisterPipeline(eventlogger.Pipeline{
|
||||
EventType: eventlogger.EventType(p.eventType),
|
||||
PipelineID: eventlogger.PipelineID(pipeId),
|
||||
NodeIDs: []eventlogger.NodeID{p.gateId, p.fmtId, p.sinkId},
|
||||
// order of nodes is important! gate (aggregate), then filter/format, then write to sink
|
||||
NodeIDs: []eventlogger.NodeID{p.gateId, p.fmtId, p.sinkId},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: failed to register observation pipeline: %w", op, err)
|
||||
@@ -368,7 +399,8 @@ func NewEventer(log hclog.Logger, serializationLock *sync.Mutex, serverName stri
|
||||
err = e.broker.RegisterPipeline(eventlogger.Pipeline{
|
||||
EventType: eventlogger.EventType(p.eventType),
|
||||
PipelineID: eventlogger.PipelineID(pipeId),
|
||||
NodeIDs: []eventlogger.NodeID{p.fmtId, p.sinkId},
|
||||
// order of nodes is important! filter/format, then write to sink
|
||||
NodeIDs: []eventlogger.NodeID{p.fmtId, p.sinkId},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: failed to register err pipeline: %w", op, err)
|
||||
@@ -384,7 +416,8 @@ func NewEventer(log hclog.Logger, serializationLock *sync.Mutex, serverName stri
|
||||
err = e.broker.RegisterPipeline(eventlogger.Pipeline{
|
||||
EventType: eventlogger.EventType(p.eventType),
|
||||
PipelineID: eventlogger.PipelineID(pipeId),
|
||||
NodeIDs: []eventlogger.NodeID{p.fmtId, p.sinkId},
|
||||
// order of nodes is important! filter/format, then write to sink
|
||||
NodeIDs: []eventlogger.NodeID{p.fmtId, p.sinkId},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: failed to register sys pipeline: %w", op, err)
|
||||
@@ -469,16 +502,17 @@ func DefaultEventerConfig() *EventerConfig {
|
||||
AuditEnabled: false,
|
||||
ObservationsEnabled: true,
|
||||
SysEventsEnabled: true,
|
||||
Sinks: []SinkConfig{DefaultSink()},
|
||||
Sinks: []*SinkConfig{DefaultSink()},
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultSink() SinkConfig {
|
||||
return SinkConfig{
|
||||
Name: "default",
|
||||
EventTypes: []Type{EveryType},
|
||||
Format: JSONSinkFormat,
|
||||
Type: StderrSink,
|
||||
func DefaultSink() *SinkConfig {
|
||||
return &SinkConfig{
|
||||
Name: "default",
|
||||
EventTypes: []Type{EveryType},
|
||||
Format: JSONSinkFormat,
|
||||
Type: StderrSink,
|
||||
AuditConfig: DefaultAuditConfig(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@ import (
|
||||
|
||||
// EventerConfig supplies all the configuration needed to create/config an Eventer.
|
||||
type EventerConfig struct {
|
||||
AuditEnabled bool `hcl:"audit_enabled"` // AuditEnabled specifies if audit events should be emitted.
|
||||
ObservationsEnabled bool `hcl:"observations_enabled"` // ObservationsEnabled specifies if observation events should be emitted.
|
||||
SysEventsEnabled bool `hcl:"sysevents_enabled"` // SysEventsEnabled specifies if sysevents should be emitted.
|
||||
Sinks []SinkConfig `hcl:"-"` // Sinks are all the configured sinks
|
||||
AuditEnabled bool `hcl:"audit_enabled"` // AuditEnabled specifies if audit events should be emitted.
|
||||
ObservationsEnabled bool `hcl:"observations_enabled"` // ObservationsEnabled specifies if observation events should be emitted.
|
||||
SysEventsEnabled bool `hcl:"sysevents_enabled"` // SysEventsEnabled specifies if sysevents should be emitted.
|
||||
Sinks []*SinkConfig `hcl:"-"` // Sinks are all the configured sinks
|
||||
}
|
||||
|
||||
// Validate will Validate the config. A config isn't required to have any
|
||||
|
||||
@@ -17,7 +17,7 @@ func TestEventerConfig_Validate(t *testing.T) {
|
||||
{
|
||||
name: "invalid-sink",
|
||||
c: EventerConfig{
|
||||
Sinks: []SinkConfig{
|
||||
Sinks: []*SinkConfig{
|
||||
{
|
||||
Type: "invalid",
|
||||
},
|
||||
|
||||
@@ -82,7 +82,7 @@ func Test_InitSysEventer(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "bad-config",
|
||||
opt: []Option{WithEventerConfig(&EventerConfig{Sinks: []SinkConfig{{Format: "bad-format"}}})},
|
||||
opt: []Option{WithEventerConfig(&EventerConfig{Sinks: []*SinkConfig{{Format: "bad-format"}}})},
|
||||
log: testLogger,
|
||||
lock: testLock,
|
||||
serverName: "success-with-config",
|
||||
@@ -108,12 +108,13 @@ func Test_InitSysEventer(t *testing.T) {
|
||||
want: &Eventer{
|
||||
logger: testLogger,
|
||||
conf: EventerConfig{
|
||||
Sinks: []SinkConfig{
|
||||
Sinks: []*SinkConfig{
|
||||
{
|
||||
Name: "default",
|
||||
EventTypes: []Type{EveryType},
|
||||
Format: JSONSinkFormat,
|
||||
Type: StderrSink,
|
||||
Name: "default",
|
||||
EventTypes: []Type{EveryType},
|
||||
Format: JSONSinkFormat,
|
||||
Type: StderrSink,
|
||||
AuditConfig: DefaultAuditConfig(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -362,19 +363,110 @@ func Test_NewEventer(t *testing.T) {
|
||||
Name: "test",
|
||||
})
|
||||
|
||||
twrapper := testWrapper(t)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
config EventerConfig
|
||||
opts []Option
|
||||
logger hclog.Logger
|
||||
lock *sync.Mutex
|
||||
serverName string
|
||||
want *Eventer
|
||||
wantRegistered []string
|
||||
wantPipelines []string
|
||||
wantThresholds map[eventlogger.EventType]int
|
||||
wantErrIs error
|
||||
name string
|
||||
config EventerConfig
|
||||
opts []Option
|
||||
logger hclog.Logger
|
||||
lock *sync.Mutex
|
||||
serverName string
|
||||
want *Eventer
|
||||
wantRegistered []string
|
||||
wantPipelines []string
|
||||
wantThresholds map[eventlogger.EventType]int
|
||||
wantErrIs error
|
||||
wantErrContains string
|
||||
}{
|
||||
{
|
||||
name: "missing-require-wrapper",
|
||||
config: func() EventerConfig {
|
||||
cfg := EventerConfig{
|
||||
AuditEnabled: true,
|
||||
Sinks: []*SinkConfig{
|
||||
{
|
||||
Name: "test",
|
||||
EventTypes: []Type{AuditType},
|
||||
Type: StderrSink,
|
||||
Format: JSONHclogSinkFormat,
|
||||
AuditConfig: &AuditConfig{
|
||||
FilterOverrides: AuditFilterOperations{
|
||||
SensitiveClassification: EncryptOperation,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
return cfg
|
||||
}(),
|
||||
lock: testLock,
|
||||
logger: testLogger,
|
||||
serverName: "missing-required-wrapper",
|
||||
wantErrIs: ErrInvalidParameter,
|
||||
wantErrContains: "missing wrapper and encrypt filter operation requires a wrapper",
|
||||
},
|
||||
{
|
||||
name: "valid-audit-config-with-wrapper",
|
||||
config: func() EventerConfig {
|
||||
cfg := EventerConfig{
|
||||
AuditEnabled: true,
|
||||
Sinks: []*SinkConfig{
|
||||
{
|
||||
Name: "test",
|
||||
EventTypes: []Type{AuditType},
|
||||
Type: StderrSink,
|
||||
Format: JSONSinkFormat,
|
||||
AuditConfig: &AuditConfig{
|
||||
FilterOverrides: AuditFilterOperations{
|
||||
SensitiveClassification: EncryptOperation,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
return cfg
|
||||
}(),
|
||||
opts: []Option{WithAuditWrapper(twrapper)},
|
||||
lock: testLock,
|
||||
logger: testLogger,
|
||||
serverName: "valid-audit-config-with-wrapper",
|
||||
want: &Eventer{
|
||||
logger: testLogger,
|
||||
conf: EventerConfig{
|
||||
AuditEnabled: true,
|
||||
Sinks: []*SinkConfig{
|
||||
{
|
||||
Name: "test",
|
||||
EventTypes: []Type{AuditType},
|
||||
Format: JSONSinkFormat,
|
||||
Type: StderrSink,
|
||||
AuditConfig: &AuditConfig{
|
||||
wrapper: twrapper,
|
||||
FilterOverrides: AuditFilterOperations{
|
||||
SensitiveClassification: EncryptOperation,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantRegistered: []string{
|
||||
"cloudevents", // fmt for everything
|
||||
"stderr", // stderr
|
||||
"gated-audit", // stderr
|
||||
"encrypt-audit", // stderr
|
||||
},
|
||||
wantPipelines: []string{
|
||||
"audit", // stderr
|
||||
},
|
||||
wantThresholds: map[eventlogger.EventType]int{
|
||||
"error": 0,
|
||||
"system": 0,
|
||||
"observation": 0,
|
||||
"audit": 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "missing-logger",
|
||||
config: testSetup.EventerConfig,
|
||||
@@ -401,7 +493,7 @@ func Test_NewEventer(t *testing.T) {
|
||||
config: func() EventerConfig {
|
||||
dupFileConfig := TestEventerConfig(t, "dup-sink-filename")
|
||||
dupFileConfig.EventerConfig.Sinks = append(dupFileConfig.EventerConfig.Sinks,
|
||||
SinkConfig{
|
||||
&SinkConfig{
|
||||
Name: "err-file-sink",
|
||||
Type: FileSink,
|
||||
EventTypes: []Type{ErrorType},
|
||||
@@ -428,12 +520,13 @@ func Test_NewEventer(t *testing.T) {
|
||||
want: &Eventer{
|
||||
logger: testLogger,
|
||||
conf: EventerConfig{
|
||||
Sinks: []SinkConfig{
|
||||
Sinks: []*SinkConfig{
|
||||
{
|
||||
Name: "default",
|
||||
EventTypes: []Type{EveryType},
|
||||
Format: JSONSinkFormat,
|
||||
Type: StderrSink,
|
||||
Name: "default",
|
||||
EventTypes: []Type{EveryType},
|
||||
Format: JSONSinkFormat,
|
||||
Type: StderrSink,
|
||||
AuditConfig: DefaultAuditConfig(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -443,6 +536,7 @@ func Test_NewEventer(t *testing.T) {
|
||||
"stderr", // stderr
|
||||
"gated-observation", // stderr
|
||||
"gated-audit", // stderr
|
||||
"encrypt-audit", // stderr
|
||||
},
|
||||
wantPipelines: []string{
|
||||
"audit", // stderr
|
||||
@@ -472,10 +566,12 @@ func Test_NewEventer(t *testing.T) {
|
||||
"stderr", // stderr
|
||||
"gated-observation", // stderr
|
||||
"gated-audit", // stderr
|
||||
"encrypt-audit", // stderr
|
||||
"cloudevents", // every-type-file-sync
|
||||
"tmp-all-events", // every-type-file-sync
|
||||
"gated-observation", // every-type-file-sync
|
||||
"gated-audit", // every-type-file-sync
|
||||
"encrypt-audit", // every-type-file-sync
|
||||
"cloudevents", // error-file-sink
|
||||
"tmp-errors", // error-file-sink
|
||||
},
|
||||
@@ -512,10 +608,12 @@ func Test_NewEventer(t *testing.T) {
|
||||
"stderr", // stderr
|
||||
"gated-observation", // stderr
|
||||
"gated-audit", // stderr
|
||||
"encrypt-audit", // stderr
|
||||
"cloudevents", // every-type-file-sync
|
||||
"tmp-all-events", // every-type-file-sync
|
||||
"gated-observation", // every-type-file-sync
|
||||
"gated-audit", // every-type-file-sync
|
||||
"encrypt-audit", // every-type-file-sync
|
||||
"cloudevents", // error-file-sink
|
||||
"tmp-errors", // error-file-sink
|
||||
"cloudevents", // observation-file-sink
|
||||
@@ -523,6 +621,7 @@ func Test_NewEventer(t *testing.T) {
|
||||
"tmp-observation", // observations-file-sink
|
||||
"cloudevents", // audit-file-sink
|
||||
"gated-audit", // audit-file-sink
|
||||
"encrypt-audit", // audit-file-sink
|
||||
"tmp-audit", // audit-file-sink
|
||||
"cloudevents", // sys-file-sink
|
||||
"tmp-sysevents", // sys-file-sink
|
||||
@@ -563,10 +662,12 @@ func Test_NewEventer(t *testing.T) {
|
||||
"stderr", // stderr
|
||||
"gated-observation", // stderr
|
||||
"gated-audit", // stderr
|
||||
"encrypt-audit", // stderr
|
||||
"hclog-text", // every-type-file-sync
|
||||
"tmp-all-events", // every-type-file-sync
|
||||
"gated-observation", // every-type-file-sync
|
||||
"gated-audit", // every-type-file-sync
|
||||
"encrypt-audit", // every-type-file-sync
|
||||
"hclog-text", // error-file-sink
|
||||
"tmp-errors", // error-file-sink
|
||||
},
|
||||
@@ -594,11 +695,18 @@ func Test_NewEventer(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
testBroker := &testMockBroker{}
|
||||
got, err := NewEventer(tt.logger, tt.lock, tt.serverName, tt.config, TestWithBroker(t, testBroker))
|
||||
opts := []Option{TestWithBroker(t, testBroker)}
|
||||
if tt.opts != nil {
|
||||
opts = append(opts, tt.opts...)
|
||||
}
|
||||
got, err := NewEventer(tt.logger, tt.lock, tt.serverName, tt.config, opts...)
|
||||
if tt.wantErrIs != nil {
|
||||
require.Error(err)
|
||||
require.Nil(got)
|
||||
assert.ErrorIs(err, tt.wantErrIs)
|
||||
if tt.wantErrContains != "" {
|
||||
assert.Contains(err.Error(), tt.wantErrContains)
|
||||
}
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package event
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// FilterOperation defines a filter operation (none, redact, encrypt, etc)
|
||||
type FilterOperation string
|
||||
|
||||
const (
|
||||
NoOperation FilterOperation = "" // NoOperation specifies no operation.
|
||||
UnknownOperation FilterOperation = "unknown" // UnknownOperation specifies an unknown operation.
|
||||
RedactOperation FilterOperation = "redact" // RedactOperation specifies an redaction operation
|
||||
EncryptOperation FilterOperation = "encrypt" // EncryptOperation specifies an encryption operation.
|
||||
HmacSha256Operation FilterOperation = "hmac-sha256" // HmacSha256Operation specifies an hmac-sha256 operation
|
||||
)
|
||||
|
||||
// Validate the FilterOperation
|
||||
func (fop FilterOperation) Validate() error {
|
||||
const op = "event.(DataClassification).Validate"
|
||||
switch fop {
|
||||
case RedactOperation, EncryptOperation, HmacSha256Operation, NoOperation:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("%s: invalid filter operation '%s': %w", op, fop, ErrInvalidParameter)
|
||||
}
|
||||
}
|
||||
|
||||
// AuditFilterOperation defines a map between DataClassifications and
|
||||
// FilterOperations for audit filtering
|
||||
type AuditFilterOperations map[DataClassification]FilterOperation
|
||||
|
||||
// Validate the AuditFilterOperation
|
||||
func (af AuditFilterOperations) Validate() error {
|
||||
const op = "event.(AuditFilterOperations).Validate"
|
||||
for k, v := range af {
|
||||
if err := k.Validate(); err != nil {
|
||||
return fmt.Errorf("%s: invalid filter override classification (%s): %w", op, k, err)
|
||||
}
|
||||
if err := v.Validate(); err != nil {
|
||||
return fmt.Errorf("%s: invalid filter override operation (%s): %w", op, v, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultAuditFilterOperations will return a map of the default
|
||||
// AuditConfig.AuditFilters
|
||||
func DefaultAuditFilterOperations() AuditFilterOperations {
|
||||
const op = "event.DefaultAuditFilterOperations"
|
||||
return AuditFilterOperations{
|
||||
SensitiveClassification: RedactOperation,
|
||||
SecretClassification: RedactOperation,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package event
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFilterOperation_Validate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
fop FilterOperation
|
||||
wantIsErr error
|
||||
wantErrContains string
|
||||
}{
|
||||
{name: "invalid........", fop: "invalid", wantIsErr: ErrInvalidParameter, wantErrContains: "invalid filter operation 'invalid'"},
|
||||
{name: "invalid-unknown", fop: UnknownOperation, wantIsErr: ErrInvalidParameter, wantErrContains: "invalid filter operation 'unknown'"},
|
||||
{name: "valid-sensitive", fop: RedactOperation},
|
||||
{name: "valid-public...", fop: EncryptOperation},
|
||||
{name: "valid-secret...", fop: HmacSha256Operation},
|
||||
{name: "valid-unknown..", fop: NoOperation},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
err := tt.fop.Validate()
|
||||
if tt.wantIsErr != nil {
|
||||
require.Error(err)
|
||||
assert.ErrorIs(err, tt.wantIsErr)
|
||||
if tt.wantErrContains != "" {
|
||||
assert.Contains(err.Error(), tt.wantErrContains)
|
||||
}
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultAuditFilterOperation(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
got := DefaultAuditFilterOperations()
|
||||
want := AuditFilterOperations{
|
||||
SecretClassification: RedactOperation,
|
||||
SensitiveClassification: RedactOperation,
|
||||
}
|
||||
assert.Equal(want, got)
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package event
|
||||
import (
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
wrapping "github.com/hashicorp/go-kms-wrapping"
|
||||
)
|
||||
|
||||
const msgField = "msg"
|
||||
@@ -23,21 +25,23 @@ type Option func(*options)
|
||||
|
||||
// options = how options are represented
|
||||
type options struct {
|
||||
withId string
|
||||
withDetails map[string]interface{}
|
||||
withHeader map[string]interface{}
|
||||
withFlush bool
|
||||
withInfo map[string]interface{}
|
||||
withRequestInfo *RequestInfo
|
||||
withNow time.Time
|
||||
withRequest *Request
|
||||
withResponse *Response
|
||||
withAuth *Auth
|
||||
withEventer *Eventer
|
||||
withEventerConfig *EventerConfig
|
||||
withAllow []string
|
||||
withDeny []string
|
||||
withSchema *url.URL
|
||||
withId string
|
||||
withDetails map[string]interface{}
|
||||
withHeader map[string]interface{}
|
||||
withFlush bool
|
||||
withInfo map[string]interface{}
|
||||
withRequestInfo *RequestInfo
|
||||
withNow time.Time
|
||||
withRequest *Request
|
||||
withResponse *Response
|
||||
withAuth *Auth
|
||||
withEventer *Eventer
|
||||
withEventerConfig *EventerConfig
|
||||
withAllow []string
|
||||
withDeny []string
|
||||
withSchema *url.URL
|
||||
withAuditWrapper wrapping.Wrapper
|
||||
withFilterOperations AuditFilterOperations
|
||||
|
||||
withBroker broker // test only option
|
||||
withAuditSink bool // test only option
|
||||
@@ -178,3 +182,17 @@ func WithDeny(f ...string) Option {
|
||||
o.withDeny = f
|
||||
}
|
||||
}
|
||||
|
||||
// WithAuditWrapper is an optional wrapper for audit events
|
||||
func WithAuditWrapper(w wrapping.Wrapper) Option {
|
||||
return func(o *options) {
|
||||
o.withAuditWrapper = w
|
||||
}
|
||||
}
|
||||
|
||||
// WithFilterOperations is an optional set of filter operations
|
||||
func WithFilterOperations(fop AuditFilterOperations) Option {
|
||||
return func(o *options) {
|
||||
o.withFilterOperations = fop
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
package event
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
wrapping "github.com/hashicorp/go-kms-wrapping"
|
||||
"github.com/hashicorp/go-kms-wrapping/wrappers/aead"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -150,4 +154,45 @@ func Test_GetOpts(t *testing.T) {
|
||||
testOpts.withSchema = schema
|
||||
assert.Equal(opts, testOpts)
|
||||
})
|
||||
t.Run("WithAuditWrapper", func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
w := testWrapper(t)
|
||||
opts := getOpts(WithAuditWrapper(w))
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withAuditWrapper = w
|
||||
assert.Equal(opts, testOpts)
|
||||
})
|
||||
t.Run("WithFilterOperations", func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
overrides := DefaultAuditFilterOperations()
|
||||
opts := getOpts(WithFilterOperations(overrides))
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withFilterOperations = overrides
|
||||
assert.Equal(opts, testOpts)
|
||||
})
|
||||
}
|
||||
|
||||
// testWrapper initializes an AEAD wrapping.Wrapper for testing. Note: this
|
||||
// code was cut/pasted from internal/db to eliminate a circular dependency with
|
||||
// the internal/errors pkg
|
||||
func testWrapper(t *testing.T) wrapping.Wrapper {
|
||||
rootKey := make([]byte, 32)
|
||||
n, err := rand.Read(rootKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if n != 32 {
|
||||
t.Fatal(n)
|
||||
}
|
||||
root := aead.NewWrapper(nil)
|
||||
_, err = root.SetConfig(map[string]string{
|
||||
"key_id": base64.StdEncoding.EncodeToString(rootKey),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := root.SetAESGCMKeyBytes(rootKey); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return root
|
||||
}
|
||||
@@ -17,6 +17,7 @@ type SinkConfig struct {
|
||||
Type SinkType `hcl:"type"` // Type defines the type of sink (StderrSink or FileSink).
|
||||
StderrConfig *StderrSinkTypeConfig `hcl:"stderr"` // StderrConfig defines parameters for a stderr output.
|
||||
FileConfig *FileSinkTypeConfig `hcl:"file"` // FileConfig defines parameters for a file output.
|
||||
AuditConfig *AuditConfig `hcl:"audit_config"` // AuditConfig defines optional parameters for audit events (if EventTypes contains audit)
|
||||
}
|
||||
|
||||
func (sc *SinkConfig) Validate() error {
|
||||
@@ -62,11 +63,22 @@ func (sc *SinkConfig) Validate() error {
|
||||
if len(sc.EventTypes) == 0 {
|
||||
return fmt.Errorf("%s: missing event types: %w", op, ErrInvalidParameter)
|
||||
}
|
||||
|
||||
for _, et := range sc.EventTypes {
|
||||
if err := et.Validate(); err != nil {
|
||||
return fmt.Errorf("%s: %w", op, err)
|
||||
}
|
||||
// well, if there's an event type of audit, we need to check the audit
|
||||
// config, if it's optionally provided. We are intentionally only
|
||||
// checking the FilterOverrides, because there's no way to specify the
|
||||
// wrapper in a config.
|
||||
if (et == AuditType || et == EveryType) && sc.AuditConfig != nil && sc.AuditConfig.FilterOverrides != nil {
|
||||
if err := sc.AuditConfig.FilterOverrides.Validate(); err != nil {
|
||||
return fmt.Errorf("%s: invalid audit config: %w", op, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,44 @@ func TestSinkConfig_Validate(t *testing.T) {
|
||||
wantErrIs error
|
||||
wantErrContains string
|
||||
}{
|
||||
{
|
||||
name: "invalid-everytype-audit-config",
|
||||
sc: SinkConfig{
|
||||
Name: "sink-name",
|
||||
EventTypes: []Type{EveryType},
|
||||
Type: FileSink,
|
||||
FileConfig: &FileSinkTypeConfig{
|
||||
FileName: "tmp.file",
|
||||
},
|
||||
Format: JSONSinkFormat,
|
||||
AuditConfig: &AuditConfig{
|
||||
FilterOverrides: AuditFilterOperations{
|
||||
SensitiveClassification: "invalid",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErrIs: ErrInvalidParameter,
|
||||
wantErrContains: "invalid audit config",
|
||||
},
|
||||
{
|
||||
name: "invalid-auditaudit-config",
|
||||
sc: SinkConfig{
|
||||
Name: "sink-name",
|
||||
EventTypes: []Type{AuditType},
|
||||
Type: FileSink,
|
||||
FileConfig: &FileSinkTypeConfig{
|
||||
FileName: "tmp.file",
|
||||
},
|
||||
Format: JSONSinkFormat,
|
||||
AuditConfig: &AuditConfig{
|
||||
FilterOverrides: AuditFilterOperations{
|
||||
"invalid": EncryptOperation,
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErrIs: ErrInvalidParameter,
|
||||
wantErrContains: "invalid audit config",
|
||||
},
|
||||
{
|
||||
name: "missing-name",
|
||||
sc: SinkConfig{
|
||||
@@ -195,3 +233,48 @@ func TestSinkConfig_Validate(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSinkFilter_Validate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
sf *SinkFilter
|
||||
wantErrIs error
|
||||
wantErrContains string
|
||||
}{
|
||||
{
|
||||
name: "invalid-type",
|
||||
sf: &SinkFilter{
|
||||
Type: "invalid",
|
||||
Filter: `"/Data" ==1`,
|
||||
},
|
||||
wantErrContains: "invalid filter type",
|
||||
},
|
||||
{
|
||||
name: "invalid-filter-bad-path",
|
||||
sf: &SinkFilter{
|
||||
Type: AllowFilter,
|
||||
Filter: `"data" == 1`,
|
||||
},
|
||||
wantErrContains: "invalid filter '\"data\" == 1'",
|
||||
},
|
||||
{
|
||||
name: "valid",
|
||||
sf: &SinkFilter{
|
||||
Type: DenyFilter,
|
||||
Filter: `"/Data" ==1`,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
err := tt.sf.Validate()
|
||||
if tt.wantErrContains != "" {
|
||||
require.Error(err)
|
||||
assert.Contains(err.Error(), tt.wantErrContains)
|
||||
return
|
||||
}
|
||||
assert.NoError(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ func TestEventerConfig(t *testing.T, testName string, opt ...Option) TestConfig
|
||||
EventerConfig: EventerConfig{
|
||||
ObservationsEnabled: true,
|
||||
AuditEnabled: true,
|
||||
Sinks: []SinkConfig{
|
||||
Sinks: []*SinkConfig{
|
||||
{
|
||||
Name: "every-type-file-sink",
|
||||
Type: FileSink,
|
||||
@@ -86,12 +86,14 @@ func TestEventerConfig(t *testing.T, testName string, opt ...Option) TestConfig
|
||||
Path: "./",
|
||||
FileName: tmpAllFile.Name(),
|
||||
},
|
||||
AuditConfig: DefaultAuditConfig(),
|
||||
},
|
||||
{
|
||||
Name: "stderr",
|
||||
Type: StderrSink,
|
||||
EventTypes: []Type{EveryType},
|
||||
Format: opts.withSinkFormat,
|
||||
Name: "stderr",
|
||||
Type: StderrSink,
|
||||
EventTypes: []Type{EveryType},
|
||||
Format: opts.withSinkFormat,
|
||||
AuditConfig: DefaultAuditConfig(),
|
||||
},
|
||||
{
|
||||
Name: "err-file-sink",
|
||||
@@ -114,7 +116,7 @@ func TestEventerConfig(t *testing.T, testName string, opt ...Option) TestConfig
|
||||
t.Cleanup(func() {
|
||||
os.Remove(tmpFile.Name())
|
||||
})
|
||||
c.EventerConfig.Sinks = append(c.EventerConfig.Sinks, SinkConfig{
|
||||
c.EventerConfig.Sinks = append(c.EventerConfig.Sinks, &SinkConfig{
|
||||
Name: "audit-file-sink",
|
||||
Type: FileSink,
|
||||
EventTypes: []Type{AuditType},
|
||||
@@ -123,6 +125,7 @@ func TestEventerConfig(t *testing.T, testName string, opt ...Option) TestConfig
|
||||
Path: "./",
|
||||
FileName: tmpFile.Name(),
|
||||
},
|
||||
AuditConfig: DefaultAuditConfig(),
|
||||
})
|
||||
c.AuditEvents = tmpFile
|
||||
}
|
||||
@@ -132,7 +135,7 @@ func TestEventerConfig(t *testing.T, testName string, opt ...Option) TestConfig
|
||||
t.Cleanup(func() {
|
||||
os.Remove(tmpFile.Name())
|
||||
})
|
||||
c.EventerConfig.Sinks = append(c.EventerConfig.Sinks, SinkConfig{
|
||||
c.EventerConfig.Sinks = append(c.EventerConfig.Sinks, &SinkConfig{
|
||||
Name: "err-observation-sink",
|
||||
Type: FileSink,
|
||||
EventTypes: []Type{ObservationType},
|
||||
@@ -150,7 +153,7 @@ func TestEventerConfig(t *testing.T, testName string, opt ...Option) TestConfig
|
||||
t.Cleanup(func() {
|
||||
os.Remove(tmpFile.Name())
|
||||
})
|
||||
c.EventerConfig.Sinks = append(c.EventerConfig.Sinks, SinkConfig{
|
||||
c.EventerConfig.Sinks = append(c.EventerConfig.Sinks, &SinkConfig{
|
||||
Name: "err-sysevents-sink",
|
||||
Type: FileSink,
|
||||
EventTypes: []Type{SystemType},
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package testing.event.v1;
|
||||
|
||||
option go_package = "github.com/hashicorp/boundary/internal/gen/testing/event;event";
|
||||
|
||||
import "google/protobuf/struct.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "google/api/annotations.proto";
|
||||
|
||||
service TestAuthMethodService {
|
||||
// TestAuthenticate validates credentials provided and returns an Auth Token.
|
||||
// Deprecated: use AuthenticateLogin instead.
|
||||
rpc TestAuthenticate(TestAuthenticateRequest) returns (TestAuthenticateResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/auth-methods/{auth_method_id}:authenticate"
|
||||
body: "*"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
summary: "Authenticate a user to an scope and retrieve an authentication token."
|
||||
};
|
||||
}
|
||||
}
|
||||
message TestAuthenticateRequest {
|
||||
// The ID of the Auth Method in the system that should be used for authentication.
|
||||
// @inject_tag: `class:"public"`
|
||||
string auth_method_id = 1 [json_name = "auth_method_id"];
|
||||
// This can be "cookie" or "token". If not provided, "token" will be used. "cookie" activates a split-cookie method where the token is split partially between http-only and regular cookies in order
|
||||
// to keep it safe from rogue JS in the browser.
|
||||
// @inject_tag: `class:"public"`
|
||||
string token_type = 2 [json_name = "token_type"];
|
||||
// Attributes are passed to the Auth Method; the valid keys and values depend on the type of Auth Method as well as the command.
|
||||
google.protobuf.Struct attributes = 4 [json_name = "attributes"];
|
||||
// The command to perform.
|
||||
// @inject_tag: `class:"public"`
|
||||
string command = 5 [json_name = "command"];
|
||||
}
|
||||
|
||||
message TestAuthenticateResponse {
|
||||
reserved 1, 2; // Old item and token_type
|
||||
reserved "item", "token_type";
|
||||
// Valid keys and values depend on the type of Auth Method as well as the command.
|
||||
google.protobuf.Struct attributes = 4 [json_name = "attributes"];
|
||||
// The command that was performed.
|
||||
// @inject_tag: `class:"public"`
|
||||
string command = 5 [json_name = "command"];
|
||||
}
|
||||
@@ -11,7 +11,7 @@ The stderr sink configures Boundary to send events to a stderr.
|
||||
|
||||
```hcl
|
||||
|
||||
sink "stderr" = {
|
||||
sink "stderr" {
|
||||
name = "all-events"
|
||||
description = "All events sent to stderr"
|
||||
event_types = ["*"]
|
||||
|
||||
Reference in new issue
Block a user