mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-07 07:28:57 +00:00
feat: New user (#1153)
* fix: use pointer in events * fix: change user requests to command side * fix: org policy * fix: profile
This commit is contained in:
parent
61d16e4621
commit
65a8efeb0e
@ -60,48 +60,48 @@ func (s *Server) CreateUser(ctx context.Context, in *management.CreateUserReques
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) DeactivateUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
|
func (s *Server) DeactivateUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
|
||||||
user, err := s.user.DeactivateUser(ctx, in.Id)
|
user, err := s.command.DeactivateUser(ctx, in.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return userFromModel(user), nil
|
return userFromDomain(user), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) ReactivateUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
|
func (s *Server) ReactivateUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
|
||||||
user, err := s.user.ReactivateUser(ctx, in.Id)
|
user, err := s.command.ReactivateUser(ctx, in.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return userFromModel(user), nil
|
return userFromDomain(user), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) LockUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
|
func (s *Server) LockUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
|
||||||
user, err := s.user.LockUser(ctx, in.Id)
|
user, err := s.command.LockUser(ctx, in.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return userFromModel(user), nil
|
return userFromDomain(user), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) UnlockUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
|
func (s *Server) UnlockUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
|
||||||
user, err := s.user.UnlockUser(ctx, in.Id)
|
user, err := s.command.UnlockUser(ctx, in.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return userFromModel(user), nil
|
return userFromDomain(user), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) DeleteUser(ctx context.Context, in *management.UserID) (*empty.Empty, error) {
|
func (s *Server) DeleteUser(ctx context.Context, in *management.UserID) (*empty.Empty, error) {
|
||||||
err := s.user.RemoveUser(ctx, in.Id)
|
err := s.command.RemoveUser(ctx, in.Id)
|
||||||
return &empty.Empty{}, err
|
return &empty.Empty{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) UpdateUserMachine(ctx context.Context, in *management.UpdateMachineRequest) (*management.MachineResponse, error) {
|
func (s *Server) UpdateUserMachine(ctx context.Context, in *management.UpdateMachineRequest) (*management.MachineResponse, error) {
|
||||||
machine, err := s.user.ChangeMachine(ctx, updateMachineToModel(in))
|
machine, err := s.command.ChangeMachine(ctx, updateMachineToDomain(in))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return machineFromModel(machine), nil
|
return machineFromDomain(machine), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetUserProfile(ctx context.Context, in *management.UserID) (*management.UserProfileView, error) {
|
func (s *Server) GetUserProfile(ctx context.Context, in *management.UserID) (*management.UserProfileView, error) {
|
||||||
@ -117,11 +117,11 @@ func (s *Server) ChangeUserUserName(ctx context.Context, request *management.Upd
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) UpdateUserProfile(ctx context.Context, request *management.UpdateUserProfileRequest) (*management.UserProfile, error) {
|
func (s *Server) UpdateUserProfile(ctx context.Context, request *management.UpdateUserProfileRequest) (*management.UserProfile, error) {
|
||||||
profile, err := s.user.ChangeProfile(ctx, updateProfileToModel(request))
|
profile, err := s.command.ChangeHumanProfile(ctx, updateProfileToDomain(request))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return profileFromModel(profile), nil
|
return profileFromDomain(profile), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) GetUserEmail(ctx context.Context, in *management.UserID) (*management.UserEmailView, error) {
|
func (s *Server) GetUserEmail(ctx context.Context, in *management.UserID) (*management.UserEmailView, error) {
|
||||||
@ -133,11 +133,11 @@ func (s *Server) GetUserEmail(ctx context.Context, in *management.UserID) (*mana
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) ChangeUserEmail(ctx context.Context, request *management.UpdateUserEmailRequest) (*management.UserEmail, error) {
|
func (s *Server) ChangeUserEmail(ctx context.Context, request *management.UpdateUserEmailRequest) (*management.UserEmail, error) {
|
||||||
email, err := s.user.ChangeEmail(ctx, updateEmailToModel(request))
|
email, err := s.command.ChangeHumanEmail(ctx, updateEmailToDomain(request))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return emailFromModel(email), nil
|
return emailFromDomain(email), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) ResendEmailVerificationMail(ctx context.Context, in *management.UserID) (*empty.Empty, error) {
|
func (s *Server) ResendEmailVerificationMail(ctx context.Context, in *management.UserID) (*empty.Empty, error) {
|
||||||
@ -180,11 +180,11 @@ func (s *Server) GetUserAddress(ctx context.Context, in *management.UserID) (*ma
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) UpdateUserAddress(ctx context.Context, request *management.UpdateUserAddressRequest) (*management.UserAddress, error) {
|
func (s *Server) UpdateUserAddress(ctx context.Context, request *management.UpdateUserAddressRequest) (*management.UserAddress, error) {
|
||||||
address, err := s.user.ChangeAddress(ctx, updateAddressToModel(request))
|
address, err := s.command.ChangeHumanAddress(ctx, updateAddressToDomain(request))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return addressFromModel(address), nil
|
return addressFromDomain(address), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) SendSetPasswordNotification(ctx context.Context, request *management.SetPasswordNotificationRequest) (*empty.Empty, error) {
|
func (s *Server) SendSetPasswordNotification(ctx context.Context, request *management.SetPasswordNotificationRequest) (*empty.Empty, error) {
|
||||||
|
@ -43,32 +43,6 @@ func userFromDomain(user *domain.User) *management.UserResponse {
|
|||||||
return userResp
|
return userResp
|
||||||
}
|
}
|
||||||
|
|
||||||
func userFromModel(user *usr_model.User) *management.UserResponse {
|
|
||||||
creationDate, err := ptypes.TimestampProto(user.CreationDate)
|
|
||||||
logging.Log("GRPC-8duwe").OnError(err).Debug("unable to parse timestamp")
|
|
||||||
|
|
||||||
changeDate, err := ptypes.TimestampProto(user.ChangeDate)
|
|
||||||
logging.Log("GRPC-ckoe3d").OnError(err).Debug("unable to parse timestamp")
|
|
||||||
|
|
||||||
userResp := &management.UserResponse{
|
|
||||||
Id: user.AggregateID,
|
|
||||||
State: management.UserState(user.State),
|
|
||||||
CreationDate: creationDate,
|
|
||||||
ChangeDate: changeDate,
|
|
||||||
Sequence: user.Sequence,
|
|
||||||
UserName: user.UserName,
|
|
||||||
}
|
|
||||||
|
|
||||||
if user.Machine != nil {
|
|
||||||
userResp.User = &management.UserResponse_Machine{Machine: machineFromModel(user.Machine)}
|
|
||||||
}
|
|
||||||
if user.Human != nil {
|
|
||||||
userResp.User = &management.UserResponse_Human{Human: humanFromModel(user.Human)}
|
|
||||||
}
|
|
||||||
|
|
||||||
return userResp
|
|
||||||
}
|
|
||||||
|
|
||||||
func userCreateToDomain(user *management.CreateUserRequest) *domain.User {
|
func userCreateToDomain(user *management.CreateUserRequest) *domain.User {
|
||||||
var human *domain.Human
|
var human *domain.Human
|
||||||
var machine *domain.Machine
|
var machine *domain.Machine
|
||||||
@ -232,7 +206,7 @@ func userMembershipSearchKeyToModel(key management.UserMembershipSearchKey) usr_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func profileFromModel(profile *usr_model.Profile) *management.UserProfile {
|
func profileFromDomain(profile *domain.Profile) *management.UserProfile {
|
||||||
creationDate, err := ptypes.TimestampProto(profile.CreationDate)
|
creationDate, err := ptypes.TimestampProto(profile.CreationDate)
|
||||||
logging.Log("GRPC-dkso3").OnError(err).Debug("unable to parse timestamp")
|
logging.Log("GRPC-dkso3").OnError(err).Debug("unable to parse timestamp")
|
||||||
|
|
||||||
@ -276,21 +250,21 @@ func profileViewFromModel(profile *usr_model.Profile) *management.UserProfileVie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateProfileToModel(u *management.UpdateUserProfileRequest) *usr_model.Profile {
|
func updateProfileToDomain(u *management.UpdateUserProfileRequest) *domain.Profile {
|
||||||
preferredLanguage, err := language.Parse(u.PreferredLanguage)
|
preferredLanguage, err := language.Parse(u.PreferredLanguage)
|
||||||
logging.Log("GRPC-d8k2s").OnError(err).Debug("language malformed")
|
logging.Log("GRPC-d8k2s").OnError(err).Debug("language malformed")
|
||||||
|
|
||||||
return &usr_model.Profile{
|
return &domain.Profile{
|
||||||
ObjectRoot: models.ObjectRoot{AggregateID: u.Id},
|
ObjectRoot: models.ObjectRoot{AggregateID: u.Id},
|
||||||
FirstName: u.FirstName,
|
FirstName: u.FirstName,
|
||||||
LastName: u.LastName,
|
LastName: u.LastName,
|
||||||
NickName: u.NickName,
|
NickName: u.NickName,
|
||||||
PreferredLanguage: preferredLanguage,
|
PreferredLanguage: preferredLanguage,
|
||||||
Gender: usr_model.Gender(u.Gender),
|
Gender: genderToDomain(u.Gender),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func emailFromModel(email *usr_model.Email) *management.UserEmail {
|
func emailFromDomain(email *domain.Email) *management.UserEmail {
|
||||||
creationDate, err := ptypes.TimestampProto(email.CreationDate)
|
creationDate, err := ptypes.TimestampProto(email.CreationDate)
|
||||||
logging.Log("GRPC-d9ow2").OnError(err).Debug("unable to parse timestamp")
|
logging.Log("GRPC-d9ow2").OnError(err).Debug("unable to parse timestamp")
|
||||||
|
|
||||||
@ -324,8 +298,8 @@ func emailViewFromModel(email *usr_model.Email) *management.UserEmailView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateEmailToModel(e *management.UpdateUserEmailRequest) *usr_model.Email {
|
func updateEmailToDomain(e *management.UpdateUserEmailRequest) *domain.Email {
|
||||||
return &usr_model.Email{
|
return &domain.Email{
|
||||||
ObjectRoot: models.ObjectRoot{AggregateID: e.Id},
|
ObjectRoot: models.ObjectRoot{AggregateID: e.Id},
|
||||||
EmailAddress: e.Email,
|
EmailAddress: e.Email,
|
||||||
IsEmailVerified: e.IsEmailVerified,
|
IsEmailVerified: e.IsEmailVerified,
|
||||||
@ -373,7 +347,7 @@ func updatePhoneToModel(e *management.UpdateUserPhoneRequest) *usr_model.Phone {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addressFromModel(address *usr_model.Address) *management.UserAddress {
|
func addressFromDomain(address *domain.Address) *management.UserAddress {
|
||||||
creationDate, err := ptypes.TimestampProto(address.CreationDate)
|
creationDate, err := ptypes.TimestampProto(address.CreationDate)
|
||||||
logging.Log("GRPC-ud8w7").OnError(err).Debug("unable to parse timestamp")
|
logging.Log("GRPC-ud8w7").OnError(err).Debug("unable to parse timestamp")
|
||||||
|
|
||||||
@ -413,8 +387,8 @@ func addressViewFromModel(address *usr_model.Address) *management.UserAddressVie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateAddressToModel(address *management.UpdateUserAddressRequest) *usr_model.Address {
|
func updateAddressToDomain(address *management.UpdateUserAddressRequest) *domain.Address {
|
||||||
return &usr_model.Address{
|
return &domain.Address{
|
||||||
ObjectRoot: models.ObjectRoot{AggregateID: address.Id},
|
ObjectRoot: models.ObjectRoot{AggregateID: address.Id},
|
||||||
Country: address.Country,
|
Country: address.Country,
|
||||||
StreetAddress: address.StreetAddress,
|
StreetAddress: address.StreetAddress,
|
||||||
|
@ -20,9 +20,10 @@ func machineCreateToDomain(machine *management.CreateMachineRequest) *domain.Mac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateMachineToModel(machine *management.UpdateMachineRequest) *usr_model.Machine {
|
func updateMachineToDomain(machine *management.UpdateMachineRequest) *domain.Machine {
|
||||||
return &usr_model.Machine{
|
return &domain.Machine{
|
||||||
ObjectRoot: models.ObjectRoot{AggregateID: machine.Id},
|
ObjectRoot: models.ObjectRoot{AggregateID: machine.Id},
|
||||||
|
Name: machine.Name,
|
||||||
Description: machine.Description,
|
Description: machine.Description,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34,13 +35,6 @@ func machineFromDomain(account *domain.Machine) *management.MachineResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func machineFromModel(account *usr_model.Machine) *management.MachineResponse {
|
|
||||||
return &management.MachineResponse{
|
|
||||||
Name: account.Name,
|
|
||||||
Description: account.Description,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func machineViewFromModel(machine *usr_model.MachineView) *management.MachineView {
|
func machineViewFromModel(machine *usr_model.MachineView) *management.MachineView {
|
||||||
lastKeyAdded, err := ptypes.TimestampProto(machine.LastKeyAdded)
|
lastKeyAdded, err := ptypes.TimestampProto(machine.LastKeyAdded)
|
||||||
logging.Log("MANAG-wGcAQ").OnError(err).Debug("unable to parse date")
|
logging.Log("MANAG-wGcAQ").OnError(err).Debug("unable to parse date")
|
||||||
|
@ -207,7 +207,7 @@ func eventData(event EventPusher) ([]byte, error) {
|
|||||||
if dataType.Kind() == reflect.Struct {
|
if dataType.Kind() == reflect.Struct {
|
||||||
dataBytes, err := json.Marshal(event.Data())
|
dataBytes, err := json.Marshal(event.Data())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.ThrowInvalidArgument(err, "V2-xG87M", "could not marhsal data")
|
return nil, errors.ThrowInvalidArgument(err, "V2-xG87M", "could not marshal data")
|
||||||
}
|
}
|
||||||
return dataBytes, nil
|
return dataBytes, nil
|
||||||
}
|
}
|
||||||
|
@ -45,16 +45,15 @@ func (wm *IAMLabelPolicyWriteModel) NewChangedEvent(
|
|||||||
primaryColor,
|
primaryColor,
|
||||||
secondaryColor string,
|
secondaryColor string,
|
||||||
) (*iam.LabelPolicyChangedEvent, bool) {
|
) (*iam.LabelPolicyChangedEvent, bool) {
|
||||||
|
|
||||||
hasChanged := false
|
hasChanged := false
|
||||||
changedEvent := iam.NewLabelPolicyChangedEvent(ctx)
|
changedEvent := iam.NewLabelPolicyChangedEvent(ctx)
|
||||||
if wm.PrimaryColor != primaryColor {
|
if wm.PrimaryColor != primaryColor {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.PrimaryColor = primaryColor
|
changedEvent.PrimaryColor = &primaryColor
|
||||||
}
|
}
|
||||||
if wm.SecondaryColor != secondaryColor {
|
if wm.SecondaryColor != secondaryColor {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.SecondaryColor = secondaryColor
|
changedEvent.SecondaryColor = &secondaryColor
|
||||||
}
|
}
|
||||||
return changedEvent, hasChanged
|
return changedEvent, hasChanged
|
||||||
}
|
}
|
||||||
|
@ -58,23 +58,23 @@ func (wm *IAMLoginPolicyWriteModel) NewChangedEvent(
|
|||||||
changedEvent := iam.NewLoginPolicyChangedEvent(ctx)
|
changedEvent := iam.NewLoginPolicyChangedEvent(ctx)
|
||||||
if wm.AllowUserNamePassword == allowUsernamePassword {
|
if wm.AllowUserNamePassword == allowUsernamePassword {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.AllowUserNamePassword = allowUsernamePassword
|
changedEvent.AllowUserNamePassword = &allowUsernamePassword
|
||||||
}
|
}
|
||||||
if wm.AllowRegister == allowRegister {
|
if wm.AllowRegister == allowRegister {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.AllowRegister = allowRegister
|
changedEvent.AllowRegister = &allowRegister
|
||||||
}
|
}
|
||||||
if wm.AllowExternalIDP == allowExternalIDP {
|
if wm.AllowExternalIDP == allowExternalIDP {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.AllowExternalIDP = allowExternalIDP
|
changedEvent.AllowExternalIDP = &allowExternalIDP
|
||||||
}
|
}
|
||||||
if wm.ForceMFA != forceMFA {
|
if wm.ForceMFA != forceMFA {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.ForceMFA = forceMFA
|
changedEvent.ForceMFA = &forceMFA
|
||||||
}
|
}
|
||||||
if passwordlessType.Valid() && wm.PasswordlessType != passwordlessType {
|
if passwordlessType.Valid() && wm.PasswordlessType != passwordlessType {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.PasswordlessType = passwordlessType
|
changedEvent.PasswordlessType = &passwordlessType
|
||||||
}
|
}
|
||||||
return changedEvent, hasChanged
|
return changedEvent, hasChanged
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ func (wm *IAMOrgIAMPolicyWriteModel) NewChangedEvent(ctx context.Context, userLo
|
|||||||
changedEvent := iam.NewOrgIAMPolicyChangedEvent(ctx)
|
changedEvent := iam.NewOrgIAMPolicyChangedEvent(ctx)
|
||||||
if wm.UserLoginMustBeDomain != userLoginMustBeDomain {
|
if wm.UserLoginMustBeDomain != userLoginMustBeDomain {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.UserLoginMustBeDomain = userLoginMustBeDomain
|
changedEvent.UserLoginMustBeDomain = &userLoginMustBeDomain
|
||||||
}
|
}
|
||||||
return changedEvent, hasChanged
|
return changedEvent, hasChanged
|
||||||
}
|
}
|
||||||
|
@ -45,11 +45,11 @@ func (wm *IAMPasswordAgePolicyWriteModel) NewChangedEvent(ctx context.Context, e
|
|||||||
changedEvent := iam.NewPasswordAgePolicyChangedEvent(ctx)
|
changedEvent := iam.NewPasswordAgePolicyChangedEvent(ctx)
|
||||||
if wm.ExpireWarnDays != expireWarnDays {
|
if wm.ExpireWarnDays != expireWarnDays {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.ExpireWarnDays = expireWarnDays
|
changedEvent.ExpireWarnDays = &expireWarnDays
|
||||||
}
|
}
|
||||||
if wm.MaxAgeDays != maxAgeDays {
|
if wm.MaxAgeDays != maxAgeDays {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.MaxAgeDays = maxAgeDays
|
changedEvent.MaxAgeDays = &maxAgeDays
|
||||||
}
|
}
|
||||||
return changedEvent, hasChanged
|
return changedEvent, hasChanged
|
||||||
}
|
}
|
||||||
|
@ -53,23 +53,23 @@ func (wm *IAMPasswordComplexityPolicyWriteModel) NewChangedEvent(
|
|||||||
changedEvent := iam.NewPasswordComplexityPolicyChangedEvent(ctx)
|
changedEvent := iam.NewPasswordComplexityPolicyChangedEvent(ctx)
|
||||||
if wm.MinLength != minLength {
|
if wm.MinLength != minLength {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.MinLength = minLength
|
changedEvent.MinLength = &minLength
|
||||||
}
|
}
|
||||||
if wm.HasLowercase != hasLowercase {
|
if wm.HasLowercase != hasLowercase {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.HasLowercase = hasLowercase
|
changedEvent.HasLowercase = &hasLowercase
|
||||||
}
|
}
|
||||||
if wm.HasUpperCase != hasUppercase {
|
if wm.HasUpperCase != hasUppercase {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.HasUpperCase = hasUppercase
|
changedEvent.HasUpperCase = &hasUppercase
|
||||||
}
|
}
|
||||||
if wm.HasNumber != hasNumber {
|
if wm.HasNumber != hasNumber {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.HasNumber = hasNumber
|
changedEvent.HasNumber = &hasNumber
|
||||||
}
|
}
|
||||||
if wm.HasSymbol != hasSymbol {
|
if wm.HasSymbol != hasSymbol {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.HasSymbol = hasSymbol
|
changedEvent.HasSymbol = &hasSymbol
|
||||||
}
|
}
|
||||||
return changedEvent, hasChanged
|
return changedEvent, hasChanged
|
||||||
}
|
}
|
||||||
|
@ -45,11 +45,11 @@ func (wm *IAMPasswordLockoutPolicyWriteModel) NewChangedEvent(ctx context.Contex
|
|||||||
changedEvent := iam.NewPasswordLockoutPolicyChangedEvent(ctx)
|
changedEvent := iam.NewPasswordLockoutPolicyChangedEvent(ctx)
|
||||||
if wm.MaxAttempts != maxAttempts {
|
if wm.MaxAttempts != maxAttempts {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.MaxAttempts = maxAttempts
|
changedEvent.MaxAttempts = &maxAttempts
|
||||||
}
|
}
|
||||||
if wm.ShowLockOutFailures != showLockoutFailure {
|
if wm.ShowLockOutFailures != showLockoutFailure {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.ShowLockOutFailures = showLockoutFailure
|
changedEvent.ShowLockOutFailures = &showLockoutFailure
|
||||||
}
|
}
|
||||||
return changedEvent, hasChanged
|
return changedEvent, hasChanged
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ func (wm *ORGOrgIAMPolicyWriteModel) NewChangedEvent(ctx context.Context, userLo
|
|||||||
changedEvent := org.NewOrgIAMPolicyChangedEvent(ctx)
|
changedEvent := org.NewOrgIAMPolicyChangedEvent(ctx)
|
||||||
if wm.UserLoginMustBeDomain != userLoginMustBeDomain {
|
if wm.UserLoginMustBeDomain != userLoginMustBeDomain {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.UserLoginMustBeDomain = userLoginMustBeDomain
|
changedEvent.UserLoginMustBeDomain = &userLoginMustBeDomain
|
||||||
}
|
}
|
||||||
return changedEvent, hasChanged
|
return changedEvent, hasChanged
|
||||||
}
|
}
|
||||||
|
@ -53,23 +53,23 @@ func (wm *OrgPasswordComplexityPolicyWriteModel) NewChangedEvent(
|
|||||||
changedEvent := org.NewPasswordComplexityPolicyChangedEvent(ctx)
|
changedEvent := org.NewPasswordComplexityPolicyChangedEvent(ctx)
|
||||||
if wm.MinLength != minLength {
|
if wm.MinLength != minLength {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.MinLength = minLength
|
changedEvent.MinLength = &minLength
|
||||||
}
|
}
|
||||||
if wm.HasLowercase != hasLowercase {
|
if wm.HasLowercase != hasLowercase {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.HasLowercase = hasLowercase
|
changedEvent.HasLowercase = &hasLowercase
|
||||||
}
|
}
|
||||||
if wm.HasUpperCase != hasUppercase {
|
if wm.HasUpperCase != hasUppercase {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.HasUpperCase = hasUppercase
|
changedEvent.HasUpperCase = &hasUppercase
|
||||||
}
|
}
|
||||||
if wm.HasNumber != hasNumber {
|
if wm.HasNumber != hasNumber {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.HasNumber = hasNumber
|
changedEvent.HasNumber = &hasNumber
|
||||||
}
|
}
|
||||||
if wm.HasSymbol != hasSymbol {
|
if wm.HasSymbol != hasSymbol {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.HasSymbol = hasSymbol
|
changedEvent.HasSymbol = &hasSymbol
|
||||||
}
|
}
|
||||||
return changedEvent, hasChanged
|
return changedEvent, hasChanged
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,12 @@ func (wm *LabelPolicyWriteModel) Reduce() error {
|
|||||||
wm.SecondaryColor = e.SecondaryColor
|
wm.SecondaryColor = e.SecondaryColor
|
||||||
wm.IsActive = true
|
wm.IsActive = true
|
||||||
case *policy.LabelPolicyChangedEvent:
|
case *policy.LabelPolicyChangedEvent:
|
||||||
wm.PrimaryColor = e.PrimaryColor
|
if e.PrimaryColor != nil {
|
||||||
wm.SecondaryColor = e.SecondaryColor
|
wm.PrimaryColor = *e.PrimaryColor
|
||||||
|
}
|
||||||
|
if e.SecondaryColor != nil {
|
||||||
|
wm.SecondaryColor = *e.SecondaryColor
|
||||||
|
}
|
||||||
case *policy.LabelPolicyRemovedEvent:
|
case *policy.LabelPolicyRemovedEvent:
|
||||||
wm.IsActive = false
|
wm.IsActive = false
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,21 @@ func (wm *LoginPolicyWriteModel) Reduce() error {
|
|||||||
wm.PasswordlessType = e.PasswordlessType
|
wm.PasswordlessType = e.PasswordlessType
|
||||||
wm.IsActive = true
|
wm.IsActive = true
|
||||||
case *policy.LoginPolicyChangedEvent:
|
case *policy.LoginPolicyChangedEvent:
|
||||||
wm.AllowRegister = e.AllowRegister
|
if e.AllowRegister != nil {
|
||||||
wm.AllowUserNamePassword = e.AllowUserNamePassword
|
wm.AllowRegister = *e.AllowRegister
|
||||||
wm.AllowExternalIDP = e.AllowExternalIDP
|
}
|
||||||
wm.ForceMFA = e.ForceMFA
|
if e.AllowUserNamePassword != nil {
|
||||||
wm.PasswordlessType = e.PasswordlessType
|
wm.AllowUserNamePassword = *e.AllowUserNamePassword
|
||||||
|
}
|
||||||
|
if e.AllowExternalIDP != nil {
|
||||||
|
wm.AllowExternalIDP = *e.AllowExternalIDP
|
||||||
|
}
|
||||||
|
if e.ForceMFA != nil {
|
||||||
|
wm.ForceMFA = *e.ForceMFA
|
||||||
|
}
|
||||||
|
if e.PasswordlessType != nil {
|
||||||
|
wm.PasswordlessType = *e.PasswordlessType
|
||||||
|
}
|
||||||
case *policy.LoginPolicyRemovedEvent:
|
case *policy.LoginPolicyRemovedEvent:
|
||||||
wm.IsActive = false
|
wm.IsActive = false
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,9 @@ func (wm *PolicyOrgIAMWriteModel) Reduce() error {
|
|||||||
wm.UserLoginMustBeDomain = e.UserLoginMustBeDomain
|
wm.UserLoginMustBeDomain = e.UserLoginMustBeDomain
|
||||||
wm.IsActive = true
|
wm.IsActive = true
|
||||||
case *policy.OrgIAMPolicyChangedEvent:
|
case *policy.OrgIAMPolicyChangedEvent:
|
||||||
wm.UserLoginMustBeDomain = e.UserLoginMustBeDomain
|
if e.UserLoginMustBeDomain != nil {
|
||||||
|
wm.UserLoginMustBeDomain = *e.UserLoginMustBeDomain
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wm.WriteModel.Reduce()
|
return wm.WriteModel.Reduce()
|
||||||
|
@ -21,8 +21,12 @@ func (wm *PasswordAgePolicyWriteModel) Reduce() error {
|
|||||||
wm.MaxAgeDays = e.MaxAgeDays
|
wm.MaxAgeDays = e.MaxAgeDays
|
||||||
wm.IsActive = true
|
wm.IsActive = true
|
||||||
case *policy.PasswordAgePolicyChangedEvent:
|
case *policy.PasswordAgePolicyChangedEvent:
|
||||||
wm.ExpireWarnDays = e.ExpireWarnDays
|
if e.ExpireWarnDays != nil {
|
||||||
wm.MaxAgeDays = e.MaxAgeDays
|
wm.ExpireWarnDays = *e.ExpireWarnDays
|
||||||
|
}
|
||||||
|
if e.ExpireWarnDays != nil {
|
||||||
|
wm.ExpireWarnDays = *e.ExpireWarnDays
|
||||||
|
}
|
||||||
case *policy.PasswordAgePolicyRemovedEvent:
|
case *policy.PasswordAgePolicyRemovedEvent:
|
||||||
wm.IsActive = false
|
wm.IsActive = false
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,21 @@ func (wm *PasswordComplexityPolicyWriteModel) Reduce() error {
|
|||||||
wm.HasSymbol = e.HasSymbol
|
wm.HasSymbol = e.HasSymbol
|
||||||
wm.IsActive = true
|
wm.IsActive = true
|
||||||
case *policy.PasswordComplexityPolicyChangedEvent:
|
case *policy.PasswordComplexityPolicyChangedEvent:
|
||||||
wm.MinLength = e.MinLength
|
if e.MinLength != nil {
|
||||||
wm.HasLowercase = e.HasLowercase
|
wm.MinLength = *e.MinLength
|
||||||
wm.HasUpperCase = e.HasUpperCase
|
}
|
||||||
wm.HasNumber = e.HasNumber
|
if e.HasLowercase != nil {
|
||||||
wm.HasSymbol = e.HasSymbol
|
wm.HasLowercase = *e.HasLowercase
|
||||||
|
}
|
||||||
|
if e.HasUpperCase != nil {
|
||||||
|
wm.HasUpperCase = *e.HasUpperCase
|
||||||
|
}
|
||||||
|
if e.HasNumber != nil {
|
||||||
|
wm.HasNumber = *e.HasNumber
|
||||||
|
}
|
||||||
|
if e.HasSymbol != nil {
|
||||||
|
wm.HasSymbol = *e.HasSymbol
|
||||||
|
}
|
||||||
case *policy.PasswordComplexityPolicyRemovedEvent:
|
case *policy.PasswordComplexityPolicyRemovedEvent:
|
||||||
wm.IsActive = false
|
wm.IsActive = false
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,12 @@ func (wm *PasswordLockoutPolicyWriteModel) Reduce() error {
|
|||||||
wm.ShowLockOutFailures = e.ShowLockOutFailures
|
wm.ShowLockOutFailures = e.ShowLockOutFailures
|
||||||
wm.IsActive = true
|
wm.IsActive = true
|
||||||
case *policy.PasswordLockoutPolicyChangedEvent:
|
case *policy.PasswordLockoutPolicyChangedEvent:
|
||||||
wm.MaxAttempts = e.MaxAttempts
|
if e.MaxAttempts != nil {
|
||||||
wm.ShowLockOutFailures = e.ShowLockOutFailures
|
wm.MaxAttempts = *e.MaxAttempts
|
||||||
|
}
|
||||||
|
if e.ShowLockOutFailures != nil {
|
||||||
|
wm.ShowLockOutFailures = *e.ShowLockOutFailures
|
||||||
|
}
|
||||||
case *policy.PasswordLockoutPolicyRemovedEvent:
|
case *policy.PasswordLockoutPolicyRemovedEvent:
|
||||||
wm.IsActive = false
|
wm.IsActive = false
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,11 @@ func (r *CommandSide) AddUser(ctx context.Context, user *domain.User) (*domain.U
|
|||||||
}
|
}
|
||||||
return &domain.User{UserName: user.UserName, Human: human}, nil
|
return &domain.User{UserName: user.UserName, Human: human}, nil
|
||||||
} else if user.Machine != nil {
|
} else if user.Machine != nil {
|
||||||
|
machine, err := r.AddMachine(ctx, user.ResourceOwner, user.UserName, user.Machine)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &domain.User{UserName: user.UserName, Machine: machine}, nil
|
||||||
}
|
}
|
||||||
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-8K0df", "Errors.User.TypeUndefined")
|
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-8K0df", "Errors.User.TypeUndefined")
|
||||||
}
|
}
|
||||||
@ -31,9 +35,11 @@ func (r *CommandSide) RegisterUser(ctx context.Context, user *domain.User) (*dom
|
|||||||
}
|
}
|
||||||
|
|
||||||
if user.Human != nil {
|
if user.Human != nil {
|
||||||
|
human, err := r.RegisterHuman(ctx, user.ResourceOwner, user.UserName, user.Human, nil)
|
||||||
} else if user.Machine != nil {
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &domain.User{UserName: user.UserName, Human: human}, nil
|
||||||
}
|
}
|
||||||
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-8K0df", "Errors.User.TypeUndefined")
|
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-8K0df", "Errors.User.TypeUndefined")
|
||||||
}
|
}
|
||||||
@ -122,6 +128,21 @@ func (r *CommandSide) UnlockUser(ctx context.Context, userID string) (*domain.Us
|
|||||||
return writeModelToUser(existingUser), nil
|
return writeModelToUser(existingUser), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *CommandSide) RemoveUser(ctx context.Context, userID string) error {
|
||||||
|
existingUser, err := r.userWriteModelByID(ctx, userID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if existingUser.UserState != domain.UserStateDeleted {
|
||||||
|
return caos_errs.ThrowAlreadyExists(nil, "COMMAND-5M0od", "Errors.User.NotFound")
|
||||||
|
}
|
||||||
|
userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel)
|
||||||
|
userAgg.PushEvents(user.NewUserRemovedEvent(ctx))
|
||||||
|
//TODO: release unqie username
|
||||||
|
|
||||||
|
return r.eventstore.PushAggregate(ctx, existingUser, userAgg)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *CommandSide) userWriteModelByID(ctx context.Context, userID string) (writeModel *UserWriteModel, err error) {
|
func (r *CommandSide) userWriteModelByID(ctx context.Context, userID string) (writeModel *UserWriteModel, err error) {
|
||||||
ctx, span := tracing.NewSpan(ctx)
|
ctx, span := tracing.NewSpan(ctx)
|
||||||
defer func() { span.EndWithError(err) }()
|
defer func() { span.EndWithError(err) }()
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/caos/zitadel/internal/user/model"
|
|
||||||
"github.com/caos/zitadel/internal/v2/domain"
|
"github.com/caos/zitadel/internal/v2/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,28 +37,28 @@ func writeModelToHuman(wm *HumanWriteModel) *domain.Human {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeModelToProfile(wm *HumanProfileWriteModel) *model.Profile {
|
func writeModelToProfile(wm *HumanProfileWriteModel) *domain.Profile {
|
||||||
return &model.Profile{
|
return &domain.Profile{
|
||||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||||
FirstName: wm.FirstName,
|
FirstName: wm.FirstName,
|
||||||
LastName: wm.LastName,
|
LastName: wm.LastName,
|
||||||
NickName: wm.NickName,
|
NickName: wm.NickName,
|
||||||
DisplayName: wm.DisplayName,
|
DisplayName: wm.DisplayName,
|
||||||
PreferredLanguage: wm.PreferredLanguage,
|
PreferredLanguage: wm.PreferredLanguage,
|
||||||
Gender: model.Gender(wm.Gender),
|
Gender: wm.Gender,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeModelToEmail(wm *HumanEmailWriteModel) *model.Email {
|
func writeModelToEmail(wm *HumanEmailWriteModel) *domain.Email {
|
||||||
return &model.Email{
|
return &domain.Email{
|
||||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||||
EmailAddress: wm.Email,
|
EmailAddress: wm.Email,
|
||||||
IsEmailVerified: wm.IsEmailVerified,
|
IsEmailVerified: wm.IsEmailVerified,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeModelToAddress(wm *HumanAddressWriteModel) *model.Address {
|
func writeModelToAddress(wm *HumanAddressWriteModel) *domain.Address {
|
||||||
return &model.Address{
|
return &domain.Address{
|
||||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||||
Country: wm.Country,
|
Country: wm.Country,
|
||||||
Locality: wm.Locality,
|
Locality: wm.Locality,
|
||||||
@ -68,3 +67,11 @@ func writeModelToAddress(wm *HumanAddressWriteModel) *model.Address {
|
|||||||
StreetAddress: wm.StreetAddress,
|
StreetAddress: wm.StreetAddress,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeModelToMachine(wm *MachineWriteModel) *domain.Machine {
|
||||||
|
return &domain.Machine{
|
||||||
|
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||||
|
Name: wm.Name,
|
||||||
|
Description: wm.Description,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -32,32 +32,50 @@ func (r *CommandSide) AddHuman(ctx context.Context, orgID, username string, huma
|
|||||||
human.HashPasswordIfExisting(pwPolicy, r.userPasswordAlg, true)
|
human.HashPasswordIfExisting(pwPolicy, r.userPasswordAlg, true)
|
||||||
|
|
||||||
userAgg := UserAggregateFromWriteModel(&addedHuman.WriteModel)
|
userAgg := UserAggregateFromWriteModel(&addedHuman.WriteModel)
|
||||||
userAgg.PushEvents(
|
addEvent := user.NewHumanAddedEvent(
|
||||||
user.NewHumanAddedEvent(
|
ctx,
|
||||||
ctx,
|
username,
|
||||||
username,
|
human.FirstName,
|
||||||
human.FirstName,
|
human.LastName,
|
||||||
human.LastName,
|
human.NickName,
|
||||||
human.NickName,
|
human.DisplayName,
|
||||||
human.DisplayName,
|
human.PreferredLanguage,
|
||||||
human.PreferredLanguage,
|
human.Gender,
|
||||||
human.Gender,
|
human.EmailAddress,
|
||||||
human.EmailAddress,
|
)
|
||||||
human.PhoneNumber,
|
if human.Phone != nil {
|
||||||
|
addEvent.AddPhoneData(human.PhoneNumber)
|
||||||
|
}
|
||||||
|
if human.Address != nil {
|
||||||
|
addEvent.AddAddressData(
|
||||||
human.Country,
|
human.Country,
|
||||||
human.Locality,
|
human.Locality,
|
||||||
human.PostalCode,
|
human.PostalCode,
|
||||||
human.Region,
|
human.Region,
|
||||||
human.StreetAddress,
|
human.StreetAddress)
|
||||||
),
|
}
|
||||||
)
|
if human.Password != nil {
|
||||||
//TODO: HashPassword If existing
|
addEvent.AddPasswordData(human.SecretCrypto, human.ChangeRequired)
|
||||||
//TODO: Generate Init Code if needed
|
}
|
||||||
//TODO: Generate Phone Code if needed
|
userAgg.PushEvents(addEvent)
|
||||||
|
|
||||||
|
if human.IsInitialState() {
|
||||||
|
initCode, err := domain.NewInitUserCode(r.initializeUserCode)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
user.NewHumanInitialCodeAddedEvent(ctx, initCode.Code, initCode.Expiry)
|
||||||
|
}
|
||||||
if human.Email != nil && human.EmailAddress != "" && human.IsEmailVerified {
|
if human.Email != nil && human.EmailAddress != "" && human.IsEmailVerified {
|
||||||
userAgg.PushEvents(user.NewHumanEmailVerifiedEvent(ctx))
|
userAgg.PushEvents(user.NewHumanEmailVerifiedEvent(ctx))
|
||||||
}
|
}
|
||||||
if human.Phone != nil && human.PhoneNumber != "" && human.IsPhoneVerified {
|
if human.Phone != nil && human.PhoneNumber != "" && !human.IsPhoneVerified {
|
||||||
|
phoneCode, err := domain.NewPhoneCode(r.phoneVerificationCode)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
user.NewHumanPhoneCodeAddedEvent(ctx, phoneCode.Code, phoneCode.Expiry)
|
||||||
|
} else if human.Phone != nil && human.PhoneNumber != "" && human.IsPhoneVerified {
|
||||||
userAgg.PushEvents(user.NewHumanPhoneVerifiedEvent(ctx))
|
userAgg.PushEvents(user.NewHumanPhoneVerifiedEvent(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,3 +86,82 @@ func (r *CommandSide) AddHuman(ctx context.Context, orgID, username string, huma
|
|||||||
|
|
||||||
return writeModelToHuman(addedHuman), nil
|
return writeModelToHuman(addedHuman), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *CommandSide) RegisterHuman(ctx context.Context, orgID, username string, human *domain.Human, externalIDP *domain.ExternalIDP) (*domain.Human, error) {
|
||||||
|
if !human.IsValid() || externalIDP == nil && (human.Password == nil || human.SecretString == "") {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-9dk45", "Errors.User.Invalid")
|
||||||
|
}
|
||||||
|
userID, err := r.idGenerator.Next()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
human.AggregateID = userID
|
||||||
|
orgIAMPolicy, err := r.GetOrgIAMPolicy(ctx, orgID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pwPolicy, err := r.GetOrgPasswordComplexityPolicy(ctx, orgID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
addedHuman := NewHumanWriteModel(human.AggregateID)
|
||||||
|
//TODO: Check Unique Username or unique external idp
|
||||||
|
human.CheckOrgIAMPolicy(username, orgIAMPolicy)
|
||||||
|
human.SetNamesAsDisplayname()
|
||||||
|
human.HashPasswordIfExisting(pwPolicy, r.userPasswordAlg, true)
|
||||||
|
|
||||||
|
userAgg := UserAggregateFromWriteModel(&addedHuman.WriteModel)
|
||||||
|
addEvent := user.NewHumanRegisteredEvent(
|
||||||
|
ctx,
|
||||||
|
username,
|
||||||
|
human.FirstName,
|
||||||
|
human.LastName,
|
||||||
|
human.NickName,
|
||||||
|
human.DisplayName,
|
||||||
|
human.PreferredLanguage,
|
||||||
|
human.Gender,
|
||||||
|
human.EmailAddress,
|
||||||
|
)
|
||||||
|
if human.Phone != nil {
|
||||||
|
addEvent.AddPhoneData(human.PhoneNumber)
|
||||||
|
}
|
||||||
|
if human.Address != nil {
|
||||||
|
addEvent.AddAddressData(
|
||||||
|
human.Country,
|
||||||
|
human.Locality,
|
||||||
|
human.PostalCode,
|
||||||
|
human.Region,
|
||||||
|
human.StreetAddress)
|
||||||
|
}
|
||||||
|
if human.Password != nil {
|
||||||
|
addEvent.AddPasswordData(human.SecretCrypto, human.ChangeRequired)
|
||||||
|
}
|
||||||
|
userAgg.PushEvents(addEvent)
|
||||||
|
//TODO: Add External IDP Event
|
||||||
|
if human.IsInitialState() {
|
||||||
|
initCode, err := domain.NewInitUserCode(r.initializeUserCode)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
user.NewHumanInitialCodeAddedEvent(ctx, initCode.Code, initCode.Expiry)
|
||||||
|
}
|
||||||
|
|
||||||
|
if human.Email != nil && human.EmailAddress != "" && human.IsEmailVerified {
|
||||||
|
userAgg.PushEvents(user.NewHumanEmailVerifiedEvent(ctx))
|
||||||
|
}
|
||||||
|
if human.Phone != nil && human.PhoneNumber != "" && !human.IsPhoneVerified {
|
||||||
|
phoneCode, err := domain.NewPhoneCode(r.phoneVerificationCode)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
user.NewHumanPhoneCodeAddedEvent(ctx, phoneCode.Code, phoneCode.Expiry)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = r.eventstore.PushAggregate(ctx, addedHuman, userAgg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return writeModelToHuman(addedHuman), nil
|
||||||
|
}
|
||||||
|
@ -4,11 +4,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
|
||||||
"github.com/caos/zitadel/internal/v2/domain"
|
"github.com/caos/zitadel/internal/v2/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *CommandSide) ChangeHumanAddress(ctx context.Context, address *usr_model.Address) (*usr_model.Address, error) {
|
func (r *CommandSide) ChangeHumanAddress(ctx context.Context, address *domain.Address) (*domain.Address, error) {
|
||||||
existingAddress, err := r.addressWriteModel(ctx, address.AggregateID)
|
existingAddress, err := r.addressWriteModel(ctx, address.AggregateID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -58,11 +58,21 @@ func (wm *HumanAddressWriteModel) Reduce() error {
|
|||||||
wm.StreetAddress = e.StreetAddress
|
wm.StreetAddress = e.StreetAddress
|
||||||
wm.UserState = domain.UserStateActive
|
wm.UserState = domain.UserStateActive
|
||||||
case *user.HumanAddressChangedEvent:
|
case *user.HumanAddressChangedEvent:
|
||||||
wm.Country = e.Country
|
if e.Country != nil {
|
||||||
wm.Locality = e.Locality
|
wm.Country = *e.Country
|
||||||
wm.PostalCode = e.PostalCode
|
}
|
||||||
wm.Region = e.Region
|
if e.Locality != nil {
|
||||||
wm.StreetAddress = e.StreetAddress
|
wm.Locality = *e.Locality
|
||||||
|
}
|
||||||
|
if e.PostalCode != nil {
|
||||||
|
wm.PostalCode = *e.PostalCode
|
||||||
|
}
|
||||||
|
if e.Region != nil {
|
||||||
|
wm.Region = *e.Region
|
||||||
|
}
|
||||||
|
if e.StreetAddress != nil {
|
||||||
|
wm.StreetAddress = *e.StreetAddress
|
||||||
|
}
|
||||||
case *user.UserRemovedEvent:
|
case *user.UserRemovedEvent:
|
||||||
wm.UserState = domain.UserStateDeleted
|
wm.UserState = domain.UserStateDeleted
|
||||||
}
|
}
|
||||||
@ -87,23 +97,23 @@ func (wm *HumanAddressWriteModel) NewChangedEvent(
|
|||||||
changedEvent := user.NewHumanAddressChangedEvent(ctx)
|
changedEvent := user.NewHumanAddressChangedEvent(ctx)
|
||||||
if wm.Country != country {
|
if wm.Country != country {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.Country = country
|
changedEvent.Country = &country
|
||||||
}
|
}
|
||||||
if wm.Locality != locality {
|
if wm.Locality != locality {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.Locality = locality
|
changedEvent.Locality = &locality
|
||||||
}
|
}
|
||||||
if wm.PostalCode != postalCode {
|
if wm.PostalCode != postalCode {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.PostalCode = postalCode
|
changedEvent.PostalCode = &postalCode
|
||||||
}
|
}
|
||||||
if wm.Region != region {
|
if wm.Region != region {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.Region = region
|
changedEvent.Region = ®ion
|
||||||
}
|
}
|
||||||
if wm.StreetAddress != streetAddress {
|
if wm.StreetAddress != streetAddress {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.StreetAddress = streetAddress
|
changedEvent.StreetAddress = &streetAddress
|
||||||
}
|
}
|
||||||
return changedEvent, hasChanged
|
return changedEvent, hasChanged
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
|
||||||
"github.com/caos/zitadel/internal/v2/domain"
|
"github.com/caos/zitadel/internal/v2/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *CommandSide) ChangeHumanEmail(ctx context.Context, email *usr_model.Email) (*usr_model.Email, error) {
|
func (r *CommandSide) ChangeHumanEmail(ctx context.Context, email *domain.Email) (*domain.Email, error) {
|
||||||
if !email.IsValid() {
|
if !email.IsValid() {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M9sf", "Errors.Email.Invalid")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M9sf", "Errors.Email.Invalid")
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/caos/zitadel/internal/crypto"
|
||||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||||
"github.com/caos/zitadel/internal/v2/domain"
|
"github.com/caos/zitadel/internal/v2/domain"
|
||||||
"github.com/caos/zitadel/internal/v2/repository/user"
|
"github.com/caos/zitadel/internal/v2/repository/user"
|
||||||
@ -31,6 +32,9 @@ type HumanWriteModel struct {
|
|||||||
Region string
|
Region string
|
||||||
StreetAddress string
|
StreetAddress string
|
||||||
|
|
||||||
|
Secret *crypto.CryptoValue
|
||||||
|
SecretChangeRequired bool
|
||||||
|
|
||||||
UserState domain.UserState
|
UserState domain.UserState
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,21 +49,20 @@ func NewHumanWriteModel(userID string) *HumanWriteModel {
|
|||||||
func (wm *HumanWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
func (wm *HumanWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *user.HumanEmailChangedEvent:
|
case *user.HumanAddedEvent,
|
||||||
wm.AppendEvents(e)
|
*user.HumanRegisteredEvent,
|
||||||
case *user.HumanEmailVerifiedEvent:
|
*user.HumanProfileChangedEvent,
|
||||||
wm.AppendEvents(e)
|
*user.HumanEmailChangedEvent,
|
||||||
case *user.HumanAddedEvent, *user.HumanRegisteredEvent:
|
*user.HumanEmailVerifiedEvent,
|
||||||
wm.AppendEvents(e)
|
*user.HumanPhoneChangedEvent,
|
||||||
case *user.UserDeactivatedEvent:
|
*user.HumanPhoneVerifiedEvent,
|
||||||
wm.AppendEvents(e)
|
*user.HumanAddressChangedEvent,
|
||||||
case *user.UserReactivatedEvent:
|
*user.HumanPasswordChangedEvent,
|
||||||
wm.AppendEvents(e)
|
*user.UserDeactivatedEvent,
|
||||||
case *user.UserLockedEvent:
|
*user.UserReactivatedEvent,
|
||||||
wm.AppendEvents(e)
|
*user.UserLockedEvent,
|
||||||
case *user.UserUnlockedEvent:
|
*user.UserUnlockedEvent,
|
||||||
wm.AppendEvents(e)
|
*user.UserRemovedEvent:
|
||||||
case *user.UserRemovedEvent:
|
|
||||||
wm.AppendEvents(e)
|
wm.AppendEvents(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,11 +73,21 @@ func (wm *HumanWriteModel) Reduce() error {
|
|||||||
for _, event := range wm.Events {
|
for _, event := range wm.Events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *user.HumanAddedEvent:
|
case *user.HumanAddedEvent:
|
||||||
wm.UserName = e.UserName
|
wm.reduceHumanAddedEvent(e)
|
||||||
wm.UserState = domain.UserStateInitial
|
|
||||||
case *user.HumanRegisteredEvent:
|
case *user.HumanRegisteredEvent:
|
||||||
wm.UserName = e.UserName
|
wm.reduceHumanRegisteredEvent(e)
|
||||||
wm.UserState = domain.UserStateInitial
|
case *user.HumanProfileChangedEvent:
|
||||||
|
wm.reduceHumanProfileChangedEvent(e)
|
||||||
|
case *user.HumanEmailChangedEvent:
|
||||||
|
wm.reduceHumanEmailChangedEvent(e)
|
||||||
|
case *user.HumanEmailVerifiedEvent:
|
||||||
|
wm.reduceHumanEmailVerifiedEvent()
|
||||||
|
case *user.HumanPhoneChangedEvent:
|
||||||
|
wm.reduceHumanPhoneChangedEvent(e)
|
||||||
|
case *user.HumanPhoneVerifiedEvent:
|
||||||
|
wm.reduceHumanPhoneVerifiedEvent()
|
||||||
|
case *user.HumanPasswordChangedEvent:
|
||||||
|
wm.reduceHumanPasswordChangedEvent(e)
|
||||||
case *user.UserLockedEvent:
|
case *user.UserLockedEvent:
|
||||||
if wm.UserState != domain.UserStateDeleted {
|
if wm.UserState != domain.UserStateDeleted {
|
||||||
wm.UserState = domain.UserStateLocked
|
wm.UserState = domain.UserStateLocked
|
||||||
@ -102,3 +115,105 @@ func (wm *HumanWriteModel) Query() *eventstore.SearchQueryBuilder {
|
|||||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
|
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
|
||||||
AggregateIDs(wm.AggregateID)
|
AggregateIDs(wm.AggregateID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (wm *HumanWriteModel) reduceHumanAddedEvent(e *user.HumanAddedEvent) {
|
||||||
|
wm.UserName = e.UserName
|
||||||
|
wm.FirstName = e.FirstName
|
||||||
|
wm.LastName = e.LastName
|
||||||
|
wm.NickName = e.NickName
|
||||||
|
wm.DisplayName = e.DisplayName
|
||||||
|
wm.PreferredLanguage = e.PreferredLanguage
|
||||||
|
wm.Gender = e.Gender
|
||||||
|
wm.Email = e.EmailAddress
|
||||||
|
wm.Phone = e.PhoneNumber
|
||||||
|
wm.Country = e.Country
|
||||||
|
wm.Locality = e.Locality
|
||||||
|
wm.PostalCode = e.PostalCode
|
||||||
|
wm.Region = e.Region
|
||||||
|
wm.StreetAddress = e.StreetAddress
|
||||||
|
wm.Secret = e.Secret
|
||||||
|
wm.SecretChangeRequired = e.ChangeRequired
|
||||||
|
wm.UserState = domain.UserStateInitial
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *HumanWriteModel) reduceHumanRegisteredEvent(e *user.HumanRegisteredEvent) {
|
||||||
|
wm.UserName = e.UserName
|
||||||
|
wm.FirstName = e.FirstName
|
||||||
|
wm.LastName = e.LastName
|
||||||
|
wm.NickName = e.NickName
|
||||||
|
wm.DisplayName = e.DisplayName
|
||||||
|
wm.PreferredLanguage = e.PreferredLanguage
|
||||||
|
wm.Gender = e.Gender
|
||||||
|
wm.Email = e.EmailAddress
|
||||||
|
wm.Phone = e.PhoneNumber
|
||||||
|
wm.Country = e.Country
|
||||||
|
wm.Locality = e.Locality
|
||||||
|
wm.PostalCode = e.PostalCode
|
||||||
|
wm.Region = e.Region
|
||||||
|
wm.StreetAddress = e.StreetAddress
|
||||||
|
wm.Secret = e.Secret
|
||||||
|
wm.SecretChangeRequired = e.ChangeRequired
|
||||||
|
wm.UserState = domain.UserStateInitial
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *HumanWriteModel) reduceHumanProfileChangedEvent(e *user.HumanProfileChangedEvent) {
|
||||||
|
if e.FirstName != "" {
|
||||||
|
wm.FirstName = e.FirstName
|
||||||
|
}
|
||||||
|
if e.LastName != "" {
|
||||||
|
wm.LastName = e.LastName
|
||||||
|
}
|
||||||
|
if e.NickName != nil {
|
||||||
|
wm.NickName = *e.NickName
|
||||||
|
}
|
||||||
|
if e.DisplayName != nil {
|
||||||
|
wm.DisplayName = *e.DisplayName
|
||||||
|
}
|
||||||
|
if e.PreferredLanguage != nil {
|
||||||
|
wm.PreferredLanguage = *e.PreferredLanguage
|
||||||
|
}
|
||||||
|
if e.Gender != nil {
|
||||||
|
wm.Gender = *e.Gender
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *HumanWriteModel) reduceHumanEmailChangedEvent(e *user.HumanEmailChangedEvent) {
|
||||||
|
wm.Email = e.EmailAddress
|
||||||
|
wm.IsEmailVerified = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *HumanWriteModel) reduceHumanEmailVerifiedEvent() {
|
||||||
|
wm.IsEmailVerified = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *HumanWriteModel) reduceHumanPhoneChangedEvent(e *user.HumanPhoneChangedEvent) {
|
||||||
|
wm.Phone = e.PhoneNumber
|
||||||
|
wm.IsPhoneVerified = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *HumanWriteModel) reduceHumanPhoneVerifiedEvent() {
|
||||||
|
wm.IsPhoneVerified = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *HumanWriteModel) reduceHumanAddressChangedEvent(e *user.HumanAddressChangedEvent) {
|
||||||
|
if e.Country != nil {
|
||||||
|
wm.Country = *e.Country
|
||||||
|
}
|
||||||
|
if e.Locality != nil {
|
||||||
|
wm.Locality = *e.Locality
|
||||||
|
}
|
||||||
|
if e.PostalCode != nil {
|
||||||
|
wm.PostalCode = *e.PostalCode
|
||||||
|
}
|
||||||
|
if e.Region != nil {
|
||||||
|
wm.Region = *e.Region
|
||||||
|
}
|
||||||
|
if e.StreetAddress != nil {
|
||||||
|
wm.StreetAddress = *e.StreetAddress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *HumanWriteModel) reduceHumanPasswordChangedEvent(e *user.HumanPasswordChangedEvent) {
|
||||||
|
wm.Secret = e.Secret
|
||||||
|
wm.SecretChangeRequired = e.ChangeRequired
|
||||||
|
}
|
||||||
|
@ -4,11 +4,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
|
||||||
"github.com/caos/zitadel/internal/v2/domain"
|
"github.com/caos/zitadel/internal/v2/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *CommandSide) ChangeHumanProfile(ctx context.Context, profile *usr_model.Profile) (*usr_model.Profile, error) {
|
func (r *CommandSide) ChangeHumanProfile(ctx context.Context, profile *domain.Profile) (*domain.Profile, error) {
|
||||||
if !profile.IsValid() {
|
if !profile.IsValid() {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-8io0d", "Errors.User.Profile.Invalid")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-8io0d", "Errors.User.Profile.Invalid")
|
||||||
}
|
}
|
||||||
|
@ -62,12 +62,24 @@ func (wm *HumanProfileWriteModel) Reduce() error {
|
|||||||
wm.Gender = e.Gender
|
wm.Gender = e.Gender
|
||||||
wm.UserState = domain.UserStateActive
|
wm.UserState = domain.UserStateActive
|
||||||
case *user.HumanProfileChangedEvent:
|
case *user.HumanProfileChangedEvent:
|
||||||
wm.FirstName = e.FirstName
|
if e.FirstName != "" {
|
||||||
wm.LastName = e.LastName
|
wm.FirstName = e.FirstName
|
||||||
wm.NickName = e.NickName
|
}
|
||||||
wm.DisplayName = e.DisplayName
|
if e.LastName != "" {
|
||||||
wm.PreferredLanguage = e.PreferredLanguage
|
wm.LastName = e.LastName
|
||||||
wm.Gender = e.Gender
|
}
|
||||||
|
if e.NickName != nil {
|
||||||
|
wm.NickName = *e.NickName
|
||||||
|
}
|
||||||
|
if e.DisplayName != nil {
|
||||||
|
wm.DisplayName = *e.DisplayName
|
||||||
|
}
|
||||||
|
if e.PreferredLanguage != nil {
|
||||||
|
wm.PreferredLanguage = *e.PreferredLanguage
|
||||||
|
}
|
||||||
|
if e.Gender != nil {
|
||||||
|
wm.Gender = *e.Gender
|
||||||
|
}
|
||||||
case *user.UserRemovedEvent:
|
case *user.UserRemovedEvent:
|
||||||
wm.UserState = domain.UserStateDeleted
|
wm.UserState = domain.UserStateDeleted
|
||||||
}
|
}
|
||||||
@ -101,19 +113,19 @@ func (wm *HumanProfileWriteModel) NewChangedEvent(
|
|||||||
}
|
}
|
||||||
if wm.NickName != nickName {
|
if wm.NickName != nickName {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.NickName = nickName
|
changedEvent.NickName = &nickName
|
||||||
}
|
}
|
||||||
if wm.DisplayName != displayName {
|
if wm.DisplayName != displayName {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.DisplayName = displayName
|
changedEvent.DisplayName = &displayName
|
||||||
}
|
}
|
||||||
if wm.PreferredLanguage != preferredLanguage {
|
if wm.PreferredLanguage != preferredLanguage {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.PreferredLanguage = preferredLanguage
|
changedEvent.PreferredLanguage = &preferredLanguage
|
||||||
}
|
}
|
||||||
if gender.Valid() && wm.Gender != gender {
|
if gender.Valid() && wm.Gender != gender {
|
||||||
hasChanged = true
|
hasChanged = true
|
||||||
changedEvent.Gender = gender
|
changedEvent.Gender = &gender
|
||||||
}
|
}
|
||||||
|
|
||||||
return changedEvent, hasChanged
|
return changedEvent, hasChanged
|
||||||
|
78
internal/v2/command/user_machine.go
Normal file
78
internal/v2/command/user_machine.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||||
|
"github.com/caos/zitadel/internal/v2/domain"
|
||||||
|
"github.com/caos/zitadel/internal/v2/repository/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (r *CommandSide) AddMachine(ctx context.Context, orgID, username string, machine *domain.Machine) (*domain.Machine, error) {
|
||||||
|
if !machine.IsValid() {
|
||||||
|
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-5M0ds", "Errors.User.Invalid")
|
||||||
|
}
|
||||||
|
userID, err := r.idGenerator.Next()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
//TODO: Check Unique username
|
||||||
|
machine.AggregateID = userID
|
||||||
|
orgIAMPolicy, err := r.GetOrgIAMPolicy(ctx, orgID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !orgIAMPolicy.UserLoginMustBeDomain {
|
||||||
|
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-6M0ds", "Errors.User.Invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
addedMachine := NewMachineWriteModel(machine.AggregateID)
|
||||||
|
userAgg := UserAggregateFromWriteModel(&addedMachine.WriteModel)
|
||||||
|
userAgg.PushEvents(
|
||||||
|
user.NewMachineAddedEvent(
|
||||||
|
ctx,
|
||||||
|
username,
|
||||||
|
machine.Name,
|
||||||
|
machine.Description,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return writeModelToMachine(addedMachine), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CommandSide) ChangeMachine(ctx context.Context, machine *domain.Machine) (*domain.Machine, error) {
|
||||||
|
existingUser, err := r.machineWriteModelByID(ctx, machine.AggregateID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if existingUser.UserState == domain.UserStateDeleted || existingUser.UserState == domain.UserStateUnspecified {
|
||||||
|
return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-5M0od", "Errors.User.NotFound")
|
||||||
|
}
|
||||||
|
|
||||||
|
changedEvent, hasChanged := existingUser.NewChangedEvent(ctx, machine.Name, machine.Description)
|
||||||
|
if !hasChanged {
|
||||||
|
return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-2M9fs", "Errors.User.Email.NotChanged")
|
||||||
|
}
|
||||||
|
userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel)
|
||||||
|
userAgg.PushEvents(changedEvent)
|
||||||
|
|
||||||
|
err = r.eventstore.PushAggregate(ctx, existingUser, userAgg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return writeModelToMachine(existingUser), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CommandSide) machineWriteModelByID(ctx context.Context, userID string) (writeModel *MachineWriteModel, err error) {
|
||||||
|
if userID == "" {
|
||||||
|
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-5M0ds", "Errors.User.UserIDMissing")
|
||||||
|
}
|
||||||
|
ctx, span := tracing.NewSpan(ctx)
|
||||||
|
defer func() { span.EndWithError(err) }()
|
||||||
|
|
||||||
|
writeModel = NewMachineWriteModel(userID)
|
||||||
|
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return writeModel, nil
|
||||||
|
}
|
109
internal/v2/command/user_machine_write_model.go
Normal file
109
internal/v2/command/user_machine_write_model.go
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||||
|
"github.com/caos/zitadel/internal/v2/domain"
|
||||||
|
"github.com/caos/zitadel/internal/v2/repository/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MachineWriteModel struct {
|
||||||
|
eventstore.WriteModel
|
||||||
|
|
||||||
|
UserName string
|
||||||
|
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
UserState domain.UserState
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMachineWriteModel(userID string) *MachineWriteModel {
|
||||||
|
return &MachineWriteModel{
|
||||||
|
WriteModel: eventstore.WriteModel{
|
||||||
|
AggregateID: userID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *MachineWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||||
|
for _, event := range events {
|
||||||
|
switch e := event.(type) {
|
||||||
|
case *user.MachineAddedEvent:
|
||||||
|
wm.AppendEvents(e)
|
||||||
|
case *user.MachineChangedEvent:
|
||||||
|
wm.AppendEvents(e)
|
||||||
|
case *user.UserDeactivatedEvent:
|
||||||
|
wm.AppendEvents(e)
|
||||||
|
case *user.UserReactivatedEvent:
|
||||||
|
wm.AppendEvents(e)
|
||||||
|
case *user.UserLockedEvent:
|
||||||
|
wm.AppendEvents(e)
|
||||||
|
case *user.UserUnlockedEvent:
|
||||||
|
wm.AppendEvents(e)
|
||||||
|
case *user.UserRemovedEvent:
|
||||||
|
wm.AppendEvents(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Compute State? initial/active
|
||||||
|
func (wm *MachineWriteModel) Reduce() error {
|
||||||
|
for _, event := range wm.Events {
|
||||||
|
switch e := event.(type) {
|
||||||
|
case *user.MachineAddedEvent:
|
||||||
|
wm.UserName = e.UserName
|
||||||
|
wm.Name = e.Name
|
||||||
|
wm.Description = e.Description
|
||||||
|
wm.UserState = domain.UserStateActive
|
||||||
|
case *user.MachineChangedEvent:
|
||||||
|
if e.Name != nil {
|
||||||
|
wm.Name = *e.Name
|
||||||
|
}
|
||||||
|
if e.Description != nil {
|
||||||
|
wm.Description = *e.Description
|
||||||
|
}
|
||||||
|
case *user.UserLockedEvent:
|
||||||
|
if wm.UserState != domain.UserStateDeleted {
|
||||||
|
wm.UserState = domain.UserStateLocked
|
||||||
|
}
|
||||||
|
case *user.UserUnlockedEvent:
|
||||||
|
if wm.UserState != domain.UserStateDeleted {
|
||||||
|
wm.UserState = domain.UserStateActive
|
||||||
|
}
|
||||||
|
case *user.UserDeactivatedEvent:
|
||||||
|
if wm.UserState != domain.UserStateDeleted {
|
||||||
|
wm.UserState = domain.UserStateInactive
|
||||||
|
}
|
||||||
|
case *user.UserReactivatedEvent:
|
||||||
|
if wm.UserState != domain.UserStateDeleted {
|
||||||
|
wm.UserState = domain.UserStateActive
|
||||||
|
}
|
||||||
|
case *user.UserRemovedEvent:
|
||||||
|
wm.UserState = domain.UserStateDeleted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wm.WriteModel.Reduce()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *MachineWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||||
|
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
|
||||||
|
AggregateIDs(wm.AggregateID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *MachineWriteModel) NewChangedEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
name,
|
||||||
|
description string,
|
||||||
|
) (*user.MachineChangedEvent, bool) {
|
||||||
|
hasChanged := false
|
||||||
|
changedEvent := user.NewMachineChangedEvent(ctx)
|
||||||
|
if wm.Name != name {
|
||||||
|
hasChanged = true
|
||||||
|
changedEvent.Name = &name
|
||||||
|
}
|
||||||
|
if wm.Description != description {
|
||||||
|
hasChanged = true
|
||||||
|
changedEvent.Description = &description
|
||||||
|
}
|
||||||
|
return changedEvent, hasChanged
|
||||||
|
}
|
@ -17,10 +17,6 @@ type Human struct {
|
|||||||
*Phone
|
*Phone
|
||||||
*Address
|
*Address
|
||||||
ExternalIDPs []*ExternalIDP
|
ExternalIDPs []*ExternalIDP
|
||||||
InitCode *InitUserCode
|
|
||||||
EmailCode *EmailCode
|
|
||||||
PhoneCode *PhoneCode
|
|
||||||
PasswordCode *PasswordCode
|
|
||||||
OTP *OTP
|
OTP *OTP
|
||||||
U2FTokens []*WebAuthNToken
|
U2FTokens []*WebAuthNToken
|
||||||
PasswordlessTokens []*WebAuthNToken
|
PasswordlessTokens []*WebAuthNToken
|
||||||
@ -79,3 +75,18 @@ func (u *Human) HashPasswordIfExisting(policy *PasswordComplexityPolicy, passwor
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *Human) IsInitialState() bool {
|
||||||
|
return u.Email == nil || !u.IsEmailVerified || (u.ExternalIDPs == nil || len(u.ExternalIDPs) == 0) && (u.Password == nil || u.SecretString == "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInitUserCode(generator crypto.Generator) (*InitUserCode, error) {
|
||||||
|
initCodeCrypto, _, err := crypto.NewCode(generator)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &InitUserCode{
|
||||||
|
Code: initCodeCrypto,
|
||||||
|
Expiry: generator.Expiry(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
@ -39,3 +39,14 @@ func (p *Phone) formatPhone() error {
|
|||||||
p.PhoneNumber = libphonenumber.Format(phoneNr, libphonenumber.E164)
|
p.PhoneNumber = libphonenumber.Format(phoneNr, libphonenumber.E164)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewPhoneCode(phoneGenerator crypto.Generator) (*PhoneCode, error) {
|
||||||
|
phoneCodeCrypto, _, err := crypto.NewCode(phoneGenerator)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &PhoneCode{
|
||||||
|
Code: phoneCodeCrypto,
|
||||||
|
Expiry: phoneGenerator.Expiry(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
@ -17,3 +17,7 @@ type Profile struct {
|
|||||||
PreferredLoginName string
|
PreferredLoginName string
|
||||||
LoginNames []string
|
LoginNames []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Profile) IsValid() bool {
|
||||||
|
return p.FirstName != "" && p.LastName != ""
|
||||||
|
}
|
||||||
|
@ -21,8 +21,12 @@ func (rm *LabelPolicyReadModel) Reduce() error {
|
|||||||
rm.SecondaryColor = e.SecondaryColor
|
rm.SecondaryColor = e.SecondaryColor
|
||||||
rm.IsActive = true
|
rm.IsActive = true
|
||||||
case *policy.LabelPolicyChangedEvent:
|
case *policy.LabelPolicyChangedEvent:
|
||||||
rm.PrimaryColor = e.PrimaryColor
|
if e.PrimaryColor != nil {
|
||||||
rm.SecondaryColor = e.SecondaryColor
|
rm.PrimaryColor = *e.PrimaryColor
|
||||||
|
}
|
||||||
|
if e.SecondaryColor != nil {
|
||||||
|
rm.SecondaryColor = *e.SecondaryColor
|
||||||
|
}
|
||||||
case *policy.LabelPolicyRemovedEvent:
|
case *policy.LabelPolicyRemovedEvent:
|
||||||
rm.IsActive = false
|
rm.IsActive = false
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,21 @@ func (rm *LoginPolicyReadModel) Reduce() error {
|
|||||||
rm.PasswordlessType = e.PasswordlessType
|
rm.PasswordlessType = e.PasswordlessType
|
||||||
rm.IsActive = true
|
rm.IsActive = true
|
||||||
case *policy.LoginPolicyChangedEvent:
|
case *policy.LoginPolicyChangedEvent:
|
||||||
rm.AllowUserNamePassword = e.AllowUserNamePassword
|
if e.AllowUserNamePassword != nil {
|
||||||
rm.AllowExternalIDP = e.AllowExternalIDP
|
rm.AllowUserNamePassword = *e.AllowUserNamePassword
|
||||||
rm.AllowRegister = e.AllowRegister
|
}
|
||||||
rm.ForceMFA = e.ForceMFA
|
if e.AllowExternalIDP != nil {
|
||||||
rm.PasswordlessType = e.PasswordlessType
|
rm.AllowExternalIDP = *e.AllowExternalIDP
|
||||||
|
}
|
||||||
|
if e.AllowRegister != nil {
|
||||||
|
rm.AllowRegister = *e.AllowRegister
|
||||||
|
}
|
||||||
|
if e.ForceMFA != nil {
|
||||||
|
rm.ForceMFA = *e.ForceMFA
|
||||||
|
}
|
||||||
|
if e.PasswordlessType != nil {
|
||||||
|
rm.PasswordlessType = *e.PasswordlessType
|
||||||
|
}
|
||||||
case *policy.LoginPolicyRemovedEvent:
|
case *policy.LoginPolicyRemovedEvent:
|
||||||
rm.IsActive = false
|
rm.IsActive = false
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,9 @@ func (rm *OrgIAMPolicyReadModel) Reduce() error {
|
|||||||
case *policy.OrgIAMPolicyAddedEvent:
|
case *policy.OrgIAMPolicyAddedEvent:
|
||||||
rm.UserLoginMustBeDomain = e.UserLoginMustBeDomain
|
rm.UserLoginMustBeDomain = e.UserLoginMustBeDomain
|
||||||
case *policy.OrgIAMPolicyChangedEvent:
|
case *policy.OrgIAMPolicyChangedEvent:
|
||||||
rm.UserLoginMustBeDomain = e.UserLoginMustBeDomain
|
if e.UserLoginMustBeDomain != nil {
|
||||||
|
rm.UserLoginMustBeDomain = *e.UserLoginMustBeDomain
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rm.ReadModel.Reduce()
|
return rm.ReadModel.Reduce()
|
||||||
|
@ -19,8 +19,12 @@ func (rm *PasswordAgePolicyReadModel) Reduce() error {
|
|||||||
rm.ExpireWarnDays = e.ExpireWarnDays
|
rm.ExpireWarnDays = e.ExpireWarnDays
|
||||||
rm.MaxAgeDays = e.MaxAgeDays
|
rm.MaxAgeDays = e.MaxAgeDays
|
||||||
case *policy.PasswordAgePolicyChangedEvent:
|
case *policy.PasswordAgePolicyChangedEvent:
|
||||||
rm.ExpireWarnDays = e.ExpireWarnDays
|
if e.ExpireWarnDays != nil {
|
||||||
rm.MaxAgeDays = e.MaxAgeDays
|
rm.ExpireWarnDays = *e.ExpireWarnDays
|
||||||
|
}
|
||||||
|
if e.MaxAgeDays != nil {
|
||||||
|
rm.MaxAgeDays = *e.MaxAgeDays
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rm.ReadModel.Reduce()
|
return rm.ReadModel.Reduce()
|
||||||
|
@ -25,11 +25,21 @@ func (rm *PasswordComplexityPolicyReadModel) Reduce() error {
|
|||||||
rm.HasNumber = e.HasNumber
|
rm.HasNumber = e.HasNumber
|
||||||
rm.HasSymbol = e.HasSymbol
|
rm.HasSymbol = e.HasSymbol
|
||||||
case *policy.PasswordComplexityPolicyChangedEvent:
|
case *policy.PasswordComplexityPolicyChangedEvent:
|
||||||
rm.MinLength = e.MinLength
|
if e.MinLength != nil {
|
||||||
rm.HasLowercase = e.HasLowercase
|
rm.MinLength = *e.MinLength
|
||||||
rm.HasUpperCase = e.HasUpperCase
|
}
|
||||||
rm.HasNumber = e.HasNumber
|
if e.HasLowercase != nil {
|
||||||
rm.HasSymbol = e.HasSymbol
|
rm.HasLowercase = *e.HasLowercase
|
||||||
|
}
|
||||||
|
if e.HasUpperCase != nil {
|
||||||
|
rm.HasUpperCase = *e.HasUpperCase
|
||||||
|
}
|
||||||
|
if e.HasNumber != nil {
|
||||||
|
rm.HasNumber = *e.HasNumber
|
||||||
|
}
|
||||||
|
if e.HasSymbol != nil {
|
||||||
|
rm.HasSymbol = *e.HasSymbol
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rm.ReadModel.Reduce()
|
return rm.ReadModel.Reduce()
|
||||||
|
@ -19,8 +19,12 @@ func (rm *PasswordLockoutPolicyReadModel) Reduce() error {
|
|||||||
rm.MaxAttempts = e.MaxAttempts
|
rm.MaxAttempts = e.MaxAttempts
|
||||||
rm.ShowLockOutFailures = e.ShowLockOutFailures
|
rm.ShowLockOutFailures = e.ShowLockOutFailures
|
||||||
case *policy.PasswordLockoutPolicyChangedEvent:
|
case *policy.PasswordLockoutPolicyChangedEvent:
|
||||||
rm.MaxAttempts = e.MaxAttempts
|
if e.MaxAttempts != nil {
|
||||||
rm.ShowLockOutFailures = e.ShowLockOutFailures
|
rm.MaxAttempts = *e.MaxAttempts
|
||||||
|
}
|
||||||
|
if e.ShowLockOutFailures != nil {
|
||||||
|
rm.ShowLockOutFailures = *e.ShowLockOutFailures
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rm.ReadModel.Reduce()
|
return rm.ReadModel.Reduce()
|
||||||
|
@ -53,8 +53,8 @@ func LabelPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReade
|
|||||||
type LabelPolicyChangedEvent struct {
|
type LabelPolicyChangedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
PrimaryColor string `json:"primaryColor,omitempty"`
|
PrimaryColor *string `json:"primaryColor,omitempty"`
|
||||||
SecondaryColor string `json:"secondaryColor,omitempty"`
|
SecondaryColor *string `json:"secondaryColor,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *LabelPolicyChangedEvent) Data() interface{} {
|
func (e *LabelPolicyChangedEvent) Data() interface{} {
|
||||||
|
@ -63,11 +63,11 @@ func LoginPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReade
|
|||||||
type LoginPolicyChangedEvent struct {
|
type LoginPolicyChangedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
AllowUserNamePassword bool `json:"allowUsernamePassword,omitempty"`
|
AllowUserNamePassword *bool `json:"allowUsernamePassword,omitempty"`
|
||||||
AllowRegister bool `json:"allowRegister,omitempty"`
|
AllowRegister *bool `json:"allowRegister,omitempty"`
|
||||||
AllowExternalIDP bool `json:"allowExternalIdp,omitempty"`
|
AllowExternalIDP *bool `json:"allowExternalIdp,omitempty"`
|
||||||
ForceMFA bool `json:"forceMFA,omitempty"`
|
ForceMFA *bool `json:"forceMFA,omitempty"`
|
||||||
PasswordlessType domain.PasswordlessType `json:"passwordlessType,omitempty"`
|
PasswordlessType *domain.PasswordlessType `json:"passwordlessType,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type LoginPolicyEventData struct {
|
type LoginPolicyEventData struct {
|
||||||
|
@ -49,7 +49,7 @@ func OrgIAMPolicyAddedEventMapper(event *repository.Event) (eventstore.EventRead
|
|||||||
type OrgIAMPolicyChangedEvent struct {
|
type OrgIAMPolicyChangedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
UserLoginMustBeDomain bool `json:"userLoginMustBeDomain,omitempty"`
|
UserLoginMustBeDomain *bool `json:"userLoginMustBeDomain,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *OrgIAMPolicyChangedEvent) Data() interface{} {
|
func (e *OrgIAMPolicyChangedEvent) Data() interface{} {
|
||||||
|
@ -53,8 +53,8 @@ func PasswordAgePolicyAddedEventMapper(event *repository.Event) (eventstore.Even
|
|||||||
type PasswordAgePolicyChangedEvent struct {
|
type PasswordAgePolicyChangedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
ExpireWarnDays uint64 `json:"expireWarnDays,omitempty"`
|
ExpireWarnDays *uint64 `json:"expireWarnDays,omitempty"`
|
||||||
MaxAgeDays uint64 `json:"maxAgeDays,omitempty"`
|
MaxAgeDays *uint64 `json:"maxAgeDays,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *PasswordAgePolicyChangedEvent) Data() interface{} {
|
func (e *PasswordAgePolicyChangedEvent) Data() interface{} {
|
||||||
|
@ -61,11 +61,11 @@ func PasswordComplexityPolicyAddedEventMapper(event *repository.Event) (eventsto
|
|||||||
type PasswordComplexityPolicyChangedEvent struct {
|
type PasswordComplexityPolicyChangedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
MinLength uint64 `json:"minLength,omitempty"`
|
MinLength *uint64 `json:"minLength,omitempty"`
|
||||||
HasLowercase bool `json:"hasLowercase,omitempty"`
|
HasLowercase *bool `json:"hasLowercase,omitempty"`
|
||||||
HasUpperCase bool `json:"hasUppercase,omitempty"`
|
HasUpperCase *bool `json:"hasUppercase,omitempty"`
|
||||||
HasNumber bool `json:"hasNumber,omitempty"`
|
HasNumber *bool `json:"hasNumber,omitempty"`
|
||||||
HasSymbol bool `json:"hasSymbol,omitempty"`
|
HasSymbol *bool `json:"hasSymbol,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *PasswordComplexityPolicyChangedEvent) Data() interface{} {
|
func (e *PasswordComplexityPolicyChangedEvent) Data() interface{} {
|
||||||
|
@ -53,8 +53,8 @@ func PasswordLockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.
|
|||||||
type PasswordLockoutPolicyChangedEvent struct {
|
type PasswordLockoutPolicyChangedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
MaxAttempts uint64 `json:"maxAttempts,omitempty"`
|
MaxAttempts *uint64 `json:"maxAttempts,omitempty"`
|
||||||
ShowLockOutFailures bool `json:"showLockOutFailures,omitempty"`
|
ShowLockOutFailures *bool `json:"showLockOutFailures,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *PasswordLockoutPolicyChangedEvent) Data() interface{} {
|
func (e *PasswordLockoutPolicyChangedEvent) Data() interface{} {
|
||||||
|
@ -53,6 +53,34 @@ func (e *HumanAddedEvent) Data() interface{} {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *HumanAddedEvent) AddAddressData(
|
||||||
|
country,
|
||||||
|
locality,
|
||||||
|
postalCode,
|
||||||
|
region,
|
||||||
|
streetAddress string,
|
||||||
|
) {
|
||||||
|
e.Country = country
|
||||||
|
e.Locality = locality
|
||||||
|
e.PostalCode = postalCode
|
||||||
|
e.Region = region
|
||||||
|
e.StreetAddress = streetAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *HumanAddedEvent) AddPhoneData(
|
||||||
|
phoneNumber string,
|
||||||
|
) {
|
||||||
|
e.PhoneNumber = phoneNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *HumanAddedEvent) AddPasswordData(
|
||||||
|
secret *crypto.CryptoValue,
|
||||||
|
changeRequired bool,
|
||||||
|
) {
|
||||||
|
e.Secret = secret
|
||||||
|
e.ChangeRequired = changeRequired
|
||||||
|
}
|
||||||
|
|
||||||
func NewHumanAddedEvent(
|
func NewHumanAddedEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
userName,
|
userName,
|
||||||
@ -62,13 +90,7 @@ func NewHumanAddedEvent(
|
|||||||
displayName string,
|
displayName string,
|
||||||
preferredLanguage language.Tag,
|
preferredLanguage language.Tag,
|
||||||
gender domain.Gender,
|
gender domain.Gender,
|
||||||
emailAddress,
|
emailAddress string,
|
||||||
phoneNumber,
|
|
||||||
country,
|
|
||||||
locality,
|
|
||||||
postalCode,
|
|
||||||
region,
|
|
||||||
streetAddress string,
|
|
||||||
) *HumanAddedEvent {
|
) *HumanAddedEvent {
|
||||||
return &HumanAddedEvent{
|
return &HumanAddedEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||||
@ -83,12 +105,6 @@ func NewHumanAddedEvent(
|
|||||||
PreferredLanguage: preferredLanguage,
|
PreferredLanguage: preferredLanguage,
|
||||||
Gender: gender,
|
Gender: gender,
|
||||||
EmailAddress: emailAddress,
|
EmailAddress: emailAddress,
|
||||||
PhoneNumber: phoneNumber,
|
|
||||||
Country: country,
|
|
||||||
Locality: locality,
|
|
||||||
PostalCode: postalCode,
|
|
||||||
Region: region,
|
|
||||||
StreetAddress: streetAddress,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,12 +141,43 @@ type HumanRegisteredEvent struct {
|
|||||||
PostalCode string `json:"postalCode,omitempty"`
|
PostalCode string `json:"postalCode,omitempty"`
|
||||||
Region string `json:"region,omitempty"`
|
Region string `json:"region,omitempty"`
|
||||||
StreetAddress string `json:"streetAddress,omitempty"`
|
StreetAddress string `json:"streetAddress,omitempty"`
|
||||||
|
|
||||||
|
Secret *crypto.CryptoValue `json:"secret,omitempty"`
|
||||||
|
ChangeRequired bool `json:"changeRequired,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *HumanRegisteredEvent) Data() interface{} {
|
func (e *HumanRegisteredEvent) Data() interface{} {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *HumanRegisteredEvent) AddAddressData(
|
||||||
|
country,
|
||||||
|
locality,
|
||||||
|
postalCode,
|
||||||
|
region,
|
||||||
|
streetAddress string,
|
||||||
|
) {
|
||||||
|
e.Country = country
|
||||||
|
e.Locality = locality
|
||||||
|
e.PostalCode = postalCode
|
||||||
|
e.Region = region
|
||||||
|
e.StreetAddress = streetAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *HumanRegisteredEvent) AddPhoneData(
|
||||||
|
phoneNumber string,
|
||||||
|
) {
|
||||||
|
e.PhoneNumber = phoneNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *HumanRegisteredEvent) AddPasswordData(
|
||||||
|
secret *crypto.CryptoValue,
|
||||||
|
changeRequired bool,
|
||||||
|
) {
|
||||||
|
e.Secret = secret
|
||||||
|
e.ChangeRequired = changeRequired
|
||||||
|
}
|
||||||
|
|
||||||
func NewHumanRegisteredEvent(
|
func NewHumanRegisteredEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
userName,
|
userName,
|
||||||
@ -140,13 +187,7 @@ func NewHumanRegisteredEvent(
|
|||||||
displayName string,
|
displayName string,
|
||||||
preferredLanguage language.Tag,
|
preferredLanguage language.Tag,
|
||||||
gender domain.Gender,
|
gender domain.Gender,
|
||||||
emailAddress,
|
emailAddress string,
|
||||||
phoneNumber,
|
|
||||||
country,
|
|
||||||
locality,
|
|
||||||
postalCode,
|
|
||||||
region,
|
|
||||||
streetAddress string,
|
|
||||||
) *HumanRegisteredEvent {
|
) *HumanRegisteredEvent {
|
||||||
return &HumanRegisteredEvent{
|
return &HumanRegisteredEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||||
@ -161,12 +202,6 @@ func NewHumanRegisteredEvent(
|
|||||||
PreferredLanguage: preferredLanguage,
|
PreferredLanguage: preferredLanguage,
|
||||||
Gender: gender,
|
Gender: gender,
|
||||||
EmailAddress: emailAddress,
|
EmailAddress: emailAddress,
|
||||||
PhoneNumber: phoneNumber,
|
|
||||||
Country: country,
|
|
||||||
Locality: locality,
|
|
||||||
PostalCode: postalCode,
|
|
||||||
Region: region,
|
|
||||||
StreetAddress: streetAddress,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,11 +16,11 @@ const (
|
|||||||
type HumanAddressChangedEvent struct {
|
type HumanAddressChangedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
Country string `json:"country,omitempty"`
|
Country *string `json:"country,omitempty"`
|
||||||
Locality string `json:"locality,omitempty"`
|
Locality *string `json:"locality,omitempty"`
|
||||||
PostalCode string `json:"postalCode,omitempty"`
|
PostalCode *string `json:"postalCode,omitempty"`
|
||||||
Region string `json:"region,omitempty"`
|
Region *string `json:"region,omitempty"`
|
||||||
StreetAddress string `json:"streetAddress,omitempty"`
|
StreetAddress *string `json:"streetAddress,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *HumanAddressChangedEvent) Data() interface{} {
|
func (e *HumanAddressChangedEvent) Data() interface{} {
|
||||||
|
@ -20,14 +20,14 @@ const (
|
|||||||
HumanPasswordCheckFailedType = passwordEventPrefix + "check.failed"
|
HumanPasswordCheckFailedType = passwordEventPrefix + "check.failed"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HumanPasswordChangedChangedEvent struct {
|
type HumanPasswordChangedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
Secret *crypto.CryptoValue `json:"secret,omitempty"`
|
Secret *crypto.CryptoValue `json:"secret,omitempty"`
|
||||||
ChangeRequired bool `json:"changeRequired,omitempty"`
|
ChangeRequired bool `json:"changeRequired"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *HumanPasswordChangedChangedEvent) Data() interface{} {
|
func (e *HumanPasswordChangedEvent) Data() interface{} {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,8 +35,8 @@ func NewHumanPasswordChangedEvent(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
secret *crypto.CryptoValue,
|
secret *crypto.CryptoValue,
|
||||||
changeRequired bool,
|
changeRequired bool,
|
||||||
) *HumanPasswordChangedChangedEvent {
|
) *HumanPasswordChangedEvent {
|
||||||
return &HumanPasswordChangedChangedEvent{
|
return &HumanPasswordChangedEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
HumanPasswordChangedType,
|
HumanPasswordChangedType,
|
||||||
@ -47,7 +47,7 @@ func NewHumanPasswordChangedEvent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func HumanPasswordChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
func HumanPasswordChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||||
humanAdded := &HumanPasswordChangedChangedEvent{
|
humanAdded := &HumanPasswordChangedEvent{
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(event.Data, humanAdded)
|
err := json.Unmarshal(event.Data, humanAdded)
|
||||||
|
@ -18,19 +18,20 @@ const (
|
|||||||
type HumanProfileChangedEvent struct {
|
type HumanProfileChangedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
FirstName string `json:"firstName,omitempty"`
|
FirstName string `json:"firstName,omitempty"`
|
||||||
LastName string `json:"lastName,omitempty"`
|
LastName string `json:"lastName,omitempty"`
|
||||||
NickName string `json:"nickName,omitempty"`
|
NickName *string `json:"nickName,omitempty"`
|
||||||
DisplayName string `json:"displayName,omitempty"`
|
DisplayName *string `json:"displayName,omitempty"`
|
||||||
PreferredLanguage language.Tag `json:"preferredLanguage,omitempty"`
|
PreferredLanguage *language.Tag `json:"preferredLanguage,omitempty"`
|
||||||
Gender domain.Gender `json:"gender,omitempty"`
|
Gender *domain.Gender `json:"gender,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *HumanProfileChangedEvent) Data() interface{} {
|
func (e *HumanProfileChangedEvent) Data() interface{} {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHumanProfileChangedEvent(ctx context.Context) *HumanProfileChangedEvent {
|
func NewHumanProfileChangedEvent(
|
||||||
|
ctx context.Context) *HumanProfileChangedEvent {
|
||||||
return &HumanProfileChangedEvent{
|
return &HumanProfileChangedEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
|
@ -61,8 +61,8 @@ type MachineChangedEvent struct {
|
|||||||
|
|
||||||
UserName string `json:"userName"`
|
UserName string `json:"userName"`
|
||||||
|
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
Description string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *MachineChangedEvent) Data() interface{} {
|
func (e *MachineChangedEvent) Data() interface{} {
|
||||||
|
@ -190,8 +190,8 @@ func NewUserV1PasswordChangedEvent(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
secret *crypto.CryptoValue,
|
secret *crypto.CryptoValue,
|
||||||
changeRequired bool,
|
changeRequired bool,
|
||||||
) *HumanPasswordChangedChangedEvent {
|
) *HumanPasswordChangedEvent {
|
||||||
return &HumanPasswordChangedChangedEvent{
|
return &HumanPasswordChangedEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
UserV1PasswordChangedType,
|
UserV1PasswordChangedType,
|
||||||
@ -360,24 +360,12 @@ func NewUserV1PhoneCodeSentEvent(ctx context.Context) *HumanPhoneCodeSentEvent {
|
|||||||
|
|
||||||
func NewUserV1ProfileChangedEvent(
|
func NewUserV1ProfileChangedEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
firstName,
|
|
||||||
lastName,
|
|
||||||
nickName,
|
|
||||||
displayName string,
|
|
||||||
preferredLanguage language.Tag,
|
|
||||||
gender domain.Gender,
|
|
||||||
) *HumanProfileChangedEvent {
|
) *HumanProfileChangedEvent {
|
||||||
return &HumanProfileChangedEvent{
|
return &HumanProfileChangedEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
UserV1ProfileChangedType,
|
UserV1ProfileChangedType,
|
||||||
),
|
),
|
||||||
FirstName: firstName,
|
|
||||||
LastName: lastName,
|
|
||||||
NickName: nickName,
|
|
||||||
DisplayName: displayName,
|
|
||||||
PreferredLanguage: preferredLanguage,
|
|
||||||
Gender: gender,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,11 +382,6 @@ func NewUserV1AddressChangedEvent(
|
|||||||
ctx,
|
ctx,
|
||||||
UserV1AddressChangedType,
|
UserV1AddressChangedType,
|
||||||
),
|
),
|
||||||
Country: country,
|
|
||||||
Locality: locality,
|
|
||||||
PostalCode: postalCode,
|
|
||||||
Region: region,
|
|
||||||
StreetAddress: streetAddress,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1842,6 +1842,7 @@ message MachineView {
|
|||||||
message UpdateMachineRequest {
|
message UpdateMachineRequest {
|
||||||
string id = 1 [(validate.rules).string.min_len = 1];
|
string id = 1 [(validate.rules).string.min_len = 1];
|
||||||
string description = 2 [(validate.rules).string.max_len = 500];
|
string description = 2 [(validate.rules).string.max_len = 500];
|
||||||
|
string name = 3 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
}
|
}
|
||||||
|
|
||||||
message AddMachineKeyRequest {
|
message AddMachineKeyRequest {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user