perf: user grant owner removed (#6962)

* fix: change logic for usergrants projection with no selects

* fix: change logic for usergrants projection with one select

* fix: move resource owner select to single function

* fix: move resource owner select to single function

* fix: changes after merge

* fix: changes after merge

---------

Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
This commit is contained in:
Stefan Benz
2024-01-08 16:26:30 +01:00
committed by GitHub
parent e9cb1b90aa
commit e769b163ef
22 changed files with 488 additions and 210 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"testing"
"github.com/stretchr/testify/require"
"golang.org/x/text/language"
"github.com/zitadel/zitadel/internal/database"
@@ -57,16 +58,15 @@ func TestUserGrantProjection_reduces(t *testing.T) {
"email1",
true,
),
}).appendFilterResponse([]eventstore.Event{
project.NewProjectAddedEvent(context.Background(),
&project.NewAggregate("project-id", "org2").Aggregate,
"project",
false,
false,
false,
domain.PrivateLabelingSettingUnspecified,
),
}),
project.NewProjectAddedEvent(context.Background(),
&project.NewAggregate("project-id", "org2").Aggregate,
"project",
false,
false,
false,
domain.PrivateLabelingSettingUnspecified,
),
}),
}).reduceAdded,
want: wantReduce{
aggregateType: usergrant.AggregateType,
@@ -74,7 +74,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.user_grants3 (id, resource_owner, instance_id, creation_date, change_date, sequence, user_id, resource_owner_user, project_id, resource_owner_project, grant_id, granted_org, roles, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)",
expectedStmt: "INSERT INTO projections.user_grants4 (id, resource_owner, instance_id, creation_date, change_date, sequence, user_id, resource_owner_user, project_id, resource_owner_project, grant_id, granted_org, roles, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)",
expectedArgs: []interface{}{
"agg-id",
"ro-id",
@@ -126,14 +126,13 @@ func TestUserGrantProjection_reduces(t *testing.T) {
"email1",
true,
),
}).appendFilterResponse([]eventstore.Event{
project.NewGrantAddedEvent(context.Background(),
&project.NewAggregate("project-id", "org2").Aggregate,
"grant-id",
"org3",
[]string{},
),
}),
project.NewGrantAddedEvent(context.Background(),
&project.NewAggregate("project-id", "org2").Aggregate,
"grant-id",
"org3",
[]string{},
),
}),
}).reduceAdded,
want: wantReduce{
aggregateType: usergrant.AggregateType,
@@ -141,7 +140,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.user_grants3 (id, resource_owner, instance_id, creation_date, change_date, sequence, user_id, resource_owner_user, project_id, resource_owner_project, grant_id, granted_org, roles, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)",
expectedStmt: "INSERT INTO projections.user_grants4 (id, resource_owner, instance_id, creation_date, change_date, sequence, user_id, resource_owner_user, project_id, resource_owner_project, grant_id, granted_org, roles, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)",
expectedArgs: []interface{}{
"agg-id",
"ro-id",
@@ -182,7 +181,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_grants3 SET (change_date, roles, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.user_grants4 SET (change_date, roles, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
database.TextArray[string]{"role"},
@@ -214,7 +213,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_grants3 SET (change_date, roles, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.user_grants4 SET (change_date, roles, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
database.TextArray[string]{"role"},
@@ -244,7 +243,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.user_grants4 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
anyArg{},
"instance-id",
@@ -271,7 +270,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.user_grants4 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -297,7 +296,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.user_grants4 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
anyArg{},
"instance-id",
@@ -324,7 +323,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_grants3 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.user_grants4 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
domain.UserGrantStateInactive,
@@ -354,7 +353,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_grants3 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.user_grants4 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
domain.UserGrantStateActive,
@@ -384,7 +383,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (user_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.user_grants4 WHERE (user_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
anyArg{},
"instance-id",
@@ -411,7 +410,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (project_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.user_grants4 WHERE (project_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
anyArg{},
"instance-id",
@@ -438,7 +437,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (grant_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.user_grants4 WHERE (grant_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"grantID",
"instance-id",
@@ -465,7 +464,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_grants3 SET roles = array_remove(roles, $1) WHERE (project_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.user_grants4 SET roles = array_remove(roles, $1) WHERE (project_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"key",
"agg-id",
@@ -493,7 +492,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_grants3 SET (roles) = (SELECT ARRAY( SELECT UNNEST(roles) INTERSECT SELECT UNNEST ($1::TEXT[]))) WHERE (grant_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.user_grants4 SET (roles) = (SELECT ARRAY( SELECT UNNEST(roles) INTERSECT SELECT UNNEST ($1::TEXT[]))) WHERE (grant_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
database.TextArray[string]{"key"},
"grantID",
@@ -521,28 +520,28 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (instance_id = $1) AND (resource_owner = $2)",
expectedStmt: "DELETE FROM projections.user_grants4 WHERE (instance_id = $1) AND (resource_owner = $2)",
expectedArgs: []interface{}{
"instance-id",
"agg-id",
},
},
{
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (instance_id = $1) AND (resource_owner_user = $2)",
expectedStmt: "DELETE FROM projections.user_grants4 WHERE (instance_id = $1) AND (resource_owner_user = $2)",
expectedArgs: []interface{}{
"instance-id",
"agg-id",
},
},
{
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (instance_id = $1) AND (resource_owner_project = $2)",
expectedStmt: "DELETE FROM projections.user_grants4 WHERE (instance_id = $1) AND (resource_owner_project = $2)",
expectedArgs: []interface{}{
"instance-id",
"agg-id",
},
},
{
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (instance_id = $1) AND (granted_org = $2)",
expectedStmt: "DELETE FROM projections.user_grants4 WHERE (instance_id = $1) AND (granted_org = $2)",
expectedArgs: []interface{}{
"instance-id",
"agg-id",
@@ -567,3 +566,285 @@ func TestUserGrantProjection_reduces(t *testing.T) {
})
}
}
func Test_getResourceOwners(t *testing.T) {
type args struct {
instanceID string
userID string
projectID string
grantID string
}
type fields struct {
eventstore *eventstore.Eventstore
}
type want struct {
userRO string
projectRO string
grantedOrg string
wantErr bool
}
tests := []struct {
name string
fields fields
args args
want want
}{
{
name: "user RO, filter error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilterError(zerrors.ThrowNotFound(nil, "error", "error")),
),
},
args: args{
instanceID: "instance",
userID: "user",
},
want: want{
wantErr: true,
},
},
{
name: "user RO",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user", "org").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
),
),
),
},
args: args{
instanceID: "instance",
userID: "user",
},
want: want{
userRO: "org",
wantErr: false,
},
},
{
name: "user RO, no user",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
),
},
args: args{
instanceID: "instance",
userID: "user",
},
want: want{
wantErr: true,
},
},
{
name: "user and project RO",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user", "org").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
),
eventFromEventPusher(
project.NewProjectAddedEvent(context.Background(),
&project.NewAggregate("project", "org").Aggregate,
"project",
false,
false,
false,
domain.PrivateLabelingSettingUnspecified,
),
),
),
),
},
args: args{
instanceID: "instance",
userID: "user",
projectID: "project",
},
want: want{
userRO: "org",
projectRO: "org",
wantErr: false,
},
},
{
name: "user and project RO, no project",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user", "org").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
),
),
),
},
args: args{
instanceID: "instance",
userID: "user",
projectID: "project",
},
want: want{
wantErr: true,
},
},
{
name: "user and grant RO",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user", "org").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
),
eventFromEventPusher(
project.NewGrantAddedEvent(context.Background(),
&project.NewAggregate("project", "org").Aggregate,
"projectgrant1",
"grantedorg1",
[]string{"key1"},
),
),
),
),
},
args: args{
instanceID: "instance",
userID: "user",
projectID: "project",
grantID: "projectgrant1",
},
want: want{
userRO: "org",
grantedOrg: "grantedorg1",
wantErr: false,
},
},
{
name: "user and grant RO, no grant",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user", "org").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
),
),
),
},
args: args{
instanceID: "instance",
userID: "user",
projectID: "project",
grantID: "projectgrant1",
},
want: want{
wantErr: true,
},
},
{
name: "user and grant RO, no user",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
project.NewGrantAddedEvent(context.Background(),
&project.NewAggregate("project", "org").Aggregate,
"projectgrant1",
"grantedorg1",
[]string{"key1"},
),
),
),
),
},
args: args{
instanceID: "instance",
userID: "user",
projectID: "project",
grantID: "projectgrant1",
},
want: want{
wantErr: true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
userRO, projectRO, grantedOrg, err := getResourceOwners(context.Background(), tt.fields.eventstore, tt.args.instanceID, tt.args.userID, tt.args.projectID, tt.args.grantID)
if tt.want.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
require.Equal(t, tt.want.userRO, userRO)
require.Equal(t, tt.want.projectRO, projectRO)
require.Equal(t, tt.want.grantedOrg, grantedOrg)
}
})
}
}