chore: move the go code into a subfolder

This commit is contained in:
Florian Forster
2025-08-05 15:20:32 -07:00
parent 4ad22ba456
commit cd2921de26
2978 changed files with 373 additions and 300 deletions

View File

@@ -0,0 +1,13 @@
package model
import es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
type Address struct {
es_models.ObjectRoot
Country string
Locality string
PostalCode string
Region string
StreetAddress string
}

View File

@@ -0,0 +1,41 @@
package model
import (
"time"
"github.com/zitadel/zitadel/internal/crypto"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
)
type Email struct {
es_models.ObjectRoot
EmailAddress string
IsEmailVerified bool
}
type EmailCode struct {
es_models.ObjectRoot
Code *crypto.CryptoValue
Expiry time.Duration
}
func (e *Email) GenerateEmailCodeIfNeeded(emailGenerator crypto.Generator) (*EmailCode, error) {
var emailCode *EmailCode
if e.IsEmailVerified {
return emailCode, nil
}
emailCode = new(EmailCode)
return emailCode, emailCode.GenerateEmailCode(emailGenerator)
}
func (code *EmailCode) GenerateEmailCode(emailGenerator crypto.Generator) error {
emailCodeCrypto, _, err := crypto.NewCode(emailGenerator)
if err != nil {
return err
}
code.Code = emailCodeCrypto
code.Expiry = emailGenerator.Expiry()
return nil
}

View File

@@ -0,0 +1,17 @@
package model
import (
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
)
type ExternalIDP struct {
es_models.ObjectRoot
IDPConfigID string
UserID string
DisplayName string
}
func (idp *ExternalIDP) IsValid() bool {
return idp.AggregateID != "" && idp.IDPConfigID != "" && idp.UserID != ""
}

View File

@@ -0,0 +1,69 @@
package model
import (
"time"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/zerrors"
)
type ExternalIDPView struct {
UserID string
IDPConfigID string
ExternalUserID string
IDPName string
UserDisplayName string
CreationDate time.Time
ChangeDate time.Time
ResourceOwner string
Sequence uint64
}
type ExternalIDPSearchRequest struct {
Offset uint64
Limit uint64
SortingColumn ExternalIDPSearchKey
Asc bool
Queries []*ExternalIDPSearchQuery
}
type ExternalIDPSearchKey int32
const (
ExternalIDPSearchKeyUnspecified ExternalIDPSearchKey = iota
ExternalIDPSearchKeyExternalUserID
ExternalIDPSearchKeyUserID
ExternalIDPSearchKeyIdpConfigID
ExternalIDPSearchKeyResourceOwner
ExternalIDPSearchKeyInstanceID
ExternalIDPSearchKeyOwnerRemoved
)
type ExternalIDPSearchQuery struct {
Key ExternalIDPSearchKey
Method domain.SearchMethod
Value interface{}
}
type ExternalIDPSearchResponse struct {
Offset uint64
Limit uint64
TotalResult uint64
Result []*ExternalIDPView
Sequence uint64
Timestamp time.Time
}
func (r *ExternalIDPSearchRequest) EnsureLimit(limit uint64) error {
if r.Limit > limit {
return zerrors.ThrowInvalidArgument(nil, "SEARCH-3n8fM", "Errors.Limit.ExceedsDefault")
}
if r.Limit == 0 {
r.Limit = limit
}
return nil
}
func (r *ExternalIDPSearchRequest) AppendUserQuery(userID string) {
r.Queries = append(r.Queries, &ExternalIDPSearchQuery{Key: ExternalIDPSearchKeyUserID, Method: domain.SearchMethodEquals, Value: userID})
}

View File

