mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 19:27:32 +00:00

# Which Problems Are Solved Currently the username uniqueness is on instance level, we want to achieve a way to set it at organization level. # How the Problems Are Solved Addition of endpoints and a resource on organization level, where this setting can be managed. If nothing it set, the uniqueness is expected to be at instance level, where only users with instance permissions should be able to change this setting. # Additional Changes None # Additional Context Includes #10086 Closes #9964 --------- Co-authored-by: Marco A. <marco@zitadel.com>
1426 lines
31 KiB
Go
1426 lines
31 KiB
Go
package command
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"golang.org/x/text/language"
|
|
|
|
"github.com/zitadel/zitadel/internal/api/authz"
|
|
"github.com/zitadel/zitadel/internal/domain"
|
|
"github.com/zitadel/zitadel/internal/eventstore"
|
|
"github.com/zitadel/zitadel/internal/repository/org"
|
|
"github.com/zitadel/zitadel/internal/repository/user"
|
|
"github.com/zitadel/zitadel/internal/zerrors"
|
|
)
|
|
|
|
func TestCommandSide_LockUserV2(t *testing.T) {
|
|
userAgg := &user.NewAggregate("user1", "org1").Aggregate
|
|
type fields struct {
|
|
eventstore func(*testing.T) *eventstore.Eventstore
|
|
checkPermission domain.PermissionCheck
|
|
}
|
|
type (
|
|
args struct {
|
|
ctx context.Context
|
|
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-agz3eczifm", "Errors.User.UserIDMissing"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
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-450yxuqrh1", "Errors.User.NotFound"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "user already locked, precondition error",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewHumanAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewUserLockedEvent(context.Background(),
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
ctx: context.Background(),
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
err: func(err error) bool {
|
|
return errors.Is(err, zerrors.ThrowPreconditionFailed(nil, "COMMAND-lgws8wtsqf", "Errors.User.ShouldBeActiveOrInitial"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "user already locked, precondition error",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewMachineAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"name",
|
|
"description",
|
|
true,
|
|
domain.OIDCTokenTypeBearer,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewUserLockedEvent(context.Background(),
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
ctx: context.Background(),
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
err: func(err error) bool {
|
|
return errors.Is(err, zerrors.ThrowPreconditionFailed(nil, "COMMAND-lgws8wtsqf", "Errors.User.ShouldBeActiveOrInitial"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "lock user, ok",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewHumanAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
),
|
|
expectPush(
|
|
user.NewUserLockedEvent(context.Background(),
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
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(
|
|
user.NewHumanAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
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"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "lock user machine, ok",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewMachineAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"name",
|
|
"description",
|
|
true,
|
|
domain.OIDCTokenTypeBearer,
|
|
),
|
|
),
|
|
),
|
|
expectPush(
|
|
user.NewUserLockedEvent(context.Background(),
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
ctx: context.Background(),
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
want: &domain.ObjectDetails{
|
|
ResourceOwner: "org1",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
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.LockUserV2(tt.args.ctx, 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_UnlockUserV2(t *testing.T) {
|
|
userAgg := &user.NewAggregate("user1", "org1").Aggregate
|
|
type fields struct {
|
|
eventstore func(*testing.T) *eventstore.Eventstore
|
|
checkPermission domain.PermissionCheck
|
|
}
|
|
type (
|
|
args struct {
|
|
ctx context.Context
|
|
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-a9ld4xckax", "Errors.User.UserIDMissing"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
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-x377t913pw", "Errors.User.NotFound"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "user already active, precondition error",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewHumanAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
ctx: context.Background(),
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
err: func(err error) bool {
|
|
return errors.Is(err, zerrors.ThrowPreconditionFailed(nil, "COMMAND-olb9vb0oca", "Errors.User.NotLocked"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "user already active, precondition error",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
user.NewMachineAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"name",
|
|
"description",
|
|
true,
|
|
domain.OIDCTokenTypeBearer,
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
ctx: context.Background(),
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
err: func(err error) bool {
|
|
return errors.Is(err, zerrors.ThrowPreconditionFailed(nil, "COMMAND-olb9vb0oca", "Errors.User.NotLocked"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "unlock user, ok",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewHumanAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewUserLockedEvent(context.Background(),
|
|
userAgg),
|
|
),
|
|
),
|
|
expectPush(
|
|
user.NewUserUnlockedEvent(context.Background(),
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
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(
|
|
user.NewHumanAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewUserLockedEvent(context.Background(),
|
|
userAgg),
|
|
),
|
|
),
|
|
),
|
|
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"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "unlock user machine, ok",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewMachineAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"name",
|
|
"description",
|
|
true,
|
|
domain.OIDCTokenTypeBearer,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewUserLockedEvent(context.Background(),
|
|
userAgg),
|
|
),
|
|
),
|
|
expectPush(
|
|
user.NewUserUnlockedEvent(context.Background(),
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
ctx: context.Background(),
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
want: &domain.ObjectDetails{
|
|
ResourceOwner: "org1",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
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.UnlockUserV2(tt.args.ctx, 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_DeactivateUserV2(t *testing.T) {
|
|
userAgg := &user.NewAggregate("user1", "org1").Aggregate
|
|
type fields struct {
|
|
eventstore func(*testing.T) *eventstore.Eventstore
|
|
checkPermission domain.PermissionCheck
|
|
}
|
|
type (
|
|
args struct {
|
|
ctx context.Context
|
|
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-78iiirat8y", "Errors.User.UserIDMissing"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
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-5gp2p62iin", "Errors.User.NotFound"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "user initial, precondition error",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewHumanAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewHumanInitialCodeAddedEvent(context.Background(),
|
|
userAgg,
|
|
nil, time.Hour*1,
|
|
"",
|
|
),
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
ctx: context.Background(),
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
err: func(err error) bool {
|
|
return errors.Is(err, zerrors.ThrowPreconditionFailed(nil, "COMMAND-gvx4kct9r2", "Errors.User.CantDeactivateInitial"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "user already inactive, precondition error",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewHumanAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewUserDeactivatedEvent(context.Background(),
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
ctx: context.Background(),
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
err: func(err error) bool {
|
|
return errors.Is(err, zerrors.ThrowPreconditionFailed(nil, "COMMAND-5gunjw0cd7", "Errors.User.AlreadyInactive"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "deactivate user, ok",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewHumanAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewHumanInitializedCheckSucceededEvent(context.Background(),
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
expectPush(
|
|
user.NewUserDeactivatedEvent(context.Background(),
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
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(
|
|
user.NewHumanAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewHumanInitializedCheckSucceededEvent(context.Background(),
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
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"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "user machine already inactive, precondition error",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewMachineAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"name",
|
|
"description",
|
|
true,
|
|
domain.OIDCTokenTypeBearer,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewUserDeactivatedEvent(context.Background(),
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
ctx: context.Background(),
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
err: func(err error) bool {
|
|
return errors.Is(err, zerrors.ThrowPreconditionFailed(nil, "COMMAND-5gunjw0cd7", "Errors.User.AlreadyInactive"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "deactivate user machine, ok",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewMachineAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"name",
|
|
"description",
|
|
true,
|
|
domain.OIDCTokenTypeBearer,
|
|
),
|
|
),
|
|
),
|
|
expectPush(
|
|
user.NewUserDeactivatedEvent(context.Background(),
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
ctx: context.Background(),
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
want: &domain.ObjectDetails{
|
|
ResourceOwner: "org1",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
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.DeactivateUserV2(tt.args.ctx, 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_ReactivateUserV2(t *testing.T) {
|
|
userAgg := &user.NewAggregate("user1", "org1").Aggregate
|
|
type fields struct {
|
|
eventstore func(*testing.T) *eventstore.Eventstore
|
|
checkPermission domain.PermissionCheck
|
|
}
|
|
type (
|
|
args struct {
|
|
ctx context.Context
|
|
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-0nx1ie38fw", "Errors.User.UserIDMissing"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
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-9hy5kzbuk6", "Errors.User.NotFound"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "user already active, precondition error",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewHumanAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
ctx: context.Background(),
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
err: func(err error) bool {
|
|
return errors.Is(err, zerrors.ThrowPreconditionFailed(nil, "COMMAND-s5qqcz97hf", "Errors.User.NotInactive"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "user machine already active, precondition error",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewMachineAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"name",
|
|
"description",
|
|
true,
|
|
domain.OIDCTokenTypeBearer,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
ctx: context.Background(),
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
err: func(err error) bool {
|
|
return errors.Is(err, zerrors.ThrowPreconditionFailed(nil, "COMMAND-s5qqcz97hf", "Errors.User.NotInactive"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "reactivate user, ok",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewHumanAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewUserDeactivatedEvent(context.Background(),
|
|
userAgg),
|
|
),
|
|
),
|
|
expectPush(
|
|
user.NewUserReactivatedEvent(context.Background(),
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
ctx: context.Background(),
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
want: &domain.ObjectDetails{
|
|
ResourceOwner: "org1",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "reactivate user, no permission",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewHumanAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewUserDeactivatedEvent(context.Background(),
|
|
userAgg),
|
|
),
|
|
),
|
|
),
|
|
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"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "reactivate user machine, ok",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewMachineAddedEvent(context.Background(),
|
|
userAgg,
|
|
"username",
|
|
"name",
|
|
"description",
|
|
true,
|
|
domain.OIDCTokenTypeBearer,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewUserDeactivatedEvent(context.Background(),
|
|
userAgg),
|
|
),
|
|
),
|
|
expectPush(
|
|
user.NewUserReactivatedEvent(context.Background(),
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
ctx: context.Background(),
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
want: &domain.ObjectDetails{
|
|
ResourceOwner: "org1",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
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.ReactivateUserV2(tt.args.ctx, 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_RemoveUserV2(t *testing.T) {
|
|
ctxUserID := "ctxUserID"
|
|
ctx := authz.SetCtxData(context.Background(), authz.CtxData{UserID: ctxUserID})
|
|
userAgg := &user.NewAggregate("user1", "org1").Aggregate
|
|
orgAgg := &org.NewAggregate("org1").Aggregate
|
|
type fields struct {
|
|
eventstore func(*testing.T) *eventstore.Eventstore
|
|
checkPermission domain.PermissionCheck
|
|
}
|
|
type (
|
|
args struct {
|
|
userID string
|
|
cascadingMemberships []*CascadingMembership
|
|
grantIDs []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{
|
|
userID: "",
|
|
},
|
|
res: res{
|
|
err: func(err error) bool {
|
|
return errors.Is(err, zerrors.ThrowInvalidArgument(nil, "COMMAND-vaipl7s13l", "Errors.User.UserIDMissing"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "user not existing, not found error",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
err: func(err error) bool {
|
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-bd4ir1mblj", "Errors.User.NotFound"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "user removed, notfound error",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewHumanAddedEvent(ctx,
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewUserRemovedEvent(ctx,
|
|
userAgg,
|
|
"username",
|
|
nil,
|
|
true,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
err: func(err error) bool {
|
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-bd4ir1mblj", "Errors.User.NotFound"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "remove user, ok",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewHumanAddedEvent(ctx,
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
),
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
org.NewDomainPolicyAddedEvent(context.Background(),
|
|
orgAgg,
|
|
true,
|
|
true,
|
|
true,
|
|
),
|
|
),
|
|
),
|
|
expectFilterOrganizationSettings("org1", false, false),
|
|
expectPush(
|
|
user.NewUserRemovedEvent(ctx,
|
|
userAgg,
|
|
"username",
|
|
nil,
|
|
true,
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
want: &domain.ObjectDetails{
|
|
ResourceOwner: "org1",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "remove user, no permission",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewHumanAddedEvent(ctx,
|
|
userAgg,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewHumanInitializedCheckSucceededEvent(ctx,
|
|
userAgg,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckNotAllowed(),
|
|
},
|
|
args: args{
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
err: zerrors.IsPermissionDenied,
|
|
},
|
|
},
|
|
{
|
|
name: "user machine already removed, notfound error",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewMachineAddedEvent(ctx,
|
|
userAgg,
|
|
"username",
|
|
"name",
|
|
"description",
|
|
true,
|
|
domain.OIDCTokenTypeBearer,
|
|
),
|
|
),
|
|
eventFromEventPusher(
|
|
user.NewUserRemovedEvent(ctx,
|
|
userAgg,
|
|
"username",
|
|
nil,
|
|
true,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
},
|
|
args: args{
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
err: func(err error) bool {
|
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-bd4ir1mblj", "Errors.User.NotFound"))
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "remove user machine, ok",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewMachineAddedEvent(ctx,
|
|
userAgg,
|
|
"username",
|
|
"name",
|
|
"description",
|
|
true,
|
|
domain.OIDCTokenTypeBearer,
|
|
),
|
|
),
|
|
),
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
org.NewDomainPolicyAddedEvent(context.Background(),
|
|
orgAgg,
|
|
true,
|
|
true,
|
|
true,
|
|
),
|
|
),
|
|
),
|
|
expectFilterOrganizationSettings("org1", false, false),
|
|
expectPush(
|
|
user.NewUserRemovedEvent(ctx,
|
|
userAgg,
|
|
"username",
|
|
nil,
|
|
true,
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckAllowed(),
|
|
},
|
|
args: args{
|
|
userID: "user1",
|
|
},
|
|
res: res{
|
|
want: &domain.ObjectDetails{
|
|
ResourceOwner: "org1",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "remove self, ok",
|
|
fields: fields{
|
|
eventstore: expectEventstore(
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
user.NewHumanAddedEvent(ctx,
|
|
&user.NewAggregate(ctxUserID, "org1").Aggregate,
|
|
"username",
|
|
"firstname",
|
|
"lastname",
|
|
"nickname",
|
|
"displayname",
|
|
language.German,
|
|
domain.GenderUnspecified,
|
|
"email@test.ch",
|
|
true,
|
|
),
|
|
),
|
|
),
|
|
expectFilter(
|
|
eventFromEventPusher(
|
|
org.NewDomainPolicyAddedEvent(ctx,
|
|
orgAgg,
|
|
true,
|
|
true,
|
|
true,
|
|
),
|
|
),
|
|
),
|
|
expectFilterOrganizationSettings("org1", false, false),
|
|
expectPush(
|
|
user.NewUserRemovedEvent(ctx,
|
|
&user.NewAggregate(ctxUserID, "org1").Aggregate,
|
|
"username",
|
|
nil,
|
|
true,
|
|
),
|
|
),
|
|
),
|
|
checkPermission: newMockPermissionCheckNotAllowed(),
|
|
},
|
|
args: args{
|
|
userID: ctxUserID,
|
|
},
|
|
res: res{
|
|
want: &domain.ObjectDetails{
|
|
ResourceOwner: "org1",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
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.RemoveUserV2(ctx, tt.args.userID, "", tt.args.cascadingMemberships, tt.args.grantIDs...)
|
|
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)
|
|
}
|
|
})
|
|
}
|
|
}
|