mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-04 23:45:07 +00:00
fix: backend bugs (#1449)
* i18n of compliance problems * fix: return iam member roles * remove u2f/passwordless * u2f/passwordless * fix rest path GetMachineKeyByIDs * fix rest path GetMachineKeyByIDs * fix email mime-type * fix: member preferred login name * machine users in notify * fix api key query * fix: todos grpc api * fix: handle user init state * fix: tests Co-authored-by: fabi <fabienne.gerschwiler@gmail.com>
This commit is contained in:
parent
6b1f7ba333
commit
bd1a3bb6d7
@ -2,8 +2,14 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
org_view "github.com/caos/zitadel/internal/org/repository/view"
|
||||
"github.com/caos/zitadel/internal/user/repository/view"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
|
||||
@ -11,8 +17,10 @@ import (
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
)
|
||||
@ -84,7 +92,7 @@ func (m *IAMMember) Reduce(event *es_models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (m *IAMMember) processIAMMember(event *es_models.Event) (err error) {
|
||||
member := new(iam_model.IAMMemberView)
|
||||
member := new(iam_view_model.IAMMemberView)
|
||||
switch event.Type {
|
||||
case model.IAMMemberAdded:
|
||||
err = member.AppendEvent(event)
|
||||
@ -146,17 +154,25 @@ func (m *IAMMember) processUser(event *es_models.Event) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *IAMMember) fillData(member *iam_model.IAMMemberView) (err error) {
|
||||
func (m *IAMMember) fillData(member *iam_view_model.IAMMemberView) (err error) {
|
||||
user, err := m.getUserByID(member.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.fillUserData(member, user)
|
||||
return nil
|
||||
return m.fillUserData(member, user)
|
||||
}
|
||||
|
||||
func (m *IAMMember) fillUserData(member *iam_model.IAMMemberView, user *view_model.UserView) {
|
||||
func (m *IAMMember) fillUserData(member *iam_view_model.IAMMemberView, user *view_model.UserView) error {
|
||||
org, err := m.getOrgByID(context.Background(), user.ResourceOwner)
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = m.getDefaultOrgIAMPolicy(context.TODO())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
member.UserName = user.UserName
|
||||
member.PreferredLoginName = user.GenerateLoginName(org.GetPrimaryDomain().Domain, policy.UserLoginMustBeDomain)
|
||||
if user.HumanView != nil {
|
||||
member.FirstName = user.FirstName
|
||||
member.LastName = user.LastName
|
||||
@ -166,7 +182,9 @@ func (m *IAMMember) fillUserData(member *iam_model.IAMMemberView, user *view_mod
|
||||
if user.MachineView != nil {
|
||||
member.DisplayName = user.MachineView.Name
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IAMMember) OnError(event *es_models.Event, err error) error {
|
||||
logging.LogWithFields("SPOOL-Ld9ow", "id", event.AggregateID).WithError(err).Warn("something went wrong in iammember handler")
|
||||
return spooler.HandleError(event, err, m.view.GetLatestIAMMemberFailedEvent, m.view.ProcessedIAMMemberFailedEvent, m.view.ProcessedIAMMemberSequence, m.errorCountUntilSkip)
|
||||
@ -208,3 +226,53 @@ func (m *IAMMember) getUserEvents(userID string, sequence uint64) ([]*es_models.
|
||||
|
||||
return m.es.FilterEvents(context.Background(), query)
|
||||
}
|
||||
|
||||
func (u *IAMMember) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := org_view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-3nd7s", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *IAMMember) getDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingIAM, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIAM.DefaultOrgIAMPolicy == nil {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-3Bf7s", "Errors.IAM.OrgIAMPolicy.NotExisting")
|
||||
}
|
||||
return existingIAM.DefaultOrgIAMPolicy, nil
|
||||
}
|
||||
|
||||
func (u *IAMMember) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &iam_es_model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IAMToModel(iam), nil
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
func (s *Server) ListIAMMemberRoles(ctx context.Context, req *admin_pb.ListIAMMemberRolesRequest) (*admin_pb.ListIAMMemberRolesResponse, error) {
|
||||
roles := s.iam.GetIAMMemberRoles()
|
||||
return &admin_pb.ListIAMMemberRolesResponse{
|
||||
Roles: roles,
|
||||
Details: object.ToListDetails(uint64(len(roles)), 0, time.Now()),
|
||||
}, nil
|
||||
}
|
||||
|
@ -67,7 +67,6 @@ func (s *Server) AddMyAuthFactorU2F(ctx context.Context, _ *auth_pb.AddMyAuthFac
|
||||
}
|
||||
return &auth_pb.AddMyAuthFactorU2FResponse{
|
||||
Key: &user_pb.WebAuthNKey{
|
||||
Id: u2f.WebAuthNTokenID,
|
||||
PublicKey: u2f.CredentialCreationData,
|
||||
},
|
||||
Details: object.AddToDetailsPb(
|
||||
@ -91,7 +90,7 @@ func (s *Server) VerifyMyAuthFactorU2F(ctx context.Context, req *auth_pb.VerifyM
|
||||
|
||||
func (s *Server) RemoveMyAuthFactorU2F(ctx context.Context, req *auth_pb.RemoveMyAuthFactorU2FRequest) (*auth_pb.RemoveMyAuthFactorU2FResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
objectDetails, err := s.command.HumanRemovePasswordless(ctx, ctxData.UserID, req.TokenId, ctxData.ResourceOwner)
|
||||
objectDetails, err := s.command.HumanRemoveU2F(ctx, ctxData.UserID, req.TokenId, ctxData.ResourceOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -41,14 +41,13 @@ func (s *Server) SetMyPhone(ctx context.Context, req *auth_pb.SetMyPhoneRequest)
|
||||
|
||||
func (s *Server) VerifyMyPhone(ctx context.Context, req *auth_pb.VerifyMyPhoneRequest) (*auth_pb.VerifyMyPhoneResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
_, err := s.command.VerifyHumanPhone(ctx, ctxData.UserID, req.Code, ctxData.ResourceOwner)
|
||||
objectDetails, err := s.command.VerifyHumanPhone(ctx, ctxData.UserID, req.Code, ctxData.ResourceOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//TODO: response from business
|
||||
return &auth_pb.VerifyMyPhoneResponse{
|
||||
//Details: object.DomainToChangeDetailsPb(objectDetails),
|
||||
Details: object.DomainToChangeDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,7 @@ func IDPProviderTypeModelFromPb(typ idp_pb.IDPOwnerType) iam_model.IDPProviderTy
|
||||
|
||||
func IDPIDQueryToModel(query *idp_pb.IDPIDQuery) *iam_model.IDPConfigSearchQuery {
|
||||
return &iam_model.IDPConfigSearchQuery{
|
||||
Key: iam_model.IDPConfigSearchKeyIdpConfigID, //TODO: whats the difference between idpconfigid and aggregateid search key?
|
||||
Key: iam_model.IDPConfigSearchKeyIdpConfigID,
|
||||
Method: domain.SearchMethodEquals,
|
||||
Value: query.Id,
|
||||
}
|
||||
|
@ -139,7 +139,6 @@ func (s *Server) GenerateOrgDomainValidation(ctx context.Context, req *mgmt_pb.G
|
||||
return &mgmt_pb.GenerateOrgDomainValidationResponse{
|
||||
Token: token,
|
||||
Url: url,
|
||||
//TODO: remove details from proto
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ func AddAPIClientKeyRequestToDomain(key *mgmt_pb.AddAppKeyRequest) *domain.Appli
|
||||
|
||||
func ListAPIClientKeysRequestToModel(req *mgmt_pb.ListAppKeysRequest) (*key_model.AuthNKeySearchRequest, error) {
|
||||
offset, limit, asc := object.ListQueryToModel(req.Query)
|
||||
queries := make([]*key_model.AuthNKeySearchQuery, 2)
|
||||
queries := make([]*key_model.AuthNKeySearchQuery, 0)
|
||||
queries = append(queries, &key_model.AuthNKeySearchQuery{
|
||||
Key: key_model.AuthNKeyObjectID,
|
||||
Method: domain.SearchMethodEquals,
|
||||
|
@ -2,6 +2,7 @@ package management
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
member_grpc "github.com/caos/zitadel/internal/api/grpc/member"
|
||||
@ -106,8 +107,8 @@ func (s *Server) RemoveProjectGrant(ctx context.Context, req *mgmt_pb.RemoveProj
|
||||
func (s *Server) ListProjectGrantMemberRoles(ctx context.Context, req *mgmt_pb.ListProjectGrantMemberRolesRequest) (*mgmt_pb.ListProjectGrantMemberRolesResponse, error) {
|
||||
roles := s.project.GetProjectGrantMemberRoles()
|
||||
return &mgmt_pb.ListProjectGrantMemberRolesResponse{
|
||||
Result: roles,
|
||||
//TODO: metadata
|
||||
Result: roles,
|
||||
Details: object_grpc.ToListDetails(uint64(len(roles)), 0, time.Now()),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,5 @@ func (s *Server) BulkRemoveUserGrant(ctx context.Context, req *mgmt_pb.BulkRemov
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.BulkRemoveUserGrantResponse{
|
||||
//TODO: Do we need details here?
|
||||
}, nil
|
||||
return &mgmt_pb.BulkRemoveUserGrantResponse{}, nil
|
||||
}
|
||||
|
@ -17,13 +17,13 @@ func IAMMembersToPb(members []*iam_model.IAMMemberView) []*member_pb.Member {
|
||||
|
||||
func IAMMemberToPb(m *iam_model.IAMMemberView) *member_pb.Member {
|
||||
return &member_pb.Member{
|
||||
UserId: m.UserID,
|
||||
Roles: m.Roles,
|
||||
// PreferredLoginName: //TODO: not implemented in be
|
||||
Email: m.Email,
|
||||
FirstName: m.FirstName,
|
||||
LastName: m.LastName,
|
||||
DisplayName: m.DisplayName,
|
||||
UserId: m.UserID,
|
||||
Roles: m.Roles,
|
||||
PreferredLoginName: m.PreferredLoginName,
|
||||
Email: m.Email,
|
||||
FirstName: m.FirstName,
|
||||
LastName: m.LastName,
|
||||
DisplayName: m.DisplayName,
|
||||
Details: object.ToViewDetailsPb(
|
||||
m.Sequence,
|
||||
m.CreationDate,
|
||||
|
@ -17,13 +17,13 @@ func OrgMembersToPb(members []*org_model.OrgMemberView) []*member_pb.Member {
|
||||
|
||||
func OrgMemberToPb(m *org_model.OrgMemberView) *member_pb.Member {
|
||||
return &member_pb.Member{
|
||||
UserId: m.UserID,
|
||||
Roles: m.Roles,
|
||||
// PreferredLoginName: //TODO: not implemented in be
|
||||
Email: m.Email,
|
||||
FirstName: m.FirstName,
|
||||
LastName: m.LastName,
|
||||
DisplayName: m.DisplayName,
|
||||
UserId: m.UserID,
|
||||
Roles: m.Roles,
|
||||
PreferredLoginName: m.PreferredLoginName,
|
||||
Email: m.Email,
|
||||
FirstName: m.FirstName,
|
||||
LastName: m.LastName,
|
||||
DisplayName: m.DisplayName,
|
||||
Details: object.ToViewDetailsPb(
|
||||
m.Sequence,
|
||||
m.CreationDate,
|
||||
|
@ -17,13 +17,13 @@ func ProjectGrantMembersToPb(members []*proj_model.ProjectGrantMemberView) []*me
|
||||
|
||||
func ProjectGrantMemberToPb(m *proj_model.ProjectGrantMemberView) *member_pb.Member {
|
||||
return &member_pb.Member{
|
||||
UserId: m.UserID,
|
||||
Roles: m.Roles,
|
||||
// PreferredLoginName: //TODO: not implemented in be
|
||||
Email: m.Email,
|
||||
FirstName: m.FirstName,
|
||||
LastName: m.LastName,
|
||||
DisplayName: m.DisplayName,
|
||||
UserId: m.UserID,
|
||||
Roles: m.Roles,
|
||||
PreferredLoginName: m.PreferredLoginName,
|
||||
Email: m.Email,
|
||||
FirstName: m.FirstName,
|
||||
LastName: m.LastName,
|
||||
DisplayName: m.DisplayName,
|
||||
Details: object.ToViewDetailsPb(
|
||||
m.Sequence,
|
||||
m.CreationDate,
|
||||
|
@ -17,13 +17,13 @@ func ProjectMembersToPb(members []*proj_model.ProjectMemberView) []*member_pb.Me
|
||||
|
||||
func ProjectMemberToPb(m *proj_model.ProjectMemberView) *member_pb.Member {
|
||||
return &member_pb.Member{
|
||||
UserId: m.UserID,
|
||||
Roles: m.Roles,
|
||||
// PreferredLoginName: //TODO: not implemented in be
|
||||
Email: m.Email,
|
||||
FirstName: m.FirstName,
|
||||
LastName: m.LastName,
|
||||
DisplayName: m.DisplayName,
|
||||
UserId: m.UserID,
|
||||
Roles: m.Roles,
|
||||
PreferredLoginName: m.PreferredLoginName,
|
||||
Email: m.Email,
|
||||
FirstName: m.FirstName,
|
||||
LastName: m.LastName,
|
||||
DisplayName: m.DisplayName,
|
||||
Details: object.ToViewDetailsPb(
|
||||
m.Sequence,
|
||||
m.CreationDate,
|
||||
|
@ -29,8 +29,11 @@ func OrgQueryToModel(query *org_pb.OrgQuery) (*org_model.OrgSearchQuery, error)
|
||||
Value: q.DomainQuery.Domain,
|
||||
}, nil
|
||||
case *org_pb.OrgQuery_NameQuery:
|
||||
//TODO: implement name in backend
|
||||
return nil, errors.ThrowUnimplemented(nil, "ADMIN-KGXnX", "name query not implemented")
|
||||
return &org_model.OrgSearchQuery{
|
||||
Key: org_model.OrgSearchKeyOrgName,
|
||||
Method: object.TextMethodToModel(q.NameQuery.Method),
|
||||
Value: q.NameQuery.Name,
|
||||
}, nil
|
||||
default:
|
||||
return nil, errors.ThrowInvalidArgument(nil, "ADMIN-vR9nC", "List.Query.Invalid")
|
||||
}
|
||||
|
@ -7,7 +7,8 @@ import (
|
||||
|
||||
func MultiFactorTypeToDomain(multiFactorType policy_pb.MultiFactorType) domain.MultiFactorType {
|
||||
switch multiFactorType {
|
||||
//TODO: gap between proto and backend
|
||||
case policy_pb.MultiFactorType_MULTI_FACTOR_TYPE_U2F_WITH_VERIFICATION:
|
||||
return domain.MultiFactorTypeU2FWithPIN
|
||||
default:
|
||||
return domain.MultiFactorTypeUnspecified
|
||||
}
|
||||
|
@ -244,7 +244,6 @@ func WebAuthNTokenViewToPb(token *model.WebAuthNView) *user_pb.WebAuthNToken {
|
||||
|
||||
func WebAuthNTokenToWebAuthNKeyPb(token *domain.WebAuthNToken) *user_pb.WebAuthNKey {
|
||||
return &user_pb.WebAuthNKey{
|
||||
Id: string(token.KeyID), //TODO: ask if it's the correct id?
|
||||
PublicKey: token.PublicKey,
|
||||
}
|
||||
}
|
||||
|
@ -37,10 +37,14 @@ func (wm *HumanEmailWriteModel) Reduce() error {
|
||||
switch e := event.(type) {
|
||||
case *user.HumanAddedEvent:
|
||||
wm.Email = e.EmailAddress
|
||||
wm.UserState = domain.UserStateInitial
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.HumanRegisteredEvent:
|
||||
wm.Email = e.EmailAddress
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.HumanInitialCodeAddedEvent:
|
||||
wm.UserState = domain.UserStateInitial
|
||||
case *user.HumanInitializedCheckSucceededEvent:
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.HumanEmailChangedEvent:
|
||||
wm.Email = e.EmailAddress
|
||||
wm.IsEmailVerified = false
|
||||
@ -52,9 +56,6 @@ func (wm *HumanEmailWriteModel) Reduce() error {
|
||||
case *user.HumanEmailVerifiedEvent:
|
||||
wm.IsEmailVerified = true
|
||||
wm.Code = nil
|
||||
if wm.UserState == domain.UserStateInitial {
|
||||
wm.UserState = domain.UserStateActive
|
||||
}
|
||||
case *user.UserRemovedEvent:
|
||||
wm.UserState = domain.UserStateDeleted
|
||||
}
|
||||
|
@ -572,6 +572,12 @@ func TestCommandSide_CreateVerificationCodeHumanEmail(t *testing.T) {
|
||||
true,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
user.NewHumanInitialCodeAddedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
nil, time.Hour*1,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
|
@ -37,10 +37,10 @@ func (wm *HumanInitCodeWriteModel) Reduce() error {
|
||||
switch e := event.(type) {
|
||||
case *user.HumanAddedEvent:
|
||||
wm.Email = e.EmailAddress
|
||||
wm.UserState = domain.UserStateInitial
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.HumanRegisteredEvent:
|
||||
wm.Email = e.EmailAddress
|
||||
wm.UserState = domain.UserStateInitial
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.HumanEmailChangedEvent:
|
||||
wm.Email = e.EmailAddress
|
||||
wm.IsEmailVerified = false
|
||||
@ -54,8 +54,10 @@ func (wm *HumanInitCodeWriteModel) Reduce() error {
|
||||
wm.Code = e.Code
|
||||
wm.CodeCreationDate = e.CreationDate()
|
||||
wm.CodeExpiry = e.Expiry
|
||||
wm.UserState = domain.UserStateInitial
|
||||
case *user.HumanInitializedCheckSucceededEvent:
|
||||
wm.Code = nil
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.UserRemovedEvent:
|
||||
wm.UserState = domain.UserStateDeleted
|
||||
}
|
||||
|
@ -126,6 +126,12 @@ func TestCommandSide_ResendInitialMail(t *testing.T) {
|
||||
true,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
user.NewHumanInitialCodeAddedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
nil, time.Hour*1,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
@ -178,6 +184,12 @@ func TestCommandSide_ResendInitialMail(t *testing.T) {
|
||||
true,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
user.NewHumanInitialCodeAddedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
nil, time.Hour*1,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
@ -229,6 +241,12 @@ func TestCommandSide_ResendInitialMail(t *testing.T) {
|
||||
true,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
user.NewHumanInitialCodeAddedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
nil, time.Hour*1,
|
||||
),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
|
@ -54,6 +54,10 @@ func (wm *HumanWriteModel) Reduce() error {
|
||||
wm.reduceHumanAddedEvent(e)
|
||||
case *user.HumanRegisteredEvent:
|
||||
wm.reduceHumanRegisteredEvent(e)
|
||||
case *user.HumanInitialCodeAddedEvent:
|
||||
wm.UserState = domain.UserStateInitial
|
||||
case *user.HumanInitializedCheckSucceededEvent:
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.UsernameChangedEvent:
|
||||
wm.UserName = e.UserName
|
||||
case *user.HumanProfileChangedEvent:
|
||||
@ -128,7 +132,7 @@ func (wm *HumanWriteModel) reduceHumanAddedEvent(e *user.HumanAddedEvent) {
|
||||
wm.StreetAddress = e.StreetAddress
|
||||
wm.Secret = e.Secret
|
||||
wm.SecretChangeRequired = e.ChangeRequired
|
||||
wm.UserState = domain.UserStateInitial
|
||||
wm.UserState = domain.UserStateActive
|
||||
}
|
||||
|
||||
func (wm *HumanWriteModel) reduceHumanRegisteredEvent(e *user.HumanRegisteredEvent) {
|
||||
@ -148,7 +152,7 @@ func (wm *HumanWriteModel) reduceHumanRegisteredEvent(e *user.HumanRegisteredEve
|
||||
wm.StreetAddress = e.StreetAddress
|
||||
wm.Secret = e.Secret
|
||||
wm.SecretChangeRequired = e.ChangeRequired
|
||||
wm.UserState = domain.UserStateInitial
|
||||
wm.UserState = domain.UserStateActive
|
||||
}
|
||||
|
||||
func (wm *HumanWriteModel) reduceHumanProfileChangedEvent(e *user.HumanProfileChangedEvent) {
|
||||
|
@ -37,11 +37,15 @@ func (wm *HumanPasswordWriteModel) Reduce() error {
|
||||
case *user.HumanAddedEvent:
|
||||
wm.Secret = e.Secret
|
||||
wm.SecretChangeRequired = e.ChangeRequired
|
||||
wm.UserState = domain.UserStateInitial
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.HumanRegisteredEvent:
|
||||
wm.Secret = e.Secret
|
||||
wm.SecretChangeRequired = e.ChangeRequired
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.HumanInitialCodeAddedEvent:
|
||||
wm.UserState = domain.UserStateInitial
|
||||
case *user.HumanInitializedCheckSucceededEvent:
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.HumanPasswordChangedEvent:
|
||||
wm.Secret = e.Secret
|
||||
wm.SecretChangeRequired = e.ChangeRequired
|
||||
|
@ -757,7 +757,7 @@ func TestCommandSide_RequestSetPassword(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "phone already verified, precondition error",
|
||||
name: "user initial, precondition error",
|
||||
fields: fields{
|
||||
eventstore: eventstoreExpect(
|
||||
t,
|
||||
@ -776,6 +776,12 @@ func TestCommandSide_RequestSetPassword(t *testing.T) {
|
||||
true,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
user.NewHumanInitialCodeAddedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
nil, time.Hour*1,
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
user.NewHumanPhoneChangedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
|
@ -48,6 +48,10 @@ func (wm *HumanPhoneWriteModel) Reduce() error {
|
||||
wm.State = domain.PhoneStateActive
|
||||
}
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.HumanInitialCodeAddedEvent:
|
||||
wm.UserState = domain.UserStateInitial
|
||||
case *user.HumanInitializedCheckSucceededEvent:
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.HumanPhoneChangedEvent:
|
||||
wm.Phone = e.PhoneNumber
|
||||
wm.IsPhoneVerified = false
|
||||
|
@ -474,7 +474,7 @@ func TestCommandSide_AddHuman(t *testing.T) {
|
||||
EmailAddress: "email@test.ch",
|
||||
IsEmailVerified: true,
|
||||
},
|
||||
State: domain.UserStateInitial,
|
||||
State: domain.UserStateActive,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1048,7 +1048,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
|
||||
EmailAddress: "email@test.ch",
|
||||
IsEmailVerified: true,
|
||||
},
|
||||
State: domain.UserStateInitial,
|
||||
State: domain.UserStateActive,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -173,6 +173,7 @@ func (c *Commands) HumanVerifyU2FSetup(ctx context.Context, userID, resourceowne
|
||||
webAuthN.PublicKey,
|
||||
webAuthN.AAGUID,
|
||||
webAuthN.SignCount,
|
||||
userAgentID,
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
@ -206,6 +207,7 @@ func (c *Commands) HumanHumanPasswordlessSetup(ctx context.Context, userID, reso
|
||||
webAuthN.PublicKey,
|
||||
webAuthN.AAGUID,
|
||||
webAuthN.SignCount,
|
||||
userAgentID,
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
@ -436,7 +438,7 @@ func (c *Commands) removeHumanWebAuthN(ctx context.Context, userID, webAuthNID,
|
||||
return nil, err
|
||||
}
|
||||
if existingWebAuthN.State == domain.MFAStateUnspecified || existingWebAuthN.State == domain.MFAStateRemoved {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-2M9ds", "Errors.User.ExternalIDP.NotFound")
|
||||
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-DAfb2", "Errors.User.WebAuthN.NotFound")
|
||||
}
|
||||
|
||||
userAgg := UserAggregateFromWriteModel(&existingWebAuthN.WriteModel)
|
||||
|
@ -39,18 +39,50 @@ func (wm *HumanWebAuthNWriteModel) AppendEvents(events ...eventstore.EventReader
|
||||
if wm.WebauthNTokenID == e.WebAuthNTokenID {
|
||||
wm.WriteModel.AppendEvents(e)
|
||||
}
|
||||
case *user.HumanPasswordlessAddedEvent:
|
||||
if wm.WebauthNTokenID == e.WebAuthNTokenID {
|
||||
wm.WriteModel.AppendEvents(&e.HumanWebAuthNAddedEvent)
|
||||
}
|
||||
case *user.HumanU2FAddedEvent:
|
||||
if wm.WebauthNTokenID == e.WebAuthNTokenID {
|
||||
wm.WriteModel.AppendEvents(&e.HumanWebAuthNAddedEvent)
|
||||
}
|
||||
case *user.HumanWebAuthNVerifiedEvent:
|
||||
if wm.WebauthNTokenID == e.WebAuthNTokenID {
|
||||
wm.WriteModel.AppendEvents(e)
|
||||
}
|
||||
case *user.HumanPasswordlessVerifiedEvent:
|
||||
if wm.WebauthNTokenID == e.WebAuthNTokenID {
|
||||
wm.WriteModel.AppendEvents(e)
|
||||
}
|
||||
case *user.HumanU2FVerifiedEvent:
|
||||
if wm.WebauthNTokenID == e.WebAuthNTokenID {
|
||||
wm.WriteModel.AppendEvents(e)
|
||||
}
|
||||
case *user.HumanWebAuthNSignCountChangedEvent:
|
||||
if wm.WebauthNTokenID == e.WebAuthNTokenID {
|
||||
wm.WriteModel.AppendEvents(e)
|
||||
}
|
||||
case *user.HumanPasswordlessSignCountChangedEvent:
|
||||
if wm.WebauthNTokenID == e.WebAuthNTokenID {
|
||||
wm.WriteModel.AppendEvents(e)
|
||||
}
|
||||
case *user.HumanU2FSignCountChangedEvent:
|
||||
if wm.WebauthNTokenID == e.WebAuthNTokenID {
|
||||
wm.WriteModel.AppendEvents(e)
|
||||
}
|
||||
case *user.HumanWebAuthNRemovedEvent:
|
||||
if wm.WebauthNTokenID == e.WebAuthNTokenID {
|
||||
wm.WriteModel.AppendEvents(e)
|
||||
}
|
||||
case *user.HumanPasswordlessRemovedEvent:
|
||||
if wm.WebauthNTokenID == e.WebAuthNTokenID {
|
||||
wm.WriteModel.AppendEvents(e)
|
||||
}
|
||||
case *user.HumanU2FRemovedEvent:
|
||||
if wm.WebauthNTokenID == e.WebAuthNTokenID {
|
||||
wm.WriteModel.AppendEvents(e)
|
||||
}
|
||||
case *user.UserRemovedEvent:
|
||||
wm.WriteModel.AppendEvents(e)
|
||||
}
|
||||
|
@ -30,9 +30,11 @@ func (wm *UserWriteModel) Reduce() error {
|
||||
switch e := event.(type) {
|
||||
case *user.HumanAddedEvent:
|
||||
wm.UserName = e.UserName
|
||||
wm.UserState = domain.UserStateInitial
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.HumanRegisteredEvent:
|
||||
wm.UserName = e.UserName
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.HumanInitialCodeAddedEvent:
|
||||
wm.UserState = domain.UserStateInitial
|
||||
case *user.HumanInitializedCheckSucceededEvent:
|
||||
wm.UserState = domain.UserStateActive
|
||||
|
@ -6,17 +6,18 @@ import (
|
||||
)
|
||||
|
||||
type IAMMemberView struct {
|
||||
UserID string
|
||||
IAMID string
|
||||
UserName string
|
||||
Email string
|
||||
FirstName string
|
||||
LastName string
|
||||
DisplayName string
|
||||
Roles []string
|
||||
CreationDate time.Time
|
||||
ChangeDate time.Time
|
||||
Sequence uint64
|
||||
UserID string
|
||||
IAMID string
|
||||
UserName string
|
||||
Email string
|
||||
FirstName string
|
||||
LastName string
|
||||
DisplayName string
|
||||
PreferredLoginName string
|
||||
Roles []string
|
||||
CreationDate time.Time
|
||||
ChangeDate time.Time
|
||||
Sequence uint64
|
||||
}
|
||||
|
||||
type IAMMemberSearchRequest struct {
|
||||
|
@ -23,15 +23,16 @@ const (
|
||||
)
|
||||
|
||||
type IAMMemberView struct {
|
||||
UserID string `json:"userId" gorm:"column:user_id;primary_key"`
|
||||
IAMID string `json:"-" gorm:"column:iam_id"`
|
||||
UserName string `json:"-" gorm:"column:user_name"`
|
||||
Email string `json:"-" gorm:"column:email_address"`
|
||||
FirstName string `json:"-" gorm:"column:first_name"`
|
||||
LastName string `json:"-" gorm:"column:last_name"`
|
||||
DisplayName string `json:"-" gorm:"column:display_name"`
|
||||
Roles pq.StringArray `json:"roles" gorm:"column:roles"`
|
||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||
UserID string `json:"userId" gorm:"column:user_id;primary_key"`
|
||||
IAMID string `json:"-" gorm:"column:iam_id"`
|
||||
UserName string `json:"-" gorm:"column:user_name"`
|
||||
Email string `json:"-" gorm:"column:email_address"`
|
||||
FirstName string `json:"-" gorm:"column:first_name"`
|
||||
LastName string `json:"-" gorm:"column:last_name"`
|
||||
DisplayName string `json:"-" gorm:"column:display_name"`
|
||||
Roles pq.StringArray `json:"roles" gorm:"column:roles"`
|
||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||
PreferredLoginName string `json:"-" gorm:"column:preferred_login_name"`
|
||||
|
||||
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
|
||||
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
|
||||
@ -55,17 +56,18 @@ func IAMMemberViewFromModel(member *model.IAMMemberView) *IAMMemberView {
|
||||
|
||||
func IAMMemberToModel(member *IAMMemberView) *model.IAMMemberView {
|
||||
return &model.IAMMemberView{
|
||||
UserID: member.UserID,
|
||||
IAMID: member.IAMID,
|
||||
UserName: member.UserName,
|
||||
Email: member.Email,
|
||||
FirstName: member.FirstName,
|
||||
LastName: member.LastName,
|
||||
DisplayName: member.DisplayName,
|
||||
Roles: member.Roles,
|
||||
Sequence: member.Sequence,
|
||||
CreationDate: member.CreationDate,
|
||||
ChangeDate: member.ChangeDate,
|
||||
UserID: member.UserID,
|
||||
IAMID: member.IAMID,
|
||||
UserName: member.UserName,
|
||||
Email: member.Email,
|
||||
FirstName: member.FirstName,
|
||||
LastName: member.LastName,
|
||||
DisplayName: member.DisplayName,
|
||||
PreferredLoginName: member.PreferredLoginName,
|
||||
Roles: member.Roles,
|
||||
Sequence: member.Sequence,
|
||||
CreationDate: member.CreationDate,
|
||||
ChangeDate: member.ChangeDate,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,16 +2,23 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
org_view "github.com/caos/zitadel/internal/org/repository/view"
|
||||
"github.com/caos/zitadel/internal/user/repository/view"
|
||||
|
||||
"github.com/caos/logging"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/repository/view/model"
|
||||
org_view_model "github.com/caos/zitadel/internal/org/repository/view/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
@ -84,7 +91,7 @@ func (m *OrgMember) Reduce(event *es_models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (m *OrgMember) processOrgMember(event *es_models.Event) (err error) {
|
||||
member := new(org_model.OrgMemberView)
|
||||
member := new(org_view_model.OrgMemberView)
|
||||
switch event.Type {
|
||||
case model.OrgMemberAdded:
|
||||
err = member.AppendEvent(event)
|
||||
@ -146,17 +153,25 @@ func (m *OrgMember) processUser(event *es_models.Event) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *OrgMember) fillData(member *org_model.OrgMemberView) (err error) {
|
||||
func (m *OrgMember) fillData(member *org_view_model.OrgMemberView) (err error) {
|
||||
user, err := m.getUserByID(member.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.fillUserData(member, user)
|
||||
return nil
|
||||
return m.fillUserData(member, user)
|
||||
}
|
||||
|
||||
func (m *OrgMember) fillUserData(member *org_model.OrgMemberView, user *usr_view_model.UserView) {
|
||||
func (m *OrgMember) fillUserData(member *org_view_model.OrgMemberView, user *usr_view_model.UserView) error {
|
||||
org, err := m.getOrgByID(context.Background(), user.ResourceOwner)
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = m.getDefaultOrgIAMPolicy(context.TODO())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
member.UserName = user.UserName
|
||||
member.PreferredLoginName = user.GenerateLoginName(org.GetPrimaryDomain().Domain, policy.UserLoginMustBeDomain)
|
||||
if user.HumanView != nil {
|
||||
member.FirstName = user.FirstName
|
||||
member.LastName = user.LastName
|
||||
@ -166,7 +181,9 @@ func (m *OrgMember) fillUserData(member *org_model.OrgMemberView, user *usr_view
|
||||
if user.MachineView != nil {
|
||||
member.DisplayName = user.MachineView.Name
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *OrgMember) OnError(event *es_models.Event, err error) error {
|
||||
logging.LogWithFields("SPOOL-u73es", "id", event.AggregateID).WithError(err).Warn("something went wrong in orgmember handler")
|
||||
return spooler.HandleError(event, err, m.view.GetLatestOrgMemberFailedEvent, m.view.ProcessedOrgMemberFailedEvent, m.view.ProcessedOrgMemberSequence, m.errorCountUntilSkip)
|
||||
@ -208,3 +225,53 @@ func (u *OrgMember) getUserEvents(userID string, sequence uint64) ([]*es_models.
|
||||
|
||||
return u.es.FilterEvents(context.Background(), query)
|
||||
}
|
||||
|
||||
func (u *OrgMember) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := org_view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &model.Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-kVLb2", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *OrgMember) getDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingIAM, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIAM.DefaultOrgIAMPolicy == nil {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2Fj8s", "Errors.IAM.OrgIAMPolicy.NotExisting")
|
||||
}
|
||||
return existingIAM.DefaultOrgIAMPolicy, nil
|
||||
}
|
||||
|
||||
func (u *OrgMember) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &iam_es_model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IAMToModel(iam), nil
|
||||
}
|
||||
|
@ -2,8 +2,16 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
org_view "github.com/caos/zitadel/internal/org/repository/view"
|
||||
"github.com/caos/zitadel/internal/user/repository/view"
|
||||
usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
|
||||
@ -160,8 +168,17 @@ func (p *ProjectGrantMember) fillData(member *view_model.ProjectGrantMemberView)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ProjectGrantMember) fillUserData(member *view_model.ProjectGrantMemberView, user *usr_view_model.UserView) {
|
||||
func (p *ProjectGrantMember) fillUserData(member *view_model.ProjectGrantMemberView, user *usr_view_model.UserView) error {
|
||||
org, err := p.getOrgByID(context.Background(), user.ResourceOwner)
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = p.getDefaultOrgIAMPolicy(context.TODO())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
member.UserName = user.UserName
|
||||
member.PreferredLoginName = user.GenerateLoginName(org.GetPrimaryDomain().Domain, policy.UserLoginMustBeDomain)
|
||||
if user.HumanView != nil {
|
||||
member.FirstName = user.FirstName
|
||||
member.LastName = user.LastName
|
||||
@ -171,6 +188,7 @@ func (p *ProjectGrantMember) fillUserData(member *view_model.ProjectGrantMemberV
|
||||
if user.MachineView != nil {
|
||||
member.DisplayName = user.MachineView.Name
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ProjectGrantMember) OnError(event *es_models.Event, err error) error {
|
||||
@ -214,3 +232,53 @@ func (u *ProjectGrantMember) getUserEvents(userID string, sequence uint64) ([]*e
|
||||
|
||||
return u.es.FilterEvents(context.Background(), query)
|
||||
}
|
||||
|
||||
func (u *ProjectGrantMember) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := org_view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-3nd7s", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *ProjectGrantMember) getDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingIAM, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIAM.DefaultOrgIAMPolicy == nil {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-3Bf7s", "Errors.IAM.OrgIAMPolicy.NotExisting")
|
||||
}
|
||||
return existingIAM.DefaultOrgIAMPolicy, nil
|
||||
}
|
||||
|
||||
func (u *ProjectGrantMember) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &iam_es_model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IAMToModel(iam), nil
|
||||
}
|
||||
|
@ -2,8 +2,15 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_view "github.com/caos/zitadel/internal/org/repository/view"
|
||||
"github.com/caos/zitadel/internal/user/repository/view"
|
||||
|
||||
"github.com/caos/logging"
|
||||
@ -11,6 +18,7 @@ import (
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
@ -153,12 +161,20 @@ func (p *ProjectMember) fillData(member *view_model.ProjectMemberView) (err erro
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.fillUserData(member, user)
|
||||
return nil
|
||||
return p.fillUserData(member, user)
|
||||
}
|
||||
|
||||
func (p *ProjectMember) fillUserData(member *view_model.ProjectMemberView, user *usr_view_model.UserView) {
|
||||
func (p *ProjectMember) fillUserData(member *view_model.ProjectMemberView, user *usr_view_model.UserView) error {
|
||||
org, err := p.getOrgByID(context.Background(), user.ResourceOwner)
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = p.getDefaultOrgIAMPolicy(context.TODO())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
member.UserName = user.UserName
|
||||
member.PreferredLoginName = user.GenerateLoginName(org.GetPrimaryDomain().Domain, policy.UserLoginMustBeDomain)
|
||||
if user.HumanView != nil {
|
||||
member.FirstName = user.FirstName
|
||||
member.LastName = user.LastName
|
||||
@ -168,7 +184,9 @@ func (p *ProjectMember) fillUserData(member *view_model.ProjectMemberView, user
|
||||
if user.MachineView != nil {
|
||||
member.DisplayName = user.MachineView.Name
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ProjectMember) OnError(event *es_models.Event, err error) error {
|
||||
logging.LogWithFields("SPOOL-u73es", "id", event.AggregateID).WithError(err).Warn("something went wrong in projectmember handler")
|
||||
return spooler.HandleError(event, err, p.view.GetLatestProjectMemberFailedEvent, p.view.ProcessedProjectMemberFailedEvent, p.view.ProcessedProjectMemberSequence, p.errorCountUntilSkip)
|
||||
@ -210,3 +228,53 @@ func (u *ProjectMember) getUserEvents(userID string, sequence uint64) ([]*es_mod
|
||||
|
||||
return u.es.FilterEvents(context.Background(), query)
|
||||
}
|
||||
|
||||
func (u *ProjectMember) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := org_view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-3N8fs", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *ProjectMember) getDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingIAM, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIAM.DefaultOrgIAMPolicy == nil {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-5M9sd", "Errors.IAM.OrgIAMPolicy.NotExisting")
|
||||
}
|
||||
return existingIAM.DefaultOrgIAMPolicy, nil
|
||||
}
|
||||
|
||||
func (u *ProjectMember) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &iam_es_model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IAMToModel(iam), nil
|
||||
}
|
||||
|
@ -32,9 +32,9 @@ func (msg *EmailMessage) GetContent() string {
|
||||
}
|
||||
|
||||
//default mime-type is html
|
||||
mime := "MIME-version: 1.0;" + lineBreak + "Content-KeyType: text/html; charset=\"UTF-8\";" + lineBreak + lineBreak
|
||||
mime := "MIME-version: 1.0;" + lineBreak + "Content-Type: text/html; charset=\"UTF-8\";" + lineBreak + lineBreak
|
||||
if !isHTML(msg.Content) {
|
||||
mime = "MIME-version: 1.0;" + lineBreak + "Content-KeyType: text/plain; charset=\"UTF-8\";" + lineBreak + lineBreak
|
||||
mime = "MIME-version: 1.0;" + lineBreak + "Content-Type: text/plain; charset=\"UTF-8\";" + lineBreak + lineBreak
|
||||
}
|
||||
subject := "Subject: " + msg.Subject + lineBreak
|
||||
message += subject + mime + lineBreak + msg.Content
|
||||
|
@ -2,6 +2,7 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
@ -12,6 +13,7 @@ import (
|
||||
org_view "github.com/caos/zitadel/internal/org/repository/view"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
||||
@ -97,9 +99,13 @@ func (u *NotifyUser) ProcessUser(event *es_models.Event) (err error) {
|
||||
case es_model.UserAdded,
|
||||
es_model.UserRegistered,
|
||||
es_model.HumanRegistered,
|
||||
es_model.HumanAdded:
|
||||
user.AppendEvent(event)
|
||||
u.fillLoginNames(user)
|
||||
es_model.HumanAdded,
|
||||
es_model.MachineAdded:
|
||||
err := user.AppendEvent(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = u.fillLoginNames(user)
|
||||
case es_model.UserProfileChanged,
|
||||
es_model.UserEmailChanged,
|
||||
es_model.UserEmailVerified,
|
||||
@ -128,7 +134,7 @@ func (u *NotifyUser) ProcessUser(event *es_models.Event) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.fillLoginNames(user)
|
||||
err = u.fillLoginNames(user)
|
||||
case es_model.UserRemoved:
|
||||
return u.view.DeleteNotifyUser(event.AggregateID, event)
|
||||
default:
|
||||
|
@ -1,22 +1,24 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"time"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
)
|
||||
|
||||
type OrgMemberView struct {
|
||||
UserID string
|
||||
OrgID string
|
||||
UserName string
|
||||
Email string
|
||||
FirstName string
|
||||
LastName string
|
||||
DisplayName string
|
||||
Roles []string
|
||||
CreationDate time.Time
|
||||
ChangeDate time.Time
|
||||
Sequence uint64
|
||||
UserID string
|
||||
OrgID string
|
||||
UserName string
|
||||
Email string
|
||||
FirstName string
|
||||
LastName string
|
||||
DisplayName string
|
||||
PreferredLoginName string
|
||||
Roles []string
|
||||
CreationDate time.Time
|
||||
ChangeDate time.Time
|
||||
Sequence uint64
|
||||
}
|
||||
|
||||
type OrgMemberSearchRequest struct {
|
||||
|
@ -23,15 +23,16 @@ const (
|
||||
)
|
||||
|
||||
type OrgMemberView struct {
|
||||
UserID string `json:"userId" gorm:"column:user_id;primary_key"`
|
||||
OrgID string `json:"-" gorm:"column:org_id;primary_key"`
|
||||
UserName string `json:"-" gorm:"column:user_name"`
|
||||
Email string `json:"-" gorm:"column:email_address"`
|
||||
FirstName string `json:"-" gorm:"column:first_name"`
|
||||
LastName string `json:"-" gorm:"column:last_name"`
|
||||
DisplayName string `json:"-" gorm:"column:display_name"`
|
||||
Roles pq.StringArray `json:"roles" gorm:"column:roles"`
|
||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||
UserID string `json:"userId" gorm:"column:user_id;primary_key"`
|
||||
OrgID string `json:"-" gorm:"column:org_id;primary_key"`
|
||||
UserName string `json:"-" gorm:"column:user_name"`
|
||||
Email string `json:"-" gorm:"column:email_address"`
|
||||
FirstName string `json:"-" gorm:"column:first_name"`
|
||||
LastName string `json:"-" gorm:"column:last_name"`
|
||||
DisplayName string `json:"-" gorm:"column:display_name"`
|
||||
Roles pq.StringArray `json:"roles" gorm:"column:roles"`
|
||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||
PreferredLoginName string `json:"-" gorm:"column:preferred_login_name"`
|
||||
|
||||
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
|
||||
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
|
||||
@ -39,17 +40,18 @@ type OrgMemberView struct {
|
||||
|
||||
func OrgMemberToModel(member *OrgMemberView) *model.OrgMemberView {
|
||||
return &model.OrgMemberView{
|
||||
UserID: member.UserID,
|
||||
OrgID: member.OrgID,
|
||||
UserName: member.UserName,
|
||||
Email: member.Email,
|
||||
FirstName: member.FirstName,
|
||||
LastName: member.LastName,
|
||||
DisplayName: member.DisplayName,
|
||||
Roles: member.Roles,
|
||||
Sequence: member.Sequence,
|
||||
CreationDate: member.CreationDate,
|
||||
ChangeDate: member.ChangeDate,
|
||||
UserID: member.UserID,
|
||||
OrgID: member.OrgID,
|
||||
UserName: member.UserName,
|
||||
Email: member.Email,
|
||||
FirstName: member.FirstName,
|
||||
LastName: member.LastName,
|
||||
DisplayName: member.DisplayName,
|
||||
PreferredLoginName: member.PreferredLoginName,
|
||||
Roles: member.Roles,
|
||||
Sequence: member.Sequence,
|
||||
CreationDate: member.CreationDate,
|
||||
ChangeDate: member.ChangeDate,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,18 +6,19 @@ import (
|
||||
)
|
||||
|
||||
type ProjectGrantMemberView struct {
|
||||
UserID string
|
||||
GrantID string
|
||||
ProjectID string
|
||||
UserName string
|
||||
Email string
|
||||
FirstName string
|
||||
LastName string
|
||||
DisplayName string
|
||||
Roles []string
|
||||
CreationDate time.Time
|
||||
ChangeDate time.Time
|
||||
Sequence uint64
|
||||
UserID string
|
||||
GrantID string
|
||||
ProjectID string
|
||||
UserName string
|
||||
Email string
|
||||
FirstName string
|
||||
LastName string
|
||||
DisplayName string
|
||||
PreferredLoginName string
|
||||
Roles []string
|
||||
CreationDate time.Time
|
||||
ChangeDate time.Time
|
||||
Sequence uint64
|
||||
}
|
||||
|
||||
type ProjectGrantMemberSearchRequest struct {
|
||||
|
@ -6,17 +6,18 @@ import (
|
||||
)
|
||||
|
||||
type ProjectMemberView struct {
|
||||
UserID string
|
||||
ProjectID string
|
||||
UserName string
|
||||
Email string
|
||||
FirstName string
|
||||
LastName string
|
||||
DisplayName string
|
||||
Roles []string
|
||||
CreationDate time.Time
|
||||
ChangeDate time.Time
|
||||
Sequence uint64
|
||||
UserID string
|
||||
ProjectID string
|
||||
UserName string
|
||||
Email string
|
||||
FirstName string
|
||||
LastName string
|
||||
DisplayName string
|
||||
PreferredLoginName string
|
||||
Roles []string
|
||||
CreationDate time.Time
|
||||
ChangeDate time.Time
|
||||
Sequence uint64
|
||||
}
|
||||
|
||||
type ProjectMemberSearchRequest struct {
|
||||
|
@ -5,11 +5,12 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/lib/pq"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/project/model"
|
||||
es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -23,16 +24,17 @@ const (
|
||||
)
|
||||
|
||||
type ProjectGrantMemberView struct {
|
||||
UserID string `json:"userId" gorm:"column:user_id;primary_key"`
|
||||
GrantID string `json:"grantId" gorm:"column:grant_id;primary_key"`
|
||||
ProjectID string `json:"-" gorm:"column:project_id"`
|
||||
UserName string `json:"-" gorm:"column:user_name"`
|
||||
Email string `json:"-" gorm:"column:email_address"`
|
||||
FirstName string `json:"-" gorm:"column:first_name"`
|
||||
LastName string `json:"-" gorm:"column:last_name"`
|
||||
DisplayName string `json:"-" gorm:"column:display_name"`
|
||||
Roles pq.StringArray `json:"roles" gorm:"column:roles"`
|
||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||
UserID string `json:"userId" gorm:"column:user_id;primary_key"`
|
||||
GrantID string `json:"grantId" gorm:"column:grant_id;primary_key"`
|
||||
ProjectID string `json:"-" gorm:"column:project_id"`
|
||||
UserName string `json:"-" gorm:"column:user_name"`
|
||||
Email string `json:"-" gorm:"column:email_address"`
|
||||
FirstName string `json:"-" gorm:"column:first_name"`
|
||||
LastName string `json:"-" gorm:"column:last_name"`
|
||||
DisplayName string `json:"-" gorm:"column:display_name"`
|
||||
Roles pq.StringArray `json:"roles" gorm:"column:roles"`
|
||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||
PreferredLoginName string `json:"-" gorm:"column:preferred_login_name"`
|
||||
|
||||
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
|
||||
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
|
||||
@ -40,18 +42,19 @@ type ProjectGrantMemberView struct {
|
||||
|
||||
func ProjectGrantMemberToModel(member *ProjectGrantMemberView) *model.ProjectGrantMemberView {
|
||||
return &model.ProjectGrantMemberView{
|
||||
UserID: member.UserID,
|
||||
GrantID: member.GrantID,
|
||||
ProjectID: member.ProjectID,
|
||||
UserName: member.UserName,
|
||||
Email: member.Email,
|
||||
FirstName: member.FirstName,
|
||||
LastName: member.LastName,
|
||||
DisplayName: member.DisplayName,
|
||||
Roles: member.Roles,
|
||||
Sequence: member.Sequence,
|
||||
CreationDate: member.CreationDate,
|
||||
ChangeDate: member.ChangeDate,
|
||||
UserID: member.UserID,
|
||||
GrantID: member.GrantID,
|
||||
ProjectID: member.ProjectID,
|
||||
UserName: member.UserName,
|
||||
Email: member.Email,
|
||||
FirstName: member.FirstName,
|
||||
LastName: member.LastName,
|
||||
DisplayName: member.DisplayName,
|
||||
PreferredLoginName: member.PreferredLoginName,
|
||||
Roles: member.Roles,
|
||||
Sequence: member.Sequence,
|
||||
CreationDate: member.CreationDate,
|
||||
ChangeDate: member.ChangeDate,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,15 +22,16 @@ const (
|
||||
)
|
||||
|
||||
type ProjectMemberView struct {
|
||||
UserID string `json:"userId" gorm:"column:user_id;primary_key"`
|
||||
ProjectID string `json:"-" gorm:"column:project_id;primary_key"`
|
||||
UserName string `json:"-" gorm:"column:user_name"`
|
||||
Email string `json:"-" gorm:"column:email_address"`
|
||||
FirstName string `json:"-" gorm:"column:first_name"`
|
||||
LastName string `json:"-" gorm:"column:last_name"`
|
||||
DisplayName string `json:"-" gorm:"column:display_name"`
|
||||
Roles pq.StringArray `json:"roles" gorm:"column:roles"`
|
||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||
UserID string `json:"userId" gorm:"column:user_id;primary_key"`
|
||||
ProjectID string `json:"-" gorm:"column:project_id;primary_key"`
|
||||
UserName string `json:"-" gorm:"column:user_name"`
|
||||
Email string `json:"-" gorm:"column:email_address"`
|
||||
FirstName string `json:"-" gorm:"column:first_name"`
|
||||
LastName string `json:"-" gorm:"column:last_name"`
|
||||
DisplayName string `json:"-" gorm:"column:display_name"`
|
||||
Roles pq.StringArray `json:"roles" gorm:"column:roles"`
|
||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||
PreferredLoginName string `json:"-" gorm:"column:preferred_login_name"`
|
||||
|
||||
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
|
||||
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
|
||||
|
@ -64,6 +64,7 @@ func NewHumanPasswordlessVerifiedEvent(
|
||||
publicKey,
|
||||
aaguid []byte,
|
||||
signCount uint32,
|
||||
userAgentID string,
|
||||
) *HumanPasswordlessVerifiedEvent {
|
||||
return &HumanPasswordlessVerifiedEvent{
|
||||
HumanWebAuthNVerifiedEvent: *NewHumanWebAuthNVerifiedEvent(
|
||||
@ -79,6 +80,7 @@ func NewHumanPasswordlessVerifiedEvent(
|
||||
publicKey,
|
||||
aaguid,
|
||||
signCount,
|
||||
userAgentID,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ func NewHumanU2FVerifiedEvent(
|
||||
publicKey,
|
||||
aaguid []byte,
|
||||
signCount uint32,
|
||||
userAgentID string,
|
||||
) *HumanU2FVerifiedEvent {
|
||||
return &HumanU2FVerifiedEvent{
|
||||
HumanWebAuthNVerifiedEvent: *NewHumanWebAuthNVerifiedEvent(
|
||||
@ -79,6 +80,7 @@ func NewHumanU2FVerifiedEvent(
|
||||
publicKey,
|
||||
aaguid,
|
||||
signCount,
|
||||
userAgentID,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package user
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
@ -56,6 +57,7 @@ type HumanWebAuthNVerifiedEvent struct {
|
||||
AAGUID []byte `json:"aaguid"`
|
||||
SignCount uint32 `json:"signCount"`
|
||||
WebAuthNTokenName string `json:"webAuthNTokenName"`
|
||||
UserAgentID string `json:"userAgentID,omitempty"`
|
||||
}
|
||||
|
||||
func (e *HumanWebAuthNVerifiedEvent) Data() interface{} {
|
||||
@ -75,6 +77,7 @@ func NewHumanWebAuthNVerifiedEvent(
|
||||
publicKey,
|
||||
aaguid []byte,
|
||||
signCount uint32,
|
||||
userAgentID string,
|
||||
) *HumanWebAuthNVerifiedEvent {
|
||||
return &HumanWebAuthNVerifiedEvent{
|
||||
BaseEvent: *base,
|
||||
@ -85,6 +88,7 @@ func NewHumanWebAuthNVerifiedEvent(
|
||||
AAGUID: aaguid,
|
||||
SignCount: signCount,
|
||||
WebAuthNTokenName: webAuthNTokenName,
|
||||
UserAgentID: userAgentID,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,8 +69,6 @@ func MachineAddedEventMapper(event *repository.Event) (eventstore.EventReader, e
|
||||
type MachineChangedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
UserName string `json:"userName"`
|
||||
|
||||
Name *string `json:"name,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
}
|
||||
|
@ -2,16 +2,18 @@ package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"time"
|
||||
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/lib/pq"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
"github.com/caos/zitadel/internal/user/model"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -117,7 +119,8 @@ func (u *NotifyUser) AppendEvent(event *models.Event) (err error) {
|
||||
case es_model.UserAdded,
|
||||
es_model.UserRegistered,
|
||||
es_model.HumanRegistered,
|
||||
es_model.HumanAdded:
|
||||
es_model.HumanAdded,
|
||||
es_model.MachineAdded:
|
||||
u.CreationDate = event.CreationDate
|
||||
u.setRootData(event)
|
||||
err = u.setData(event)
|
||||
@ -130,7 +133,8 @@ func (u *NotifyUser) AppendEvent(event *models.Event) (err error) {
|
||||
es_model.UserPhoneChanged,
|
||||
es_model.HumanProfileChanged,
|
||||
es_model.HumanEmailChanged,
|
||||
es_model.HumanPhoneChanged:
|
||||
es_model.HumanPhoneChanged,
|
||||
es_model.UserUserNameChanged:
|
||||
err = u.setData(event)
|
||||
case es_model.UserEmailVerified,
|
||||
es_model.HumanEmailVerified:
|
||||
|
5
migrations/cockroach/V1.37__members.sql
Normal file
5
migrations/cockroach/V1.37__members.sql
Normal file
@ -0,0 +1,5 @@
|
||||
ALTER TABLE management.org_members ADD COLUMN preferred_login_name TEXT;
|
||||
ALTER TABLE management.project_members ADD COLUMN preferred_login_name TEXT;
|
||||
ALTER TABLE management.project_grant_members ADD COLUMN preferred_login_name TEXT;
|
||||
|
||||
ALTER TABLE adminapi.iam_members ADD COLUMN preferred_login_name TEXT;
|
@ -11,16 +11,24 @@ func (a *App) Localizers() []middleware.Localizer {
|
||||
|
||||
switch configType := a.Config.(type) {
|
||||
case *App_OidcConfig:
|
||||
if !configType.OidcConfig.NoneCompliant {
|
||||
return nil
|
||||
}
|
||||
localizers := make([]middleware.Localizer, len(configType.OidcConfig.ComplianceProblems))
|
||||
for i, problem := range configType.OidcConfig.ComplianceProblems {
|
||||
localizers[i] = problem
|
||||
}
|
||||
return localizers
|
||||
return configType.ComplianceLocalizers()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *App_OidcConfig) ComplianceLocalizers() []middleware.Localizer {
|
||||
if o.OidcConfig == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !o.OidcConfig.NoneCompliant {
|
||||
return nil
|
||||
}
|
||||
localizers := make([]middleware.Localizer, len(o.OidcConfig.ComplianceProblems))
|
||||
for i, problem := range o.OidcConfig.ComplianceProblems {
|
||||
localizers[i] = problem
|
||||
}
|
||||
return localizers
|
||||
}
|
||||
|
||||
type AppConfig = isApp_Config
|
||||
|
@ -1,6 +1,28 @@
|
||||
package management
|
||||
|
||||
import "github.com/caos/zitadel/internal/api/grpc/server/middleware"
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/api/grpc/server/middleware"
|
||||
)
|
||||
|
||||
func (a *ListAppsResponse) Localizers() []middleware.Localizer {
|
||||
if a == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
localizers := make([]middleware.Localizer, 0)
|
||||
for _, a := range a.Result {
|
||||
localizers = append(localizers, a.Localizers()...)
|
||||
}
|
||||
return localizers
|
||||
}
|
||||
|
||||
func (a *GetAppByIDResponse) Localizers() []middleware.Localizer {
|
||||
if a == nil || (a != nil && a.App == nil) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return a.App.Localizers()
|
||||
}
|
||||
|
||||
func (a *AddOIDCAppResponse) Localizers() []middleware.Localizer {
|
||||
if a == nil {
|
||||
|
@ -515,7 +515,9 @@ message VerifyMyPhoneRequest {
|
||||
string code = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
}
|
||||
|
||||
message VerifyMyPhoneResponse {}
|
||||
message VerifyMyPhoneResponse {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
}
|
||||
|
||||
message ResendMyPhoneVerificationRequest {}
|
||||
|
||||
|
@ -388,7 +388,7 @@ service ManagementService {
|
||||
|
||||
rpc RemoveHumanAuthFactorU2F(RemoveHumanAuthFactorU2FRequest) returns (RemoveHumanAuthFactorU2FResponse) {
|
||||
option (google.api.http) = {
|
||||
delete: "/users/{user_id}/auth_factors/u2f"
|
||||
delete: "/users/{user_id}/auth_factors/u2f/{token_id}"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
@ -408,7 +408,7 @@ service ManagementService {
|
||||
|
||||
rpc RemoveHumanPasswordless(RemoveHumanPasswordlessRequest) returns (RemoveHumanPasswordlessResponse) {
|
||||
option (google.api.http) = {
|
||||
delete: "/users/{user_id}/passwordless"
|
||||
delete: "/users/{user_id}/passwordless/{token_id}"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
@ -429,8 +429,7 @@ service ManagementService {
|
||||
|
||||
rpc GetMachineKeyByIDs(GetMachineKeyByIDsRequest) returns (GetMachineKeyByIDsResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/users/{user_id}/keys/{key_id}"
|
||||
body: "*"
|
||||
get: "/users/{user_id}/keys/{key_id}"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
@ -2206,9 +2205,8 @@ message GenerateOrgDomainValidationRequest {
|
||||
}
|
||||
|
||||
message GenerateOrgDomainValidationResponse {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
string token = 2;
|
||||
string url = 3;
|
||||
string token = 1;
|
||||
string url = 2;
|
||||
}
|
||||
|
||||
message ValidateOrgDomainRequest {
|
||||
|
@ -172,8 +172,7 @@ message AuthFactorU2F {
|
||||
}
|
||||
|
||||
message WebAuthNKey {
|
||||
string id = 1;
|
||||
bytes public_key = 2;
|
||||
bytes public_key = 1;
|
||||
}
|
||||
|
||||
message WebAuthNVerification {
|
||||
|
Loading…
Reference in New Issue
Block a user