@@ -0,0 +1,59 @@
package model
import (
"time"
"github.com/zitadel/zitadel/internal/domain"
)
type NotifyUser struct {
ID string
CreationDate time.Time
ChangeDate time.Time
ResourceOwner string
UserName string
PreferredLoginName string
LoginNames []string
FirstName string
LastName string
NickName string
DisplayName string
PreferredLanguage string
Gender Gender
LastEmail string
VerifiedEmail string
LastPhone string
VerifiedPhone string
PasswordSet bool
Sequence uint64
}
type NotifyUserSearchRequest struct {
Offset uint64
Limit uint64
SortingColumn NotifyUserSearchKey
Asc bool
Queries []*NotifyUserSearchQuery
}
type NotifyUserSearchKey int32
const (
NotifyUserSearchKeyUnspecified NotifyUserSearchKey = iota
NotifyUserSearchKeyUserID
NotifyUserSearchKeyResourceOwner
NotifyUserSearchKeyInstanceID
)
type NotifyUserSearchQuery struct {
Key NotifyUserSearchKey
Method domain.SearchMethod
Value string
}
type NotifyUserSearchResponse struct {
Offset uint64
Limit uint64
TotalResult uint64
Result []*UserView
}

View File

@@ -0,0 +1,24 @@
package model
type MFAState int32
const (
MFAStateUnspecified MFAState = iota
MFAStateNotReady
MFAStateReady
)
type MultiFactor struct {
Type MFAType
State MFAState
Attribute string
ID string
}
type MFAType int32
const (
MFATypeUnspecified MFAType = iota
MFATypeOTP
MFATypeU2F
)

View File

@@ -0,0 +1,35 @@
package model
import (
"time"
"github.com/zitadel/zitadel/internal/crypto"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
)
type Password struct {
es_models.ObjectRoot
SecretString string
SecretCrypto *crypto.CryptoValue
ChangeRequired bool
}
type PasswordCode struct {
es_models.ObjectRoot
Code *crypto.CryptoValue
Expiry time.Duration
NotificationType NotificationType
}
type NotificationType int32
const (
NotificationTypeEmail NotificationType = iota
NotificationTypeSms
)
func (p *Password) IsValid() bool {
return p.AggregateID != "" && p.SecretString != ""
}

View File

@@ -0,0 +1,45 @@
package model
import (
"time"
"github.com/zitadel/zitadel/internal/crypto"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
)
const (
defaultRegion = "CH"
)
type Phone struct {
es_models.ObjectRoot
PhoneNumber string
IsPhoneVerified bool
}
type PhoneCode struct {
es_models.ObjectRoot
Code *crypto.CryptoValue
Expiry time.Duration
}
func (p *Phone) GeneratePhoneCodeIfNeeded(phoneGenerator crypto.Generator) (*PhoneCode, error) {
var phoneCode *PhoneCode
if p.IsPhoneVerified {
return phoneCode, nil
}
phoneCode = new(PhoneCode)
return phoneCode, phoneCode.GeneratePhoneCode(phoneGenerator)
}
func (code *PhoneCode) GeneratePhoneCode(phoneGenerator crypto.Generator) error {
phoneCodeCrypto, _, err := crypto.NewCode(phoneGenerator)
if err != nil {
return err
}
code.Code = phoneCodeCrypto
code.Expiry = phoneGenerator.Expiry()
return nil
}

View File

@@ -0,0 +1,29 @@
package model
import (
"golang.org/x/text/language"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
)
type Profile struct {
es_models.ObjectRoot
FirstName string
LastName string
NickName string
DisplayName string
PreferredLanguage language.Tag
Gender Gender
PreferredLoginName string
LoginNames []string
AvatarKey string
}
func (p *Profile) IsValid() bool {
return p.FirstName != "" && p.LastName != ""
}
func (p *Profile) SetNamesAsDisplayname() {
p.DisplayName = p.FirstName + " " + p.LastName
}

View File

@@ -0,0 +1,19 @@
package model
import (
"time"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
)
type RefreshToken struct {
es_models.ObjectRoot
TokenID string
ApplicationID string
UserAgentID string
Audience []string
Expiration time.Time
Scopes []string
PreferredLanguage string
}

View File

