mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-10 16:03:41 +00:00
fix: clean up writemodels user v3
This commit is contained in:
parent
7ce0ebd07f
commit
4efe7d1786
@ -3,8 +3,6 @@ package user
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/muhlemmer/gu"
|
|
||||||
|
|
||||||
resource_object "github.com/zitadel/zitadel/internal/api/grpc/resources/object/v3alpha"
|
resource_object "github.com/zitadel/zitadel/internal/api/grpc/resources/object/v3alpha"
|
||||||
"github.com/zitadel/zitadel/internal/command"
|
"github.com/zitadel/zitadel/internal/command"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
@ -61,7 +59,7 @@ func (s *Server) RequestPasswordReset(ctx context.Context, req *user.RequestPass
|
|||||||
}
|
}
|
||||||
return &user.RequestPasswordResetResponse{
|
return &user.RequestPasswordResetResponse{
|
||||||
Details: resource_object.DomainToDetailsPb(details, object.OwnerType_OWNER_TYPE_ORG, details.ResourceOwner),
|
Details: resource_object.DomainToDetailsPb(details, object.OwnerType_OWNER_TYPE_ORG, details.ResourceOwner),
|
||||||
VerificationCode: gu.Ptr(schemauser.PlainCode),
|
VerificationCode: schemauser.PlainCode,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ func (c *Commands) CreateSchemaUser(ctx context.Context, user *CreateSchemaUser)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
events, codeEmail, codePhone, err := writeModel.NewCreated(ctx,
|
events, codeEmail, codePhone, err := writeModel.NewCreate(ctx,
|
||||||
schemaWriteModel,
|
schemaWriteModel,
|
||||||
user.Data,
|
user.Data,
|
||||||
user.Email,
|
user.Email,
|
||||||
@ -151,10 +151,8 @@ func (c *Commands) ChangeSchemaUser(ctx context.Context, user *ChangeSchemaUser)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !writeModel.Exists() {
|
|
||||||
return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-Nn8CRVlkeZ", "Errors.User.NotFound")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// use already used schemaID, if no new schemaID is defined
|
||||||
schemaID := writeModel.SchemaID
|
schemaID := writeModel.SchemaID
|
||||||
if user.SchemaUser != nil && user.SchemaUser.SchemaID != "" {
|
if user.SchemaUser != nil && user.SchemaUser.SchemaID != "" {
|
||||||
schemaID = user.SchemaUser.SchemaID
|
schemaID = user.SchemaUser.SchemaID
|
||||||
@ -205,7 +203,7 @@ func existingSchema(ctx context.Context, c *Commands, resourceOwner, id string)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !writeModel.Exists() {
|
if !writeModel.Exists() {
|
||||||
return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-VLDTtxT3If", "Errors.UserSchema.NotExists")
|
return nil, zerrors.ThrowNotFound(nil, "COMMAND-VLDTtxT3If", "Errors.UserSchema.NotExists")
|
||||||
}
|
}
|
||||||
return writeModel, nil
|
return writeModel, nil
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ func TestCommands_ChangeSchemaUserEmail(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-nJ0TQFuRmP", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -416,7 +416,7 @@ func TestCommands_VerifySchemaUserEmail(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-qbGyMPvjvj", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -749,7 +749,7 @@ func TestCommands_ResendSchemaUserEmailCode(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-EajeF6ypOV", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -215,7 +215,7 @@ func (wm *UserV3WriteModel) Query() *eventstore.SearchQueryBuilder {
|
|||||||
EventTypes(eventtypes...).Builder()
|
EventTypes(eventtypes...).Builder()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *UserV3WriteModel) NewCreated(
|
func (wm *UserV3WriteModel) NewCreate(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
schemaWM *UserSchemaWriteModel,
|
schemaWM *UserSchemaWriteModel,
|
||||||
data json.RawMessage,
|
data json.RawMessage,
|
||||||
@ -223,11 +223,11 @@ func (wm *UserV3WriteModel) NewCreated(
|
|||||||
phone *Phone,
|
phone *Phone,
|
||||||
code func(context.Context) (*EncryptedCode, error),
|
code func(context.Context) (*EncryptedCode, error),
|
||||||
) (_ []eventstore.Command, codeEmail string, codePhone string, err error) {
|
) (_ []eventstore.Command, codeEmail string, codePhone string, err error) {
|
||||||
if err := wm.checkPermissionWrite(ctx, wm.ResourceOwner, wm.AggregateID); err != nil {
|
if err := wm.checkPermissionWrite(ctx); err != nil {
|
||||||
return nil, "", "", err
|
return nil, "", "", err
|
||||||
}
|
}
|
||||||
if wm.Exists() {
|
if err := wm.NotExists(); err != nil {
|
||||||
return nil, "", "", zerrors.ThrowPreconditionFailed(nil, "COMMAND-Nn8CRVlkeZ", "Errors.User.AlreadyExists")
|
return nil, "", "", err
|
||||||
}
|
}
|
||||||
schemaID, schemaRevision, err := wm.validateData(ctx, data, schemaWM)
|
schemaID, schemaRevision, err := wm.validateData(ctx, data, schemaWM)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -315,11 +315,11 @@ func (wm *UserV3WriteModel) NewUpdate(
|
|||||||
phone *Phone,
|
phone *Phone,
|
||||||
code func(context.Context) (*EncryptedCode, error),
|
code func(context.Context) (*EncryptedCode, error),
|
||||||
) (_ []eventstore.Command, codeEmail string, codePhone string, err error) {
|
) (_ []eventstore.Command, codeEmail string, codePhone string, err error) {
|
||||||
if err := wm.checkPermissionWrite(ctx, wm.ResourceOwner, wm.AggregateID); err != nil {
|
if err := wm.checkPermissionWrite(ctx); err != nil {
|
||||||
return nil, "", "", err
|
return nil, "", "", err
|
||||||
}
|
}
|
||||||
if !wm.Exists() {
|
if err := wm.Exists(); err != nil {
|
||||||
return nil, "", "", zerrors.ThrowPreconditionFailed(nil, "COMMAND-Nn8CRVlkeZ", "Errors.User.NotFound")
|
return nil, "", "", err
|
||||||
}
|
}
|
||||||
events := make([]eventstore.Command, 0)
|
events := make([]eventstore.Command, 0)
|
||||||
if user != nil {
|
if user != nil {
|
||||||
@ -390,14 +390,13 @@ func (wm *UserV3WriteModel) newUpdatedEvents(
|
|||||||
func (wm *UserV3WriteModel) NewDelete(
|
func (wm *UserV3WriteModel) NewDelete(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
) (_ []eventstore.Command, err error) {
|
) (_ []eventstore.Command, err error) {
|
||||||
if !wm.Exists() {
|
if err := wm.Exists(); err != nil {
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound")
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := wm.checkPermissionDelete(ctx, wm.ResourceOwner, wm.AggregateID); err != nil {
|
if err := wm.checkPermissionDelete(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return []eventstore.Command{schemauser.NewDeletedEvent(ctx, UserV3AggregateFromWriteModel(&wm.WriteModel))}, nil
|
return []eventstore.Command{schemauser.NewDeletedEvent(ctx, UserV3AggregateFromWriteModel(&wm.WriteModel))}, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func UserV3AggregateFromWriteModel(wm *eventstore.WriteModel) *eventstore.Aggregate {
|
func UserV3AggregateFromWriteModel(wm *eventstore.WriteModel) *eventstore.Aggregate {
|
||||||
@ -410,37 +409,43 @@ func UserV3AggregateFromWriteModel(wm *eventstore.WriteModel) *eventstore.Aggreg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *UserV3WriteModel) Exists() bool {
|
func (wm *UserV3WriteModel) NotExists() error {
|
||||||
return wm.State != domain.UserStateDeleted && wm.State != domain.UserStateUnspecified
|
if err := wm.Exists(); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return zerrors.ThrowPreconditionFailed(nil, "COMMAND-Nn8CRVlkeZ", "Errors.User.AlreadyExists")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *UserV3WriteModel) checkPermissionWrite(
|
func (wm *UserV3WriteModel) Exists() error {
|
||||||
ctx context.Context,
|
if wm.State != domain.UserStateDeleted && wm.State != domain.UserStateUnspecified {
|
||||||
resourceOwner string,
|
return nil
|
||||||
userID string,
|
}
|
||||||
) error {
|
return zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *UserV3WriteModel) checkPermissionWrite(ctx context.Context) error {
|
||||||
if wm.writePermissionCheck {
|
if wm.writePermissionCheck {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if userID != "" && userID == authz.GetCtxData(ctx).UserID {
|
if wm.AggregateID == authz.GetCtxData(ctx).UserID {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if err := wm.checkPermission(ctx, domain.PermissionUserWrite, resourceOwner, userID); err != nil {
|
if err := wm.checkPermission(ctx, domain.PermissionUserWrite, wm.ResourceOwner, wm.AggregateID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
wm.writePermissionCheck = true
|
wm.writePermissionCheck = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *UserV3WriteModel) checkPermissionDelete(
|
func (wm *UserV3WriteModel) checkPermissionDelete(ctx context.Context) error {
|
||||||
ctx context.Context,
|
if wm.AggregateID == authz.GetCtxData(ctx).UserID {
|
||||||
resourceOwner string,
|
|
||||||
userID string,
|
|
||||||
) error {
|
|
||||||
if userID != "" && userID == authz.GetCtxData(ctx).UserID {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return wm.checkPermission(ctx, domain.PermissionUserDelete, resourceOwner, userID)
|
return wm.checkPermission(ctx, domain.PermissionUserDelete, wm.ResourceOwner, wm.AggregateID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *UserV3WriteModel) checkPermissionStateChange(ctx context.Context) error {
|
||||||
|
return wm.checkPermission(ctx, domain.PermissionUserWrite, wm.ResourceOwner, wm.AggregateID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *UserV3WriteModel) NewEmailCreate(
|
func (wm *UserV3WriteModel) NewEmailCreate(
|
||||||
@ -448,7 +453,7 @@ func (wm *UserV3WriteModel) NewEmailCreate(
|
|||||||
email *Email,
|
email *Email,
|
||||||
code func(context.Context) (*EncryptedCode, error),
|
code func(context.Context) (*EncryptedCode, error),
|
||||||
) (_ []eventstore.Command, plainCode string, err error) {
|
) (_ []eventstore.Command, plainCode string, err error) {
|
||||||
if err := wm.checkPermissionWrite(ctx, wm.ResourceOwner, wm.AggregateID); err != nil {
|
if err := wm.checkPermissionWrite(ctx); err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
if email == nil || wm.Email == string(email.Address) {
|
if email == nil || wm.Email == string(email.Address) {
|
||||||
@ -483,8 +488,8 @@ func (wm *UserV3WriteModel) NewEmailUpdate(
|
|||||||
if !wm.EmailWM {
|
if !wm.EmailWM {
|
||||||
return nil, "", nil
|
return nil, "", nil
|
||||||
}
|
}
|
||||||
if !wm.Exists() {
|
if err := wm.Exists(); err != nil {
|
||||||
return nil, "", zerrors.ThrowNotFound(nil, "COMMAND-nJ0TQFuRmP", "Errors.User.NotFound")
|
return nil, "", err
|
||||||
}
|
}
|
||||||
return wm.NewEmailCreate(ctx, email, code)
|
return wm.NewEmailCreate(ctx, email, code)
|
||||||
}
|
}
|
||||||
@ -496,10 +501,10 @@ func (wm *UserV3WriteModel) NewEmailVerify(
|
|||||||
if !wm.EmailWM {
|
if !wm.EmailWM {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
if !wm.Exists() {
|
if err := wm.Exists(); err != nil {
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-qbGyMPvjvj", "Errors.User.NotFound")
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := wm.checkPermissionWrite(ctx, wm.ResourceOwner, wm.AggregateID); err != nil {
|
if err := wm.checkPermissionWrite(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if wm.EmailCode == nil {
|
if wm.EmailCode == nil {
|
||||||
@ -526,10 +531,10 @@ func (wm *UserV3WriteModel) NewResendEmailCode(
|
|||||||
if !wm.EmailWM {
|
if !wm.EmailWM {
|
||||||
return nil, "", nil
|
return nil, "", nil
|
||||||
}
|
}
|
||||||
if !wm.Exists() {
|
if err := wm.Exists(); err != nil {
|
||||||
return nil, "", zerrors.ThrowNotFound(nil, "COMMAND-EajeF6ypOV", "Errors.User.NotFound")
|
return nil, "", err
|
||||||
}
|
}
|
||||||
if err := wm.checkPermissionWrite(ctx, wm.ResourceOwner, wm.AggregateID); err != nil {
|
if err := wm.checkPermissionWrite(ctx); err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
if wm.EmailCode == nil {
|
if wm.EmailCode == nil {
|
||||||
@ -569,7 +574,7 @@ func (wm *UserV3WriteModel) NewPhoneCreate(
|
|||||||
phone *Phone,
|
phone *Phone,
|
||||||
code func(context.Context) (*EncryptedCode, error),
|
code func(context.Context) (*EncryptedCode, error),
|
||||||
) (_ []eventstore.Command, plainCode string, err error) {
|
) (_ []eventstore.Command, plainCode string, err error) {
|
||||||
if err := wm.checkPermissionWrite(ctx, wm.ResourceOwner, wm.AggregateID); err != nil {
|
if err := wm.checkPermissionWrite(ctx); err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
if phone == nil || wm.Phone == string(phone.Number) {
|
if phone == nil || wm.Phone == string(phone.Number) {
|
||||||
@ -604,8 +609,8 @@ func (wm *UserV3WriteModel) NewPhoneUpdate(
|
|||||||
if !wm.PhoneWM {
|
if !wm.PhoneWM {
|
||||||
return nil, "", nil
|
return nil, "", nil
|
||||||
}
|
}
|
||||||
if !wm.Exists() {
|
if err := wm.Exists(); err != nil {
|
||||||
return nil, "", zerrors.ThrowNotFound(nil, "COMMAND-b33QAVgel6", "Errors.User.NotFound")
|
return nil, "", err
|
||||||
}
|
}
|
||||||
return wm.NewPhoneCreate(ctx, phone, code)
|
return wm.NewPhoneCreate(ctx, phone, code)
|
||||||
}
|
}
|
||||||
@ -617,10 +622,10 @@ func (wm *UserV3WriteModel) NewPhoneVerify(
|
|||||||
if !wm.PhoneWM {
|
if !wm.PhoneWM {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
if !wm.Exists() {
|
if err := wm.Exists(); err != nil {
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-bx2OLtgGNS", "Errors.User.NotFound")
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := wm.checkPermissionWrite(ctx, wm.ResourceOwner, wm.AggregateID); err != nil {
|
if err := wm.checkPermissionWrite(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if wm.PhoneCode == nil {
|
if wm.PhoneCode == nil {
|
||||||
@ -646,10 +651,10 @@ func (wm *UserV3WriteModel) NewResendPhoneCode(
|
|||||||
if !wm.PhoneWM {
|
if !wm.PhoneWM {
|
||||||
return nil, "", nil
|
return nil, "", nil
|
||||||
}
|
}
|
||||||
if !wm.Exists() {
|
if err := wm.Exists(); err != nil {
|
||||||
return nil, "", zerrors.ThrowNotFound(nil, "COMMAND-z8Bu9vuL9s", "Errors.User.NotFound")
|
return nil, "", err
|
||||||
}
|
}
|
||||||
if err := wm.checkPermissionWrite(ctx, wm.ResourceOwner, wm.AggregateID); err != nil {
|
if err := wm.checkPermissionWrite(ctx); err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
if wm.PhoneCode == nil {
|
if wm.PhoneCode == nil {
|
||||||
@ -681,3 +686,59 @@ func (wm *UserV3WriteModel) newPhoneCodeAddedEvent(
|
|||||||
isReturnCode,
|
isReturnCode,
|
||||||
), plainCode, nil
|
), plainCode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (wm *UserV3WriteModel) NewLock(ctx context.Context) (_ []eventstore.Command, err error) {
|
||||||
|
if err := wm.Exists(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// can only be locked when not already locked
|
||||||
|
if wm.Locked {
|
||||||
|
return nil, zerrors.ThrowNotFound(nil, "COMMAND-G4LOrnjY7q", "Errors.User.NotFound")
|
||||||
|
}
|
||||||
|
if err := wm.checkPermissionStateChange(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []eventstore.Command{schemauser.NewLockedEvent(ctx, UserV3AggregateFromWriteModel(&wm.WriteModel))}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *UserV3WriteModel) NewUnlock(ctx context.Context) (_ []eventstore.Command, err error) {
|
||||||
|
if err := wm.Exists(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// can only be unlocked when locked
|
||||||
|
if !wm.Locked {
|
||||||
|
return nil, zerrors.ThrowNotFound(nil, "COMMAND-gpBv46Lh9m", "Errors.User.NotFound")
|
||||||
|
}
|
||||||
|
if err := wm.checkPermissionStateChange(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []eventstore.Command{schemauser.NewUnlockedEvent(ctx, UserV3AggregateFromWriteModel(&wm.WriteModel))}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *UserV3WriteModel) NewDeactivate(ctx context.Context) (_ []eventstore.Command, err error) {
|
||||||
|
if err := wm.Exists(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// can only be deactivated when active
|
||||||
|
if wm.State != domain.UserStateActive {
|
||||||
|
return nil, zerrors.ThrowNotFound(nil, "COMMAND-Ob6lR5iFTe", "Errors.User.NotFound")
|
||||||
|
}
|
||||||
|
if err := wm.checkPermissionStateChange(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []eventstore.Command{schemauser.NewDeactivatedEvent(ctx, UserV3AggregateFromWriteModel(&wm.WriteModel))}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *UserV3WriteModel) NewActivate(ctx context.Context) (_ []eventstore.Command, err error) {
|
||||||
|
if err := wm.Exists(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// can only be activated when inactive
|
||||||
|
if wm.State != domain.UserStateInactive {
|
||||||
|
return nil, zerrors.ThrowNotFound(nil, "COMMAND-rQjbBr4J3j", "Errors.User.NotFound")
|
||||||
|
}
|
||||||
|
if err := wm.checkPermissionStateChange(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []eventstore.Command{schemauser.NewActivatedEvent(ctx, UserV3AggregateFromWriteModel(&wm.WriteModel))}, nil
|
||||||
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/repository/user/authenticator"
|
|
||||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
||||||
"github.com/zitadel/zitadel/internal/zerrors"
|
"github.com/zitadel/zitadel/internal/zerrors"
|
||||||
)
|
)
|
||||||
@ -46,6 +45,7 @@ func (c *Commands) SetSchemaUserPassword(ctx context.Context, user *SetSchemaUse
|
|||||||
}
|
}
|
||||||
|
|
||||||
schemaUser := &schemaUserPassword{
|
schemaUser := &schemaUserPassword{
|
||||||
|
Create: true,
|
||||||
ResourceOwner: user.ResourceOwner,
|
ResourceOwner: user.ResourceOwner,
|
||||||
UserID: user.UserID,
|
UserID: user.UserID,
|
||||||
VerificationCode: user.VerificationCode,
|
VerificationCode: user.VerificationCode,
|
||||||
@ -54,27 +54,15 @@ func (c *Commands) SetSchemaUserPassword(ctx context.Context, user *SetSchemaUse
|
|||||||
EncodedPasswordHash: user.EncodedPasswordHash,
|
EncodedPasswordHash: user.EncodedPasswordHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
existing, err := c.getSchemaUserPasswordWithVerification(ctx, schemaUser)
|
writeModel, err := c.getSchemaUserPasswordWithVerification(ctx, schemaUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resourceOwner := existing.ResourceOwner
|
|
||||||
// when no password was set yet
|
|
||||||
if existing.EncodedHash == "" {
|
|
||||||
existingUser, err := c.getSchemaUserWMForState(ctx, user.ResourceOwner, user.UserID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !existingUser.Exists() {
|
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-TODO", "Errors.User.Password.NotFound")
|
|
||||||
}
|
|
||||||
resourceOwner = existingUser.ResourceOwner
|
|
||||||
}
|
|
||||||
|
|
||||||
// If password is provided, let's check if is compliant with the policy.
|
// If password is provided, let's check if is compliant with the policy.
|
||||||
// If only a encodedPassword is passed, we can skip this.
|
// If only a encodedPassword is passed, we can skip this.
|
||||||
if user.Password != "" {
|
if user.Password != "" {
|
||||||
if err = c.checkPasswordComplexity(ctx, user.Password, resourceOwner); err != nil {
|
if err = c.checkPasswordComplexity(ctx, user.Password, writeModel.ResourceOwner); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,18 +75,14 @@ func (c *Commands) SetSchemaUserPassword(ctx context.Context, user *SetSchemaUse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
events, err := c.eventstore.Push(ctx,
|
events, err := writeModel.NewCreate(ctx,
|
||||||
authenticator.NewPasswordCreatedEvent(ctx,
|
|
||||||
&authenticator.NewAggregate(user.UserID, resourceOwner).Aggregate,
|
|
||||||
existing.UserID,
|
|
||||||
encodedPassword,
|
encodedPassword,
|
||||||
user.ChangeRequired,
|
user.ChangeRequired,
|
||||||
),
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return pushedEventsToObjectDetails(events), nil
|
return c.pushAppendAndReduceDetails(ctx, writeModel, events...)
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestSchemaUserPasswordReset struct {
|
type RequestSchemaUserPasswordReset struct {
|
||||||
@ -107,64 +91,48 @@ type RequestSchemaUserPasswordReset struct {
|
|||||||
|
|
||||||
URLTemplate string
|
URLTemplate string
|
||||||
NotificationType domain.NotificationType
|
NotificationType domain.NotificationType
|
||||||
PlainCode string
|
PlainCode *string
|
||||||
ReturnCode bool
|
ReturnCode bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) RequestSchemaUserPasswordReset(ctx context.Context, user *RequestSchemaUserPasswordReset) (_ *domain.ObjectDetails, err error) {
|
func (c *Commands) RequestSchemaUserPasswordReset(ctx context.Context, user *RequestSchemaUserPasswordReset) (_ *domain.ObjectDetails, err error) {
|
||||||
existing, err := c.getSchemaUserPasswordExists(ctx, user.ResourceOwner, user.UserID)
|
writeModel, err := existsSchemaUserPasswordWithPermission(ctx, c, user.ResourceOwner, user.UserID)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if existing.EncodedHash == "" {
|
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-TODO", "Errors.User.Password.NotFound")
|
|
||||||
}
|
|
||||||
|
|
||||||
code, err := c.newEncryptedCode(ctx, c.eventstore.Filter, domain.SecretGeneratorTypePasswordResetCode, c.userEncryption) //nolint:staticcheck
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
events, err := c.eventstore.Push(ctx,
|
events, plainCode, err := writeModel.NewAddCode(ctx,
|
||||||
authenticator.NewPasswordCodeAddedEvent(ctx,
|
|
||||||
&authenticator.NewAggregate(existing.UserID, existing.ResourceOwner).Aggregate,
|
|
||||||
code.Crypted,
|
|
||||||
code.Expiry,
|
|
||||||
user.NotificationType,
|
user.NotificationType,
|
||||||
user.URLTemplate,
|
user.URLTemplate,
|
||||||
user.ReturnCode,
|
user.ReturnCode,
|
||||||
),
|
func(ctx context.Context) (*EncryptedCode, error) {
|
||||||
|
return c.newEncryptedCode(ctx, c.eventstore.Filter, domain.SecretGeneratorTypePasswordResetCode, c.userEncryption) //nolint:staticcheck
|
||||||
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if user.ReturnCode {
|
if plainCode != "" {
|
||||||
user.PlainCode = code.Plain
|
user.PlainCode = &plainCode
|
||||||
}
|
}
|
||||||
return pushedEventsToObjectDetails(events), nil
|
return c.pushAppendAndReduceDetails(ctx, writeModel, events...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) DeleteSchemaUserPassword(ctx context.Context, resourceOwner, id string) (_ *domain.ObjectDetails, err error) {
|
func (c *Commands) DeleteSchemaUserPassword(ctx context.Context, resourceOwner, id string) (_ *domain.ObjectDetails, err error) {
|
||||||
existing, err := c.getSchemaUserPasswordExists(ctx, resourceOwner, id)
|
writeModel, err := existsSchemaUserPasswordWithPermission(ctx, c, resourceOwner, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if existing.EncodedHash == "" {
|
|
||||||
return nil, zerrors.ThrowNotFound(nil, "TODO", "TODO")
|
|
||||||
}
|
|
||||||
|
|
||||||
events, err := c.eventstore.Push(ctx,
|
events, err := writeModel.NewDelete(ctx)
|
||||||
authenticator.NewPasswordDeletedEvent(ctx,
|
|
||||||
&authenticator.NewAggregate(id, existing.ResourceOwner).Aggregate,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return pushedEventsToObjectDetails(events), nil
|
return c.pushAppendAndReduceDetails(ctx, writeModel, events...)
|
||||||
}
|
}
|
||||||
|
|
||||||
type schemaUserPassword struct {
|
type schemaUserPassword struct {
|
||||||
|
Create bool
|
||||||
ResourceOwner string
|
ResourceOwner string
|
||||||
UserID string
|
UserID string
|
||||||
VerificationCode string
|
VerificationCode string
|
||||||
@ -173,18 +141,37 @@ type schemaUserPassword struct {
|
|||||||
EncodedPasswordHash string
|
EncodedPasswordHash string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) getSchemaUserPasswordExists(ctx context.Context, resourceOwner, id string) (*PasswordV3WriteModel, error) {
|
func (c *Commands) getSchemaUserPasswordWM(ctx context.Context, resourceOwner, id string) (*PasswordV3WriteModel, error) {
|
||||||
return c.getSchemaUserPasswordWithVerification(ctx, &schemaUserPassword{ResourceOwner: resourceOwner, UserID: id})
|
writeModel := NewPasswordV3WriteModel(resourceOwner, id, c.checkPermission)
|
||||||
|
if err := c.eventstore.FilterToQueryReducer(ctx, writeModel); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return writeModel, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func existsSchemaUserPasswordWithPermission(ctx context.Context, c *Commands, resourceOwner, id string) (*PasswordV3WriteModel, error) {
|
||||||
|
writeModel, err := c.getSchemaUserPasswordWithVerification(ctx, &schemaUserPassword{ResourceOwner: resourceOwner, UserID: id})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return writeModel, writeModel.Exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) getSchemaUserPasswordWithVerification(ctx context.Context, user *schemaUserPassword) (*PasswordV3WriteModel, error) {
|
func (c *Commands) getSchemaUserPasswordWithVerification(ctx context.Context, user *schemaUserPassword) (*PasswordV3WriteModel, error) {
|
||||||
if user.UserID == "" {
|
if user.UserID == "" {
|
||||||
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-PoSU5BOZCi", "Errors.IDMissing")
|
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-PoSU5BOZCi", "Errors.IDMissing")
|
||||||
}
|
}
|
||||||
writeModel := NewPasswordV3WriteModel(user.ResourceOwner, user.UserID)
|
writeModel, err := c.getSchemaUserPasswordWM(ctx, user.ResourceOwner, user.UserID)
|
||||||
if err := c.eventstore.FilterToQueryReducer(ctx, writeModel); err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := writeModel.Exists(); user.Create && err != nil {
|
||||||
|
schemauser, err := existingSchemaUser(ctx, c, user.ResourceOwner, user.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
writeModel.ResourceOwner = schemauser.ResourceOwner
|
||||||
|
}
|
||||||
|
|
||||||
// if no verification is set, the user must have the permission to change the password
|
// if no verification is set, the user must have the permission to change the password
|
||||||
verification := c.setSchemaUserPasswordWithPermission(writeModel.UserID, writeModel.ResourceOwner)
|
verification := c.setSchemaUserPasswordWithPermission(writeModel.UserID, writeModel.ResourceOwner)
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/repository/user/authenticator"
|
"github.com/zitadel/zitadel/internal/repository/user/authenticator"
|
||||||
|
"github.com/zitadel/zitadel/internal/zerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasswordV3WriteModel struct {
|
type PasswordV3WriteModel struct {
|
||||||
@ -18,15 +21,22 @@ type PasswordV3WriteModel struct {
|
|||||||
Code *crypto.CryptoValue
|
Code *crypto.CryptoValue
|
||||||
CodeCreationDate time.Time
|
CodeCreationDate time.Time
|
||||||
CodeExpiry time.Duration
|
CodeExpiry time.Duration
|
||||||
|
|
||||||
|
checkPermission domain.PermissionCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPasswordV3WriteModel(resourceOwner, id string) *PasswordV3WriteModel {
|
func (wm *PasswordV3WriteModel) GetWriteModel() *eventstore.WriteModel {
|
||||||
|
return &wm.WriteModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPasswordV3WriteModel(resourceOwner, id string, checkPermission domain.PermissionCheck) *PasswordV3WriteModel {
|
||||||
return &PasswordV3WriteModel{
|
return &PasswordV3WriteModel{
|
||||||
WriteModel: eventstore.WriteModel{
|
WriteModel: eventstore.WriteModel{
|
||||||
AggregateID: id,
|
AggregateID: id,
|
||||||
ResourceOwner: resourceOwner,
|
ResourceOwner: resourceOwner,
|
||||||
},
|
},
|
||||||
UserID: id,
|
UserID: id,
|
||||||
|
checkPermission: checkPermission,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,3 +74,60 @@ func (wm *PasswordV3WriteModel) Query() *eventstore.SearchQueryBuilder {
|
|||||||
authenticator.PasswordCodeAddedType,
|
authenticator.PasswordCodeAddedType,
|
||||||
).Builder()
|
).Builder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (wm *PasswordV3WriteModel) NewCreate(
|
||||||
|
ctx context.Context,
|
||||||
|
encodeHash string,
|
||||||
|
changeRequired bool,
|
||||||
|
) ([]eventstore.Command, error) {
|
||||||
|
return []eventstore.Command{
|
||||||
|
authenticator.NewPasswordCreatedEvent(ctx,
|
||||||
|
AuthenticatorAggregateFromWriteModel(wm.GetWriteModel()),
|
||||||
|
wm.UserID,
|
||||||
|
encodeHash,
|
||||||
|
changeRequired,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *PasswordV3WriteModel) NewAddCode(
|
||||||
|
ctx context.Context,
|
||||||
|
notificationType domain.NotificationType,
|
||||||
|
urlTemplate string,
|
||||||
|
codeReturned bool,
|
||||||
|
code func(context.Context) (*EncryptedCode, error),
|
||||||
|
) (_ []eventstore.Command, plainCode string, err error) {
|
||||||
|
crypt, err := code(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
events := []eventstore.Command{
|
||||||
|
authenticator.NewPasswordCodeAddedEvent(ctx,
|
||||||
|
AuthenticatorAggregateFromWriteModel(wm.GetWriteModel()),
|
||||||
|
crypt.Crypted,
|
||||||
|
crypt.Expiry,
|
||||||
|
notificationType,
|
||||||
|
urlTemplate,
|
||||||
|
codeReturned,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
if codeReturned {
|
||||||
|
plainCode = crypt.Plain
|
||||||
|
}
|
||||||
|
return events, plainCode, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *PasswordV3WriteModel) NewDelete(ctx context.Context) ([]eventstore.Command, error) {
|
||||||
|
if err := wm.Exists(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []eventstore.Command{authenticator.NewPasswordDeletedEvent(ctx, AuthenticatorAggregateFromWriteModel(wm.GetWriteModel()))}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *PasswordV3WriteModel) Exists() error {
|
||||||
|
if wm.EncodedHash == "" {
|
||||||
|
return zerrors.ThrowNotFound(nil, "COMMAND-Joi3utDPIh", "Errors.User.Password.NotFound")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -121,7 +121,7 @@ func TestCommands_SetSchemaUserPassword(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-TODO", "Errors.User.Password.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -130,6 +130,7 @@ func TestCommands_SetSchemaUserPassword(t *testing.T) {
|
|||||||
fields{
|
fields{
|
||||||
eventstore: expectEventstore(
|
eventstore: expectEventstore(
|
||||||
expectFilter(),
|
expectFilter(),
|
||||||
|
filterSchemaUserExisting(),
|
||||||
),
|
),
|
||||||
checkPermission: newMockPermissionCheckNotAllowed(),
|
checkPermission: newMockPermissionCheckNotAllowed(),
|
||||||
},
|
},
|
||||||
@ -609,7 +610,7 @@ func TestCommands_RequestSchemaUserPasswordReset(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-TODO", "Errors.User.Password.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-Joi3utDPIh", "Errors.User.Password.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -768,7 +769,8 @@ func TestCommands_RequestSchemaUserPasswordReset(t *testing.T) {
|
|||||||
assertObjectDetails(t, tt.res.details, details)
|
assertObjectDetails(t, tt.res.details, details)
|
||||||
}
|
}
|
||||||
if tt.res.plainCode != "" {
|
if tt.res.plainCode != "" {
|
||||||
assert.Equal(t, tt.res.plainCode, tt.args.user.PlainCode)
|
assert.NotNil(t, tt.args.user.PlainCode)
|
||||||
|
assert.Equal(t, tt.res.plainCode, *tt.args.user.PlainCode)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -824,7 +826,7 @@ func TestCommands_DeleteSchemaUserPassword(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "TODO", "TODO"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-Joi3utDPIh", "Errors.User.Password.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -858,7 +860,7 @@ func TestCommands_DeleteSchemaUserPassword(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "TODO", "TODO"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-Joi3utDPIh", "Errors.User.Password.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -90,7 +90,7 @@ func TestCommands_ChangeSchemaUserPhone(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-b33QAVgel6", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -394,7 +394,7 @@ func TestCommands_VerifySchemaUserPhone(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-bx2OLtgGNS", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -722,7 +722,7 @@ func TestCommands_ResendSchemaUserPhoneCode(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-z8Bu9vuL9s", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/repository/user/schemauser"
|
|
||||||
"github.com/zitadel/zitadel/internal/zerrors"
|
"github.com/zitadel/zitadel/internal/zerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,18 +15,11 @@ func (c *Commands) LockSchemaUser(ctx context.Context, resourceOwner, id string)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !writeModel.Exists() || writeModel.Locked {
|
events, err := writeModel.NewLock(ctx)
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-G4LOrnjY7q", "Errors.User.NotFound")
|
if err != nil {
|
||||||
}
|
|
||||||
if err := c.checkPermissionUpdateUserState(ctx, writeModel.ResourceOwner, writeModel.AggregateID); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := c.pushAppendAndReduce(ctx, writeModel,
|
return c.pushAppendAndReduceDetails(ctx, writeModel, events...)
|
||||||
schemauser.NewLockedEvent(ctx, UserV3AggregateFromWriteModel(&writeModel.WriteModel)),
|
|
||||||
); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return writeModelToObjectDetails(&writeModel.WriteModel), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) UnlockSchemaUser(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
func (c *Commands) UnlockSchemaUser(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
||||||
@ -38,18 +30,11 @@ func (c *Commands) UnlockSchemaUser(ctx context.Context, resourceOwner, id strin
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !writeModel.Exists() || !writeModel.Locked {
|
events, err := writeModel.NewUnlock(ctx)
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-gpBv46Lh9m", "Errors.User.NotFound")
|
if err != nil {
|
||||||
}
|
|
||||||
if err := c.checkPermissionUpdateUserState(ctx, writeModel.ResourceOwner, writeModel.AggregateID); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := c.pushAppendAndReduce(ctx, writeModel,
|
return c.pushAppendAndReduceDetails(ctx, writeModel, events...)
|
||||||
schemauser.NewUnlockedEvent(ctx, UserV3AggregateFromWriteModel(&writeModel.WriteModel)),
|
|
||||||
); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return writeModelToObjectDetails(&writeModel.WriteModel), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) DeactivateSchemaUser(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
func (c *Commands) DeactivateSchemaUser(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
||||||
@ -60,18 +45,11 @@ func (c *Commands) DeactivateSchemaUser(ctx context.Context, resourceOwner, id s
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if writeModel.State != domain.UserStateActive {
|
events, err := writeModel.NewDeactivate(ctx)
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-Ob6lR5iFTe", "Errors.User.NotFound")
|
if err != nil {
|
||||||
}
|
|
||||||
if err := c.checkPermissionUpdateUserState(ctx, writeModel.ResourceOwner, writeModel.AggregateID); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := c.pushAppendAndReduce(ctx, writeModel,
|
return c.pushAppendAndReduceDetails(ctx, writeModel, events...)
|
||||||
schemauser.NewDeactivatedEvent(ctx, UserV3AggregateFromWriteModel(&writeModel.WriteModel)),
|
|
||||||
); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return writeModelToObjectDetails(&writeModel.WriteModel), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) ActivateSchemaUser(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
func (c *Commands) ActivateSchemaUser(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
||||||
@ -82,22 +60,11 @@ func (c *Commands) ActivateSchemaUser(ctx context.Context, resourceOwner, id str
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if writeModel.State != domain.UserStateInactive {
|
events, err := writeModel.NewActivate(ctx)
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-rQjbBr4J3j", "Errors.User.NotFound")
|
if err != nil {
|
||||||
}
|
|
||||||
if err := c.checkPermissionUpdateUserState(ctx, writeModel.ResourceOwner, writeModel.AggregateID); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := c.pushAppendAndReduce(ctx, writeModel,
|
return c.pushAppendAndReduceDetails(ctx, writeModel, events...)
|
||||||
schemauser.NewActivatedEvent(ctx, UserV3AggregateFromWriteModel(&writeModel.WriteModel)),
|
|
||||||
); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return writeModelToObjectDetails(&writeModel.WriteModel), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Commands) checkPermissionUpdateUserState(ctx context.Context, resourceOwner, userID string) error {
|
|
||||||
return c.checkPermission(ctx, domain.PermissionUserWrite, resourceOwner, userID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) getSchemaUserWMForState(ctx context.Context, resourceOwner, id string) (*UserV3WriteModel, error) {
|
func (c *Commands) getSchemaUserWMForState(ctx context.Context, resourceOwner, id string) (*UserV3WriteModel, error) {
|
||||||
@ -107,3 +74,11 @@ func (c *Commands) getSchemaUserWMForState(ctx context.Context, resourceOwner, i
|
|||||||
}
|
}
|
||||||
return writeModel, nil
|
return writeModel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func existingSchemaUser(ctx context.Context, c *Commands, resourceOwner, id string) (*UserV3WriteModel, error) {
|
||||||
|
writeModel, err := c.getSchemaUserWMForState(ctx, resourceOwner, id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return writeModel, writeModel.Exists()
|
||||||
|
}
|
||||||
|
@ -66,7 +66,7 @@ func TestCommandSide_LockSchemaUser(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-G4LOrnjY7q", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -100,7 +100,7 @@ func TestCommandSide_LockSchemaUser(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-G4LOrnjY7q", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -274,7 +274,7 @@ func TestCommandSide_UnlockSchemaUser(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-gpBv46Lh9m", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -308,7 +308,7 @@ func TestCommandSide_UnlockSchemaUser(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-gpBv46Lh9m", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -487,7 +487,7 @@ func TestCommandSide_DeactivateSchemaUser(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-Ob6lR5iFTe", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -521,7 +521,7 @@ func TestCommandSide_DeactivateSchemaUser(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-Ob6lR5iFTe", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -695,7 +695,7 @@ func TestCommandSide_ReactivateSchemaUser(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-rQjbBr4J3j", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -729,7 +729,7 @@ func TestCommandSide_ReactivateSchemaUser(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-rQjbBr4J3j", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -97,7 +97,7 @@ func TestCommands_CreateSchemaUser(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowPreconditionFailed(nil, "COMMAND-VLDTtxT3If", "Errors.UserSchema.NotExists"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-VLDTtxT3If", "Errors.UserSchema.NotExists"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1008,7 +1008,7 @@ func TestCommands_ChangeSchemaUser(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowPreconditionFailed(nil, "COMMAND-VLDTtxT3If", "Errors.UserSchema.NotExists"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-VLDTtxT3If", "Errors.UserSchema.NotExists"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/repository/user/authenticator"
|
|
||||||
"github.com/zitadel/zitadel/internal/zerrors"
|
"github.com/zitadel/zitadel/internal/zerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,91 +16,60 @@ type AddUsername struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) AddUsername(ctx context.Context, username *AddUsername) (*domain.ObjectDetails, error) {
|
func (c *Commands) AddUsername(ctx context.Context, username *AddUsername) (*domain.ObjectDetails, error) {
|
||||||
existing, err := existingSchemaUserWithPermission(ctx, c, username.ResourceOwner, username.UserID)
|
if username.UserID == "" {
|
||||||
|
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-aS3Vz5t6BS", "Errors.IDMissing")
|
||||||
|
}
|
||||||
|
schemauser, err := existingSchemaUser(ctx, c, username.ResourceOwner, username.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = existingSchema(ctx, c, "", schemauser.SchemaID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// TODO check for possible authenticators
|
||||||
|
|
||||||
id, err := c.idGenerator.Next()
|
id, err := c.idGenerator.Next()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
events, err := c.eventstore.Push(ctx,
|
writeModel, err := c.getSchemaUsernameWM(ctx, schemauser.ResourceOwner, schemauser.AggregateID, id)
|
||||||
authenticator.NewUsernameCreatedEvent(ctx,
|
|
||||||
&authenticator.NewAggregate(id, existing.ResourceOwner).Aggregate,
|
|
||||||
existing.AggregateID,
|
|
||||||
username.IsOrgSpecific,
|
|
||||||
username.Username,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return pushedEventsToObjectDetails(events), nil
|
|
||||||
|
events, err := writeModel.NewCreate(ctx, username.IsOrgSpecific, username.Username)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c.pushAppendAndReduceDetails(ctx, writeModel, events...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) DeleteUsername(ctx context.Context, resourceOwner, userID, id string) (_ *domain.ObjectDetails, err error) {
|
func (c *Commands) DeleteUsername(ctx context.Context, resourceOwner, userID, id string) (_ *domain.ObjectDetails, err error) {
|
||||||
existing, err := c.getSchemaUsernameExistsWithPermission(ctx, resourceOwner, userID, id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
events, err := c.eventstore.Push(ctx,
|
|
||||||
authenticator.NewUsernameDeletedEvent(ctx,
|
|
||||||
&authenticator.NewAggregate(id, existing.ResourceOwner).Aggregate,
|
|
||||||
existing.IsOrgSpecific,
|
|
||||||
existing.Username,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return pushedEventsToObjectDetails(events), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Commands) getSchemaUsernameExistsWithPermission(ctx context.Context, resourceOwner, userID, id string) (*UsernameV3WriteModel, error) {
|
|
||||||
if userID == "" {
|
if userID == "" {
|
||||||
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-J6ybG5WZiy", "Errors.IDMissing")
|
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-J6ybG5WZiy", "Errors.IDMissing")
|
||||||
}
|
}
|
||||||
if id == "" {
|
if id == "" {
|
||||||
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-PoSU5BOZCi", "Errors.IDMissing")
|
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-PoSU5BOZCi", "Errors.IDMissing")
|
||||||
}
|
}
|
||||||
writeModel := NewUsernameV3WriteModel(resourceOwner, userID, id)
|
|
||||||
if err := c.eventstore.FilterToQueryReducer(ctx, writeModel); err != nil {
|
writeModel, err := c.getSchemaUsernameWM(ctx, resourceOwner, userID, id)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if writeModel.Username == "" {
|
|
||||||
return nil, zerrors.ThrowNotFound(nil, "TODO", "TODO")
|
events, err := writeModel.NewDelete(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c.pushAppendAndReduceDetails(ctx, writeModel, events...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.checkPermissionUpdateUser(ctx, writeModel.ResourceOwner, writeModel.UserID); err != nil {
|
func (c *Commands) getSchemaUsernameWM(ctx context.Context, resourceOwner, userID, id string) (*UsernameV3WriteModel, error) {
|
||||||
|
writeModel := NewUsernameV3WriteModel(resourceOwner, userID, id, c.checkPermission)
|
||||||
|
if err := c.eventstore.FilterToQueryReducer(ctx, writeModel); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return writeModel, nil
|
return writeModel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func existingSchemaUserWithPermission(ctx context.Context, c *Commands, resourceOwner, userID string) (*UserV3WriteModel, error) {
|
|
||||||
if userID == "" {
|
|
||||||
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-aS3Vz5t6BS", "Errors.IDMissing")
|
|
||||||
}
|
|
||||||
existingUser, err := c.getSchemaUserWMForState(ctx, resourceOwner, userID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !existingUser.Exists() {
|
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-6T2xrOHxTx", "Errors.User.NotFound")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.checkPermissionUpdateUser(ctx, existingUser.ResourceOwner, existingUser.AggregateID); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
existingSchema, err := c.getSchemaWriteModelByID(ctx, "", existingUser.SchemaID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !existingSchema.Exists() {
|
|
||||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-6T2xrOHxTx", "TODO")
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO possible authenticators check
|
|
||||||
return existingUser, nil
|
|
||||||
}
|
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/repository/user/authenticator"
|
"github.com/zitadel/zitadel/internal/repository/user/authenticator"
|
||||||
|
"github.com/zitadel/zitadel/internal/zerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UsernameV3WriteModel struct {
|
type UsernameV3WriteModel struct {
|
||||||
@ -10,15 +15,22 @@ type UsernameV3WriteModel struct {
|
|||||||
UserID string
|
UserID string
|
||||||
Username string
|
Username string
|
||||||
IsOrgSpecific bool
|
IsOrgSpecific bool
|
||||||
|
|
||||||
|
checkPermission domain.PermissionCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUsernameV3WriteModel(resourceOwner, userID, id string) *UsernameV3WriteModel {
|
func (wm *UsernameV3WriteModel) GetWriteModel() *eventstore.WriteModel {
|
||||||
|
return &wm.WriteModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUsernameV3WriteModel(resourceOwner, userID, id string, checkPermission domain.PermissionCheck) *UsernameV3WriteModel {
|
||||||
return &UsernameV3WriteModel{
|
return &UsernameV3WriteModel{
|
||||||
WriteModel: eventstore.WriteModel{
|
WriteModel: eventstore.WriteModel{
|
||||||
AggregateID: id,
|
AggregateID: id,
|
||||||
ResourceOwner: resourceOwner,
|
ResourceOwner: resourceOwner,
|
||||||
},
|
},
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
|
checkPermission: checkPermission,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,3 +64,74 @@ func (wm *UsernameV3WriteModel) Query() *eventstore.SearchQueryBuilder {
|
|||||||
authenticator.UsernameDeletedType,
|
authenticator.UsernameDeletedType,
|
||||||
).Builder()
|
).Builder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (wm *UsernameV3WriteModel) checkPermissionWrite(ctx context.Context) error {
|
||||||
|
if wm.UserID == authz.GetCtxData(ctx).UserID {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err := wm.checkPermission(ctx, domain.PermissionUserWrite, wm.ResourceOwner, wm.UserID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *UsernameV3WriteModel) NewCreate(
|
||||||
|
ctx context.Context,
|
||||||
|
isOrgSpecific bool,
|
||||||
|
username string,
|
||||||
|
) ([]eventstore.Command, error) {
|
||||||
|
if err := wm.NotExists(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := wm.checkPermissionWrite(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []eventstore.Command{
|
||||||
|
authenticator.NewUsernameCreatedEvent(ctx,
|
||||||
|
AuthenticatorAggregateFromWriteModel(wm.GetWriteModel()),
|
||||||
|
wm.UserID,
|
||||||
|
isOrgSpecific,
|
||||||
|
username,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *UsernameV3WriteModel) NewDelete(ctx context.Context) ([]eventstore.Command, error) {
|
||||||
|
if err := wm.Exists(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := wm.checkPermissionWrite(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []eventstore.Command{
|
||||||
|
authenticator.NewUsernameDeletedEvent(ctx,
|
||||||
|
AuthenticatorAggregateFromWriteModel(wm.GetWriteModel()),
|
||||||
|
wm.IsOrgSpecific,
|
||||||
|
wm.Username,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *UsernameV3WriteModel) Exists() error {
|
||||||
|
if wm.Username == "" {
|
||||||
|
return zerrors.ThrowNotFound(nil, "TODO", "TODO")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *UsernameV3WriteModel) NotExists() error {
|
||||||
|
if err := wm.Exists(); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return zerrors.ThrowAlreadyExists(nil, "TODO", "TODO")
|
||||||
|
}
|
||||||
|
|
||||||
|
func AuthenticatorAggregateFromWriteModel(wm *eventstore.WriteModel) *eventstore.Aggregate {
|
||||||
|
return &eventstore.Aggregate{
|
||||||
|
ID: wm.AggregateID,
|
||||||
|
Type: authenticator.AggregateType,
|
||||||
|
ResourceOwner: wm.ResourceOwner,
|
||||||
|
InstanceID: wm.InstanceID,
|
||||||
|
Version: authenticator.AggregateVersion,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -123,7 +123,7 @@ func TestCommands_AddUsername(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-6T2xrOHxTx", "Errors.User.NotFound"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-syHyCsGmvM", "Errors.User.NotFound"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -132,8 +132,11 @@ func TestCommands_AddUsername(t *testing.T) {
|
|||||||
fields{
|
fields{
|
||||||
eventstore: expectEventstore(
|
eventstore: expectEventstore(
|
||||||
filterSchemaUserExisting(),
|
filterSchemaUserExisting(),
|
||||||
|
filterSchemaExisting(),
|
||||||
|
expectFilter(),
|
||||||
),
|
),
|
||||||
checkPermission: newMockPermissionCheckNotAllowed(),
|
checkPermission: newMockPermissionCheckNotAllowed(),
|
||||||
|
idGenerator: mock.ExpectID(t, "username1"),
|
||||||
},
|
},
|
||||||
args{
|
args{
|
||||||
ctx: authz.NewMockContext("instanceID", "", ""),
|
ctx: authz.NewMockContext("instanceID", "", ""),
|
||||||
@ -164,7 +167,7 @@ func TestCommands_AddUsername(t *testing.T) {
|
|||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
err: func(err error) bool {
|
err: func(err error) bool {
|
||||||
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-6T2xrOHxTx", "TODO"))
|
return errors.Is(err, zerrors.ThrowNotFound(nil, "COMMAND-VLDTtxT3If", "Errors.UserSchema.NotExists"))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -174,6 +177,7 @@ func TestCommands_AddUsername(t *testing.T) {
|
|||||||
eventstore: expectEventstore(
|
eventstore: expectEventstore(
|
||||||
filterSchemaUserExisting(),
|
filterSchemaUserExisting(),
|
||||||
filterSchemaExisting(),
|
filterSchemaExisting(),
|
||||||
|
expectFilter(),
|
||||||
expectPush(
|
expectPush(
|
||||||
authenticator.NewUsernameCreatedEvent(
|
authenticator.NewUsernameCreatedEvent(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
@ -207,6 +211,7 @@ func TestCommands_AddUsername(t *testing.T) {
|
|||||||
eventstore: expectEventstore(
|
eventstore: expectEventstore(
|
||||||
filterSchemaUserExisting(),
|
filterSchemaUserExisting(),
|
||||||
filterSchemaExisting(),
|
filterSchemaExisting(),
|
||||||
|
expectFilter(),
|
||||||
expectPush(
|
expectPush(
|
||||||
authenticator.NewUsernameCreatedEvent(
|
authenticator.NewUsernameCreatedEvent(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user