mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:37:32 +00:00
feat: remove phone (#349)
* feat: remove phone number * feat: remove phone number tests * feat: remove phone number tests * fix: regenerate protos
This commit is contained in:
@@ -130,6 +130,10 @@ func (repo *UserRepo) ChangeMyPhone(ctx context.Context, phone *model.Phone) (*m
|
||||
return repo.UserEvents.ChangePhone(ctx, phone)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) RemoveMyPhone(ctx context.Context) error {
|
||||
return repo.UserEvents.RemovePhone(ctx, auth.GetCtxData(ctx).UserID)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) VerifyMyPhone(ctx context.Context, code string) error {
|
||||
return repo.UserEvents.VerifyPhone(ctx, auth.GetCtxData(ctx).UserID, code)
|
||||
}
|
||||
|
@@ -66,6 +66,7 @@ func (p *User) ProcessUser(event *models.Event) (err error) {
|
||||
es_model.UserEmailVerified,
|
||||
es_model.UserPhoneChanged,
|
||||
es_model.UserPhoneVerified,
|
||||
es_model.UserPhoneRemoved,
|
||||
es_model.UserAddressChanged,
|
||||
es_model.UserDeactivated,
|
||||
es_model.UserReactivated,
|
||||
|
@@ -42,6 +42,7 @@ type myUserRepo interface {
|
||||
|
||||
MyPhone(ctx context.Context) (*model.Phone, error)
|
||||
ChangeMyPhone(ctx context.Context, phone *model.Phone) (*model.Phone, error)
|
||||
RemoveMyPhone(ctx context.Context) error
|
||||
VerifyMyPhone(ctx context.Context, code string) error
|
||||
ResendMyPhoneVerificationCode(ctx context.Context) error
|
||||
|
||||
|
@@ -182,6 +182,10 @@ func (repo *UserRepo) ChangePhone(ctx context.Context, email *usr_model.Phone) (
|
||||
return repo.UserEvents.ChangePhone(ctx, email)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) RemovePhone(ctx context.Context, userID string) error {
|
||||
return repo.UserEvents.RemovePhone(ctx, userID)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) CreatePhoneVerificationCode(ctx context.Context, userID string) error {
|
||||
return repo.UserEvents.CreatePhoneVerificationCode(ctx, userID)
|
||||
}
|
||||
|
@@ -66,6 +66,7 @@ func (p *User) ProcessUser(event *models.Event) (err error) {
|
||||
es_model.UserEmailVerified,
|
||||
es_model.UserPhoneChanged,
|
||||
es_model.UserPhoneVerified,
|
||||
es_model.UserPhoneRemoved,
|
||||
es_model.UserAddressChanged,
|
||||
es_model.UserDeactivated,
|
||||
es_model.UserReactivated,
|
||||
|
@@ -32,6 +32,7 @@ type UserRepository interface {
|
||||
|
||||
PhoneByID(ctx context.Context, userID string) (*model.Phone, error)
|
||||
ChangePhone(ctx context.Context, email *model.Phone) (*model.Phone, error)
|
||||
RemovePhone(ctx context.Context, userID string) error
|
||||
CreatePhoneVerificationCode(ctx context.Context, userID string) error
|
||||
|
||||
AddressByID(ctx context.Context, userID string) (*model.Address, error)
|
||||
|
@@ -46,7 +46,8 @@ func (p *NotifyUser) Reduce(event *models.Event) (err error) {
|
||||
es_model.UserEmailChanged,
|
||||
es_model.UserEmailVerified,
|
||||
es_model.UserPhoneChanged,
|
||||
es_model.UserPhoneVerified:
|
||||
es_model.UserPhoneVerified,
|
||||
es_model.UserPhoneRemoved:
|
||||
user, err = p.view.NotifyUserByID(event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -895,6 +895,22 @@ func (es *UserEventstore) PhoneVerificationCodeSent(ctx context.Context, userID
|
||||
return nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) RemovePhone(ctx context.Context, userID string) error {
|
||||
existing, err := es.UserByID(ctx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
repoExisting := model.UserFromModel(existing)
|
||||
removeAggregate := PhoneRemovedAggregate(es.AggregateCreator(), repoExisting)
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, repoExisting.AppendEvents, removeAggregate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
es.userCache.cacheUser(repoExisting)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) AddressByID(ctx context.Context, userID string) (*usr_model.Address, error) {
|
||||
if userID == "" {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-di8ws", "Errors.User.UserIDMissing")
|
||||
|
@@ -2604,6 +2604,70 @@ func TestVerifyPhone(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemovePhone(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
type args struct {
|
||||
es *UserEventstore
|
||||
ctx context.Context
|
||||
userID string
|
||||
code string
|
||||
}
|
||||
type res struct {
|
||||
errFunc func(err error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "remove phone ok",
|
||||
args: args{
|
||||
es: GetMockManipulateUserVerifiedPhone(ctrl),
|
||||
ctx: auth.NewMockContext("orgID", "userID"),
|
||||
userID: "AggregateID",
|
||||
code: "code",
|
||||
},
|
||||
res: res{},
|
||||
},
|
||||
{
|
||||
name: "empty userid",
|
||||
args: args{
|
||||
es: GetMockManipulateUser(ctrl),
|
||||
ctx: auth.NewMockContext("orgID", "userID"),
|
||||
code: "Code",
|
||||
},
|
||||
res: res{
|
||||
errFunc: caos_errs.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "existing user not found",
|
||||
args: args{
|
||||
es: GetMockManipulateUserNoEvents(ctrl),
|
||||
ctx: auth.NewMockContext("orgID", "userID"),
|
||||
userID: "AggregateID",
|
||||
code: "Code",
|
||||
},
|
||||
res: res{
|
||||
errFunc: caos_errs.IsNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := tt.args.es.RemovePhone(tt.args.ctx, tt.args.userID)
|
||||
|
||||
if tt.res.errFunc == nil && err != nil {
|
||||
t.Errorf("should not get err %v", err)
|
||||
}
|
||||
if tt.res.errFunc != nil && !tt.res.errFunc(err) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreatePhoneVerificationCode(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
type args struct {
|
||||
|
@@ -81,6 +81,11 @@ func (u *User) appendUserPhoneVerifiedEvent() {
|
||||
u.IsPhoneVerified = true
|
||||
}
|
||||
|
||||
func (u *User) appendUserPhoneRemovedEvent() {
|
||||
u.Phone = nil
|
||||
u.PhoneCode = nil
|
||||
}
|
||||
|
||||
func (p *Phone) setData(event *es_models.Event) error {
|
||||
p.ObjectRoot.AppendEvent(event)
|
||||
if err := json.Unmarshal(event.Data, p); err != nil {
|
||||
|
@@ -38,6 +38,7 @@ const (
|
||||
UserEmailCodeSent models.EventType = "user.email.code.sent"
|
||||
|
||||
UserPhoneChanged models.EventType = "user.phone.changed"
|
||||
UserPhoneRemoved models.EventType = "user.phone.removed"
|
||||
UserPhoneVerified models.EventType = "user.phone.verified"
|
||||
UserPhoneVerificationFailed models.EventType = "user.phone.verification.failed"
|
||||
UserPhoneCodeAdded models.EventType = "user.phone.code.added"
|
||||
|
@@ -161,6 +161,8 @@ func (u *User) AppendEvent(event *es_models.Event) (err error) {
|
||||
err = u.appendUserPhoneCodeAddedEvent(event)
|
||||
case UserPhoneVerified:
|
||||
u.appendUserPhoneVerifiedEvent()
|
||||
case UserPhoneRemoved:
|
||||
u.appendUserPhoneRemovedEvent()
|
||||
case UserAddressChanged:
|
||||
err = u.appendUserAddressChangedEvent(event)
|
||||
case MfaOtpAdded:
|
||||
|
@@ -508,6 +508,16 @@ func PhoneChangeAggregate(aggCreator *es_models.AggregateCreator, existing *mode
|
||||
}
|
||||
}
|
||||
|
||||
func PhoneRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.User) es_sdk.AggregateFunc {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
agg, err := UserAggregate(ctx, aggCreator, existing)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return agg.AppendEvent(model.UserPhoneRemoved, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func PhoneVerifiedAggregate(aggCreator *es_models.AggregateCreator, existing *model.User) es_sdk.AggregateFunc {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
agg, err := UserAggregate(ctx, aggCreator, existing)
|
||||
|
@@ -1621,6 +1621,56 @@ func TestVerifyPhoneAggregate(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemovePhoneAggregate(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
existing *model.User
|
||||
aggCreator *models.AggregateCreator
|
||||
}
|
||||
type res struct {
|
||||
eventLen int
|
||||
eventTypes []models.EventType
|
||||
errFunc func(err error) bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "user phone removed aggregate ok",
|
||||
args: args{
|
||||
ctx: auth.NewMockContext("orgID", "userID"),
|
||||
existing: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"},
|
||||
Phone: &model.Phone{PhoneNumber: "PhoneNumber"},
|
||||
},
|
||||
aggCreator: models.NewAggregateCreator("Test"),
|
||||
},
|
||||
res: res{
|
||||
eventLen: 1,
|
||||
eventTypes: []models.EventType{model.UserPhoneRemoved},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
agg, err := PhoneRemovedAggregate(tt.args.aggCreator, tt.args.existing)(tt.args.ctx)
|
||||
|
||||
if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen {
|
||||
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
|
||||
}
|
||||
for i := 0; i < tt.res.eventLen; i++ {
|
||||
if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] {
|
||||
t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String())
|
||||
}
|
||||
}
|
||||
if tt.res.errFunc != nil && !tt.res.errFunc(err) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerificationFailedPhoneAggregate(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
|
@@ -99,6 +99,9 @@ func (u *NotifyUser) AppendEvent(event *models.Event) (err error) {
|
||||
u.VerifiedEmail = u.LastEmail
|
||||
case es_model.UserPhoneChanged:
|
||||
err = u.setData(event)
|
||||
case es_model.UserPhoneRemoved:
|
||||
u.VerifiedPhone = ""
|
||||
u.LastPhone = ""
|
||||
case es_model.UserPhoneVerified:
|
||||
u.VerifiedPhone = u.LastPhone
|
||||
case es_model.UserPasswordChanged:
|
||||
|
@@ -193,6 +193,9 @@ func (u *UserView) AppendEvent(event *models.Event) (err error) {
|
||||
err = u.setData(event)
|
||||
case es_model.UserPhoneVerified:
|
||||
u.IsPhoneVerified = true
|
||||
case es_model.UserPhoneRemoved:
|
||||
u.Phone = ""
|
||||
u.IsPhoneVerified = false
|
||||
case es_model.UserDeactivated:
|
||||
u.State = int32(model.UserStateInactive)
|
||||
case es_model.UserReactivated,
|
||||
|
Reference in New Issue
Block a user