@@ -0,0 +1,73 @@
package model
import (
"time"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/zerrors"
)
type RefreshTokenView struct {
ID string
CreationDate time.Time
ChangeDate time.Time
ResourceOwner string
UserID string
ClientID string
UserAgentID string
AuthMethodsReferences []string
Audience []string
AuthTime time.Time
IdleExpiration time.Time
Expiration time.Time
Scopes []string
Sequence uint64
Token string
Actor *domain.TokenActor
}
type RefreshTokenSearchRequest struct {
Offset uint64
Limit uint64
SortingColumn RefreshTokenSearchKey
Asc bool
Queries []*RefreshTokenSearchQuery
}
type RefreshTokenSearchKey int32
const (
RefreshTokenSearchKeyUnspecified RefreshTokenSearchKey = iota
RefreshTokenSearchKeyRefreshTokenID
RefreshTokenSearchKeyUserID
RefreshTokenSearchKeyApplicationID
RefreshTokenSearchKeyUserAgentID
RefreshTokenSearchKeyExpiration
RefreshTokenSearchKeyResourceOwner
RefreshTokenSearchKeyInstanceID
)
type RefreshTokenSearchQuery struct {
Key RefreshTokenSearchKey
Method domain.SearchMethod
Value interface{}
}
type RefreshTokenSearchResponse struct {
Offset uint64
Limit uint64
TotalResult uint64
Sequence uint64
Timestamp time.Time
Result []*RefreshTokenView
}
func (r *RefreshTokenSearchRequest) EnsureLimit(limit uint64) error {
if r.Limit > limit {
return zerrors.ThrowInvalidArgument(nil, "SEARCH-M0fse", "Errors.Limit.ExceedsDefault")
}
if r.Limit == 0 {
r.Limit = limit
}
return nil
}

View File

@@ -0,0 +1,19 @@
package model
import (
"time"
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
)
type Token struct {
es_models.ObjectRoot
TokenID string
ApplicationID string
UserAgentID string
Audience []string
Expiration time.Time
Scopes []string
PreferredLanguage string
}

View File

@@ -0,0 +1,72 @@
package model
import (
"time"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/zerrors"
)
type TokenView struct {
ID string
CreationDate time.Time
ChangeDate time.Time
ResourceOwner string
UserID string
ApplicationID string
UserAgentID string
Audience []string
Expiration time.Time
Scopes []string
Sequence uint64
PreferredLanguage string
RefreshTokenID string
IsPAT bool
Reason domain.TokenReason
Actor *domain.TokenActor
}
type TokenSearchRequest struct {
Offset uint64
Limit uint64
SortingColumn TokenSearchKey
Asc bool
Queries []*TokenSearchQuery
}
type TokenSearchKey int32
const (
TokenSearchKeyUnspecified TokenSearchKey = iota
TokenSearchKeyTokenID
TokenSearchKeyUserID
TokenSearchKeyRefreshTokenID
TokenSearchKeyApplicationID
TokenSearchKeyUserAgentID
TokenSearchKeyExpiration
TokenSearchKeyResourceOwner
TokenSearchKeyInstanceID
)
type TokenSearchQuery struct {
Key TokenSearchKey
Method domain.SearchMethod
Value interface{}
}
type TokenSearchResponse struct {
Offset uint64
Limit uint64
TotalResult uint64
Result []*Token
}
func (r *TokenSearchRequest) EnsureLimit(limit uint64) error {
if r.Limit > limit {
return zerrors.ThrowInvalidArgument(nil, "SEARCH-M0fse", "Errors.Limit.ExceedsDefault")
}
if r.Limit == 0 {
r.Limit = limit
}
return nil
}

View File

@@ -0,0 +1,21 @@
package model
import (
"google.golang.org/protobuf/types/known/timestamppb"
)
type UserChanges struct {
Changes []*UserChange
LastSequence uint64
}
type UserChange struct {
ChangeDate *timestamppb.Timestamp `json:"changeDate,omitempty"`
EventType string `json:"eventType,omitempty"`
Sequence uint64 `json:"sequence,omitempty"`
ModifierID string `json:"modifierUser,omitempty"`
ModifierName string `json:"-"`
ModifierLoginName string `json:"-"`
ModifierAvatarURL string `json:"-"`
Data interface{} `json:"data,omitempty"`
}

View File

