package command import ( "context" "encoding/json" "errors" "testing" "github.com/stretchr/testify/assert" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/repository/user/schemauser" "github.com/zitadel/zitadel/internal/zerrors" ) func TestCommandSide_LockSchemaUser(t *testing.T) { type fields struct { eventstore func(*testing.T) *eventstore.Eventstore checkPermission domain.PermissionCheck } type ( args struct { ctx context.Context orgID string userID string } ) type res struct { want *domain.ObjectDetails err func(error) bool } tests := []struct { name string fields fields args args res res }{ { name: "userid missing, invalid argument error", fields: fields{ eventstore: expectEventstore(), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowInvalidArgument(nil, "COMMAND-Eu8I2VAfjF", "Errors.IDMissing")) }, }, }, { name: "user not existing, not found error", fields: fields{ eventstore: expectEventstore( expectFilter(), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound")) }, }, }, { name: "user removed, not found error", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), eventFromEventPusher( schemauser.NewDeletedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, ), ), ), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound")) }, }, }, { name: "user locked, precondition error", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), eventFromEventPusher( schemauser.NewLockedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, ), ), ), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-G4LOrnjY7q", "Errors.User.NotFound")) }, }, }, { name: "lock user, ok", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), ), expectPush( schemauser.NewLockedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, ), ), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ want: &domain.ObjectDetails{ ResourceOwner: "org1", }, }, }, { name: "lock user, no permission", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), ), ), checkPermission: newMockPermissionCheckNotAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowPermissionDenied(nil, "AUTHZ-HKJD33", "Errors.PermissionDenied")) }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { r := &Commands{ eventstore: tt.fields.eventstore(t), checkPermission: tt.fields.checkPermission, } got, err := r.LockSchemaUser(tt.args.ctx, tt.args.orgID, tt.args.userID) if tt.res.err == nil { assert.NoError(t, err) } if tt.res.err != nil && !tt.res.err(err) { t.Errorf("got wrong err: %v ", err) } if tt.res.err == nil { assertObjectDetails(t, tt.res.want, got) } }) } } func TestCommandSide_UnlockSchemaUser(t *testing.T) { type fields struct { eventstore func(*testing.T) *eventstore.Eventstore checkPermission domain.PermissionCheck } type ( args struct { ctx context.Context orgID string userID string } ) type res struct { want *domain.ObjectDetails err func(error) bool } tests := []struct { name string fields fields args args res res }{ { name: "userid missing, invalid argument error", fields: fields{ eventstore: expectEventstore(), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowInvalidArgument(nil, "COMMAND-krXtYscQZh", "Errors.IDMissing")) }, }, }, { name: "user not existing, not found error", fields: fields{ eventstore: expectEventstore( expectFilter(), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound")) }, }, }, { name: "user removed, not found error", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), eventFromEventPusher( schemauser.NewDeletedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, ), ), ), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound")) }, }, }, { name: "user not locked, precondition error", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), ), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowPreconditionFailed(nil, "COMMAND-gpBv46Lh9m", "Errors.User.NotLocked")) }, }, }, { name: "unlock user, ok", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), eventFromEventPusher( schemauser.NewLockedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, ), ), ), expectPush( schemauser.NewUnlockedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, ), ), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ want: &domain.ObjectDetails{ ResourceOwner: "org1", }, }, }, { name: "unlock user, no permission", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), eventFromEventPusher( schemauser.NewLockedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, ), ), ), ), checkPermission: newMockPermissionCheckNotAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowPermissionDenied(nil, "AUTHZ-HKJD33", "Errors.PermissionDenied")) }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { r := &Commands{ eventstore: tt.fields.eventstore(t), checkPermission: tt.fields.checkPermission, } got, err := r.UnlockSchemaUser(tt.args.ctx, tt.args.orgID, tt.args.userID) if tt.res.err == nil { assert.NoError(t, err) } if tt.res.err != nil && !tt.res.err(err) { t.Errorf("got wrong err: %v ", err) } if tt.res.err == nil { assertObjectDetails(t, tt.res.want, got) } }) } } func TestCommandSide_DeactivateSchemaUser(t *testing.T) { type fields struct { eventstore func(*testing.T) *eventstore.Eventstore checkPermission domain.PermissionCheck } type ( args struct { ctx context.Context orgID string userID string } ) type res struct { want *domain.ObjectDetails err func(error) bool } tests := []struct { name string fields fields args args res res }{ { name: "userid missing, invalid argument error", fields: fields{ eventstore: expectEventstore(), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowInvalidArgument(nil, "COMMAND-pjJhge86ZV", "Errors.IDMissing")) }, }, }, { name: "user not existing, not found error", fields: fields{ eventstore: expectEventstore( expectFilter(), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound")) }, }, }, { name: "user removed, not found error", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), eventFromEventPusher( schemauser.NewDeletedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, ), ), ), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound")) }, }, }, { name: "user not active, precondition error", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), eventFromEventPusher( schemauser.NewDeactivatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, ), ), ), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-Ob6lR5iFTe", "Errors.User.NotFound")) }, }, }, { name: "deactivate user, ok", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), ), expectPush( schemauser.NewDeactivatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, ), ), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ want: &domain.ObjectDetails{ ResourceOwner: "org1", }, }, }, { name: "deactivate user, no permission", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), ), ), checkPermission: newMockPermissionCheckNotAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowPermissionDenied(nil, "AUTHZ-HKJD33", "Errors.PermissionDenied")) }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { r := &Commands{ eventstore: tt.fields.eventstore(t), checkPermission: tt.fields.checkPermission, } got, err := r.DeactivateSchemaUser(tt.args.ctx, tt.args.orgID, tt.args.userID) if tt.res.err == nil { assert.NoError(t, err) } if tt.res.err != nil && !tt.res.err(err) { t.Errorf("got wrong err: %v ", err) } if tt.res.err == nil { assertObjectDetails(t, tt.res.want, got) } }) } } func TestCommandSide_ReactivateSchemaUser(t *testing.T) { type fields struct { eventstore func(*testing.T) *eventstore.Eventstore checkPermission domain.PermissionCheck } type ( args struct { ctx context.Context orgID string userID string } ) type res struct { want *domain.ObjectDetails err func(error) bool } tests := []struct { name string fields fields args args res res }{ { name: "userid missing, invalid argument error", fields: fields{ eventstore: expectEventstore(), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowInvalidArgument(nil, "COMMAND-17XupGvxBJ", "Errors.IDMissing")) }, }, }, { name: "user not existing, not found error", fields: fields{ eventstore: expectEventstore( expectFilter(), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound")) }, }, }, { name: "user removed, not found error", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), eventFromEventPusher( schemauser.NewDeletedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, ), ), ), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound")) }, }, }, { name: "user not inactive, precondition error", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), ), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowPreconditionFailed(nil, "COMMAND-rQjbBr4J3j", "Errors.User.NotInactive")) }, }, }, { name: "activate user, ok", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), eventFromEventPusher( schemauser.NewDeactivatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, ), ), ), expectPush( schemauser.NewActivatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, ), ), ), checkPermission: newMockPermissionCheckAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ want: &domain.ObjectDetails{ ResourceOwner: "org1", }, }, }, { name: "activate user, no permission", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( schemauser.NewCreatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, "schema", 1, json.RawMessage(`{ "name": "user" }`), ), ), eventFromEventPusher( schemauser.NewDeactivatedEvent(context.Background(), &schemauser.NewAggregate("user1", "org1").Aggregate, ), ), ), ), checkPermission: newMockPermissionCheckNotAllowed(), }, args: args{ ctx: context.Background(), userID: "user1", }, res: res{ err: func(err error) bool { return errors.Is(err, zerrors.ThrowPermissionDenied(nil, "AUTHZ-HKJD33", "Errors.PermissionDenied")) }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { r := &Commands{ eventstore: tt.fields.eventstore(t), checkPermission: tt.fields.checkPermission, } got, err := r.ActivateSchemaUser(tt.args.ctx, tt.args.orgID, tt.args.userID) if tt.res.err == nil { assert.NoError(t, err) } if tt.res.err != nil && !tt.res.err(err) { t.Errorf("got wrong err: %v ", err) } if tt.res.err == nil { assertObjectDetails(t, tt.res.want, got) } }) } }