mirror of
https://github.com/zitadel/zitadel.git
synced 2025-07-15 11:48:36 +00:00
188 lines
5.8 KiB
Go
188 lines
5.8 KiB
Go
![]() |
package user
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"io"
|
||
|
|
||
|
"golang.org/x/text/language"
|
||
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||
|
|
||
|
"github.com/zitadel/zitadel/internal/command"
|
||
|
"github.com/zitadel/zitadel/internal/domain"
|
||
|
"github.com/zitadel/zitadel/internal/zerrors"
|
||
|
legacyobject "github.com/zitadel/zitadel/pkg/grpc/object/v2"
|
||
|
"github.com/zitadel/zitadel/pkg/grpc/user/v2"
|
||
|
)
|
||
|
|
||
|
func (s *Server) createUserTypeHuman(ctx context.Context, humanPb *user.CreateUserRequest_Human, orgId string, userName, userId *string) (*user.CreateUserResponse, error) {
|
||
|
addHumanPb := &user.AddHumanUserRequest{
|
||
|
Username: userName,
|
||
|
UserId: userId,
|
||
|
Organization: &legacyobject.Organization{
|
||
|
Org: &legacyobject.Organization_OrgId{OrgId: orgId},
|
||
|
},
|
||
|
Profile: humanPb.Profile,
|
||
|
Email: humanPb.Email,
|
||
|
Phone: humanPb.Phone,
|
||
|
IdpLinks: humanPb.IdpLinks,
|
||
|
TotpSecret: humanPb.TotpSecret,
|
||
|
}
|
||
|
switch pwType := humanPb.GetPasswordType().(type) {
|
||
|
case *user.CreateUserRequest_Human_HashedPassword:
|
||
|
addHumanPb.PasswordType = &user.AddHumanUserRequest_HashedPassword{
|
||
|
HashedPassword: pwType.HashedPassword,
|
||
|
}
|
||
|
case *user.CreateUserRequest_Human_Password:
|
||
|
addHumanPb.PasswordType = &user.AddHumanUserRequest_Password{
|
||
|
Password: pwType.Password,
|
||
|
}
|
||
|
default:
|
||
|
// optional password is not set
|
||
|
}
|
||
|
newHuman, err := AddUserRequestToAddHuman(addHumanPb)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
if err = s.command.AddUserHuman(
|
||
|
ctx,
|
||
|
orgId,
|
||
|
newHuman,
|
||
|
false,
|
||
|
s.userCodeAlg,
|
||
|
); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return &user.CreateUserResponse{
|
||
|
Id: newHuman.ID,
|
||
|
CreationDate: timestamppb.New(newHuman.Details.EventDate),
|
||
|
EmailCode: newHuman.EmailCode,
|
||
|
PhoneCode: newHuman.PhoneCode,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func (s *Server) updateUserTypeHuman(ctx context.Context, humanPb *user.UpdateUserRequest_Human, userId string, userName *string) (*user.UpdateUserResponse, error) {
|
||
|
cmd, err := updateHumanUserToCommand(userId, userName, humanPb)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
if err = s.command.ChangeUserHuman(ctx, cmd, s.userCodeAlg); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return &user.UpdateUserResponse{
|
||
|
ChangeDate: timestamppb.New(cmd.Details.EventDate),
|
||
|
EmailCode: cmd.EmailCode,
|
||
|
PhoneCode: cmd.PhoneCode,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func updateHumanUserToCommand(userId string, userName *string, human *user.UpdateUserRequest_Human) (*command.ChangeHuman, error) {
|
||
|
phone := human.GetPhone()
|
||
|
if phone != nil && phone.Phone == "" && phone.GetVerification() != nil {
|
||
|
return nil, zerrors.ThrowInvalidArgument(nil, "USERv2-4f3d6", "Errors.User.Phone.VerifyingRemovalIsNotSupported")
|
||
|
}
|
||
|
email, err := setHumanEmailToEmail(human.Email, userId)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return &command.ChangeHuman{
|
||
|
ID: userId,
|
||
|
Username: userName,
|
||
|
Profile: SetHumanProfileToProfile(human.Profile),
|
||
|
Email: email,
|
||
|
Phone: setHumanPhoneToPhone(human.Phone, true),
|
||
|
Password: setHumanPasswordToPassword(human.Password),
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func updateHumanUserRequestToChangeHuman(req *user.UpdateHumanUserRequest) (*command.ChangeHuman, error) {
|
||
|
email, err := setHumanEmailToEmail(req.Email, req.GetUserId())
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
changeHuman := &command.ChangeHuman{
|
||
|
ID: req.GetUserId(),
|
||
|
Username: req.Username,
|
||
|
Email: email,
|
||
|
Phone: setHumanPhoneToPhone(req.Phone, false),
|
||
|
Password: setHumanPasswordToPassword(req.Password),
|
||
|
}
|
||
|
if profile := req.GetProfile(); profile != nil {
|
||
|
var firstName *string
|
||
|
if profile.GivenName != "" {
|
||
|
firstName = &profile.GivenName
|
||
|
}
|
||
|
var lastName *string
|
||
|
if profile.FamilyName != "" {
|
||
|
lastName = &profile.FamilyName
|
||
|
}
|
||
|
changeHuman.Profile = SetHumanProfileToProfile(&user.UpdateUserRequest_Human_Profile{
|
||
|
GivenName: firstName,
|
||
|
FamilyName: lastName,
|
||
|
NickName: profile.NickName,
|
||
|
DisplayName: profile.DisplayName,
|
||
|
PreferredLanguage: profile.PreferredLanguage,
|
||
|
Gender: profile.Gender,
|
||
|
})
|
||
|
}
|
||
|
return changeHuman, nil
|
||
|
}
|
||
|
|
||
|
func SetHumanProfileToProfile(profile *user.UpdateUserRequest_Human_Profile) *command.Profile {
|
||
|
if profile == nil {
|
||
|
return nil
|
||
|
}
|
||
|
return &command.Profile{
|
||
|
FirstName: profile.GivenName,
|
||
|
LastName: profile.FamilyName,
|
||
|
NickName: profile.NickName,
|
||
|
DisplayName: profile.DisplayName,
|
||
|
PreferredLanguage: ifNotNilPtr(profile.PreferredLanguage, language.Make),
|
||
|
Gender: ifNotNilPtr(profile.Gender, genderToDomain),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func setHumanEmailToEmail(email *user.SetHumanEmail, userID string) (*command.Email, error) {
|
||
|
if email == nil {
|
||
|
return nil, nil
|
||
|
}
|
||
|
var urlTemplate string
|
||
|
if email.GetSendCode() != nil && email.GetSendCode().UrlTemplate != nil {
|
||
|
urlTemplate = *email.GetSendCode().UrlTemplate
|
||
|
if err := domain.RenderConfirmURLTemplate(io.Discard, urlTemplate, userID, "code", "orgID"); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
}
|
||
|
return &command.Email{
|
||
|
Address: domain.EmailAddress(email.Email),
|
||
|
Verified: email.GetIsVerified(),
|
||
|
ReturnCode: email.GetReturnCode() != nil,
|
||
|
URLTemplate: urlTemplate,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func setHumanPhoneToPhone(phone *user.SetHumanPhone, withRemove bool) *command.Phone {
|
||
|
if phone == nil {
|
||
|
return nil
|
||
|
}
|
||
|
number := phone.GetPhone()
|
||
|
return &command.Phone{
|
||
|
Number: domain.PhoneNumber(number),
|
||
|
Verified: phone.GetIsVerified(),
|
||
|
ReturnCode: phone.GetReturnCode() != nil,
|
||
|
Remove: withRemove && number == "",
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func setHumanPasswordToPassword(password *user.SetPassword) *command.Password {
|
||
|
if password == nil {
|
||
|
return nil
|
||
|
}
|
||
|
return &command.Password{
|
||
|
PasswordCode: password.GetVerificationCode(),
|
||
|
OldPassword: password.GetCurrentPassword(),
|
||
|
Password: password.GetPassword().GetPassword(),
|
||
|
EncodedPasswordHash: password.GetHashedPassword().GetHash(),
|
||
|
ChangeRequired: password.GetPassword().GetChangeRequired() || password.GetHashedPassword().GetChangeRequired(),
|
||
|
}
|
||
|
}
|