@@ -0,0 +1,96 @@
package model
import (
"time"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/zerrors"
)
type UserMembershipView struct {
UserID string
MemberType MemberType
AggregateID string
//ObjectID differs from aggregate id if obejct is sub of an aggregate
ObjectID string
Roles []string
DisplayName string
CreationDate time.Time
ChangeDate time.Time
ResourceOwner string
ResourceOwnerName string
Sequence uint64
}
type MemberType int32
const (
MemberTypeUnspecified MemberType = iota
MemberTypeOrganisation
MemberTypeProject
MemberTypeProjectGrant
MemberTypeIam
)
type UserMembershipSearchRequest struct {
Offset uint64
Limit uint64
SortingColumn UserMembershipSearchKey
Asc bool
Queries []*UserMembershipSearchQuery
}
type UserMembershipSearchKey int32
const (
UserMembershipSearchKeyUnspecified UserMembershipSearchKey = iota
UserMembershipSearchKeyUserID
UserMembershipSearchKeyMemberType
UserMembershipSearchKeyAggregateID
UserMembershipSearchKeyObjectID
UserMembershipSearchKeyResourceOwner
UserMembershipSearchKeyInstanceID
)
type UserMembershipSearchQuery struct {
Key UserMembershipSearchKey
Method domain.SearchMethod
Value interface{}
}
type UserMembershipSearchResponse struct {
Offset uint64
Limit uint64
TotalResult uint64
Result []*UserMembershipView
Sequence uint64
Timestamp time.Time
}
func (r *UserMembershipSearchRequest) EnsureLimit(limit uint64) error {
if r.Limit > limit {
return zerrors.ThrowInvalidArgument(nil, "SEARCH-288fJ", "Errors.Limit.ExceedsDefault")
}
if r.Limit == 0 {
r.Limit = limit
}
return nil
}
func (r *UserMembershipSearchRequest) GetSearchQuery(key UserMembershipSearchKey) (int, *UserMembershipSearchQuery) {
for i, q := range r.Queries {
if q.Key == key {
return i, q
}
}
return -1, nil
}
func (r *UserMembershipSearchRequest) AppendResourceOwnerAndIamQuery(orgID, iamID string) {
r.Queries = append(r.Queries, &UserMembershipSearchQuery{Key: UserMembershipSearchKeyResourceOwner, Method: domain.SearchMethodIsOneOf, Value: []string{orgID, iamID}})
}
func (r *UserMembershipSearchRequest) AppendUserIDQuery(userID string) {
r.Queries = append(r.Queries, &UserMembershipSearchQuery{Key: UserMembershipSearchKeyUserID, Method: domain.SearchMethodEquals, Value: userID})
}

View File

@@ -0,0 +1,74 @@
package model
import (
"time"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/zerrors"
)
type UserSessionView struct {
CreationDate time.Time
ChangeDate time.Time
State domain.UserSessionState
ResourceOwner string
UserAgentID string
UserID string
UserName string
LoginName string
DisplayName string
AvatarKey string
SelectedIDPConfigID string
PasswordVerification time.Time
PasswordlessVerification time.Time
ExternalLoginVerification time.Time
SecondFactorVerification time.Time
SecondFactorVerificationType domain.MFAType
MultiFactorVerification time.Time
MultiFactorVerificationType domain.MFAType
Sequence uint64
ID string
}
type UserSessionSearchRequest struct {
Offset uint64
Limit uint64
SortingColumn UserSessionSearchKey
Asc bool
Queries []*UserSessionSearchQuery
}
type UserSessionSearchKey int32
const (
UserSessionSearchKeyUnspecified UserSessionSearchKey = iota
UserSessionSearchKeyUserAgentID
UserSessionSearchKeyUserID
UserSessionSearchKeyState
UserSessionSearchKeyResourceOwner
UserSessionSearchKeyInstanceID
UserSessionSearchKeyOwnerRemoved
)
type UserSessionSearchQuery struct {
Key UserSessionSearchKey
Method domain.SearchMethod
Value interface{}
}
type UserSessionSearchResponse struct {
Offset uint64
Limit uint64
TotalResult uint64
Result []*UserSessionView
}
func (r *UserSessionSearchRequest) EnsureLimit(limit uint64) error {
if r.Limit > limit {
return zerrors.ThrowInvalidArgument(nil, "SEARCH-27ifs", "Errors.Limit.ExceedsDefault")
}
if r.Limit == 0 {
r.Limit = limit
}
return nil
}

View File

@@ -0,0 +1,310 @@
package model
import (
"time"
"golang.org/x/text/language"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
"github.com/zitadel/zitadel/internal/zerrors"
)
type UserView struct {
ID string
UserName string
CreationDate time.Time
ChangeDate time.Time
State UserState
Sequence uint64
ResourceOwner string
LastLogin time.Time
PreferredLoginName string
LoginNames []string
*MachineView
*HumanView
}
type HumanView struct {
PasswordSet bool
PasswordInitRequired bool
PasswordChangeRequired bool
UsernameChangeRequired bool
PasswordChanged time.Time
FirstName string
LastName string
NickName string
DisplayName string
AvatarKey string
PreferredLanguage string
Gender Gender
Email string
IsEmailVerified bool
VerifiedEmail string
Phone string
IsPhoneVerified bool
Country string
Locality string
PostalCode string
Region string
StreetAddress string
OTPState MFAState
OTPSMSAdded bool
OTPEmailAdded bool
U2FTokens []*WebAuthNView
PasswordlessTokens []*WebAuthNView
MFAMaxSetUp domain.MFALevel
MFAInitSkipped time.Time
InitRequired bool
PasswordlessInitRequired bool
}
type WebAuthNView struct {
TokenID string
Name string
State MFAState
}
type MachineView struct {
LastKeyAdded time.Time
Name string
Description string
}
type UserSearchRequest struct {
Offset uint64
Limit uint64
SortingColumn UserSearchKey
Asc bool
Queries []*UserSearchQuery
}
type UserSearchKey int32
const (
UserSearchKeyUnspecified UserSearchKey = iota
UserSearchKeyUserID
UserSearchKeyUserName
UserSearchKeyFirstName
UserSearchKeyLastName
UserSearchKeyNickName
UserSearchKeyDisplayName
UserSearchKeyEmail
UserSearchKeyState
UserSearchKeyResourceOwner
UserSearchKeyLoginNames
UserSearchKeyType
UserSearchKeyPreferredLoginName
UserSearchKeyInstanceID
UserSearchOwnerRemoved
)
type UserSearchQuery struct {
Key UserSearchKey
Method domain.SearchMethod
Value interface{}
}
type UserSearchResponse struct {
Offset uint64
Limit uint64
TotalResult uint64
Result []*UserView
Sequence uint64
Timestamp time.Time
}
type UserState int32
const (
UserStateUnspecified UserState = iota
UserStateActive
UserStateInactive
UserStateDeleted
UserStateLocked
UserStateSuspend
UserStateInitial
)
type Gender int32
const (
GenderUnspecified Gender = iota
GenderFemale
GenderMale
GenderDiverse
)
func (r *UserSearchRequest) EnsureLimit(limit uint64) error {
if r.Limit > limit {
return zerrors.ThrowInvalidArgument(nil, "SEARCH-zz62F", "Errors.Limit.ExceedsDefault")
}
if r.Limit == 0 {
r.Limit = limit
}
return nil
}
func (r *UserSearchRequest) AppendMyOrgQuery(orgID string) {
r.Queries = append(r.Queries, &UserSearchQuery{Key: UserSearchKeyResourceOwner, Method: domain.SearchMethodEquals, Value: orgID})
}
func (u *UserView) MFATypesSetupPossible(level domain.MFALevel, policy *domain.LoginPolicy) []domain.MFAType {
types := make([]domain.MFAType, 0)
switch level {
default:
fallthrough
case domain.MFALevelSecondFactor:
if policy.HasSecondFactors() {
for _, mfaType := range policy.SecondFactors {
switch mfaType {
case domain.SecondFactorTypeTOTP:
if u.OTPState != MFAStateReady {
types = append(types, domain.MFATypeTOTP)
}
case domain.SecondFactorTypeU2F:
types = append(types, domain.MFATypeU2F)
case domain.SecondFactorTypeOTPSMS:
if !u.OTPSMSAdded {
types = append(types, domain.MFATypeOTPSMS)
}
case domain.SecondFactorTypeOTPEmail:
if !u.OTPEmailAdded {
types = append(types, domain.MFATypeOTPEmail)
}
}
}
}
}
return types
}
func (u *UserView) MFATypesAllowed(level domain.MFALevel, policy *domain.LoginPolicy, isInternalAuthentication bool) ([]domain.MFAType, bool) {
types := make([]domain.MFAType, 0)
required := true
switch level {
default:
required = domain.RequiresMFA(policy.ForceMFA, policy.ForceMFALocalOnly, isInternalAuthentication)
fallthrough
case domain.MFALevelSecondFactor:
if policy.HasSecondFactors() {
for _, mfaType := range policy.SecondFactors {
switch mfaType {
case domain.SecondFactorTypeTOTP:
if u.OTPState == MFAStateReady {
types = append(types, domain.MFATypeTOTP)
}
case domain.SecondFactorTypeU2F:
if u.IsU2FReady() {
types = append(types, domain.MFATypeU2F)
}
case domain.SecondFactorTypeOTPSMS:
if u.OTPSMSAdded {
types = append(types, domain.MFATypeOTPSMS)
}
case domain.SecondFactorTypeOTPEmail:
if u.OTPEmailAdded {
types = append(types, domain.MFATypeOTPEmail)
}
}
}
}
}
return types, required
}
func (u *UserView) IsU2FReady() bool {
for _, token := range u.U2FTokens {
if token.State == MFAStateReady {
return true
}
}
return false
}
func (u *UserView) IsPasswordlessReady() bool {
for _, token := range u.PasswordlessTokens {
if token.State == MFAStateReady {
return true
}
}
return false
}
func (u *UserView) GetProfile() (*Profile, error) {
if u.HumanView == nil {
return nil, zerrors.ThrowPreconditionFailed(nil, "MODEL-WLTce", "Errors.User.NotHuman")
}
return &Profile{
ObjectRoot: models.ObjectRoot{
AggregateID: u.ID,
Sequence: u.Sequence,
ResourceOwner: u.ResourceOwner,
CreationDate: u.CreationDate,
ChangeDate: u.ChangeDate,
},
FirstName: u.FirstName,
LastName: u.LastName,
NickName: u.NickName,
DisplayName: u.DisplayName,
PreferredLanguage: language.Make(u.PreferredLanguage),
Gender: u.Gender,
PreferredLoginName: u.PreferredLoginName,
LoginNames: u.LoginNames,
AvatarKey: u.AvatarKey,
}, nil
}
func (u *UserView) GetPhone() (*Phone, error) {
if u.HumanView == nil {
return nil, zerrors.ThrowPreconditionFailed(nil, "MODEL-him4a", "Errors.User.NotHuman")
}
return &Phone{
ObjectRoot: models.ObjectRoot{
AggregateID: u.ID,
Sequence: u.Sequence,
ResourceOwner: u.ResourceOwner,
CreationDate: u.CreationDate,
ChangeDate: u.ChangeDate,
},
PhoneNumber: u.Phone,
IsPhoneVerified: u.IsPhoneVerified,
}, nil
}
func (u *UserView) GetEmail() (*Email, error) {
if u.HumanView == nil {
return nil, zerrors.ThrowPreconditionFailed(nil, "MODEL-PWd6K", "Errors.User.NotHuman")
}
return &Email{
ObjectRoot: models.ObjectRoot{
AggregateID: u.ID,
Sequence: u.Sequence,
ResourceOwner: u.ResourceOwner,
CreationDate: u.CreationDate,
ChangeDate: u.ChangeDate,
},
EmailAddress: u.Email,
IsEmailVerified: u.IsEmailVerified,
}, nil
}
func (u *UserView) GetAddress() (*Address, error) {
if u.HumanView == nil {
return nil, zerrors.ThrowPreconditionFailed(nil, "MODEL-DN61m", "Errors.User.NotHuman")
}
return &Address{
ObjectRoot: models.ObjectRoot{
AggregateID: u.ID,
Sequence: u.Sequence,
ResourceOwner: u.ResourceOwner,
CreationDate: u.CreationDate,
ChangeDate: u.ChangeDate,
},
Country: u.Country,
Locality: u.Locality,
PostalCode: u.PostalCode,
Region: u.Region,
StreetAddress: u.StreetAddress,
}, nil
}