mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 17:47:32 +00:00
feat(eventstore): increase parallel write capabilities (#5940)
This implementation increases parallel write capabilities of the eventstore. Please have a look at the technical advisories: [05](https://zitadel.com/docs/support/advisory/a10005) and [06](https://zitadel.com/docs/support/advisory/a10006). The implementation of eventstore.push is rewritten and stored events are migrated to a new table `eventstore.events2`. If you are using cockroach: make sure that the database user of ZITADEL has `VIEWACTIVITY` grant. This is used to query events.
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
@@ -9,7 +8,6 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/zitadel/zitadel/internal/repository/user"
|
||||
"github.com/zitadel/zitadel/internal/user/model"
|
||||
es_model "github.com/zitadel/zitadel/internal/user/repository/eventsourcing/model"
|
||||
@@ -47,9 +45,9 @@ type UserSessionView struct {
|
||||
InstanceID string `json:"instanceID" gorm:"column:instance_id;primary_key"`
|
||||
}
|
||||
|
||||
func UserSessionFromEvent(event *models.Event) (*UserSessionView, error) {
|
||||
func UserSessionFromEvent(event eventstore.Event) (*UserSessionView, error) {
|
||||
v := new(UserSessionView)
|
||||
if err := json.Unmarshal(event.Data, v); err != nil {
|
||||
if err := event.Unmarshal(v); err != nil {
|
||||
logging.Log("EVEN-lso9e").WithError(err).Error("could not unmarshal event data")
|
||||
return nil, caos_errs.ThrowInternal(nil, "MODEL-sd325", "could not unmarshal data")
|
||||
}
|
||||
@@ -88,13 +86,13 @@ func UserSessionsToModel(userSessions []*UserSessionView) []*model.UserSessionVi
|
||||
return result
|
||||
}
|
||||
|
||||
func (v *UserSessionView) AppendEvent(event *models.Event) error {
|
||||
v.Sequence = event.Sequence
|
||||
v.ChangeDate = event.CreationDate
|
||||
switch eventstore.EventType(event.Type) {
|
||||
func (v *UserSessionView) AppendEvent(event eventstore.Event) error {
|
||||
v.Sequence = event.Sequence()
|
||||
v.ChangeDate = event.CreatedAt()
|
||||
switch event.Type() {
|
||||
case user.UserV1PasswordCheckSucceededType,
|
||||
user.HumanPasswordCheckSucceededType:
|
||||
v.PasswordVerification = event.CreationDate
|
||||
v.PasswordVerification = event.CreatedAt()
|
||||
v.State = int32(domain.UserSessionStateActive)
|
||||
case user.UserIDPLoginCheckSucceededType:
|
||||
data := new(es_model.AuthRequest)
|
||||
@@ -102,12 +100,12 @@ func (v *UserSessionView) AppendEvent(event *models.Event) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.ExternalLoginVerification = event.CreationDate
|
||||
v.ExternalLoginVerification = event.CreatedAt()
|
||||
v.SelectedIDPConfigID = data.SelectedIDPConfigID
|
||||
v.State = int32(domain.UserSessionStateActive)
|
||||
case user.HumanPasswordlessTokenCheckSucceededType:
|
||||
v.PasswordlessVerification = event.CreationDate
|
||||
v.MultiFactorVerification = event.CreationDate
|
||||
v.PasswordlessVerification = event.CreatedAt()
|
||||
v.MultiFactorVerification = event.CreatedAt()
|
||||
v.MultiFactorVerificationType = int32(domain.MFATypeU2FUserVerification)
|
||||
v.State = int32(domain.UserSessionStateActive)
|
||||
case user.HumanPasswordlessTokenCheckFailedType,
|
||||
@@ -134,11 +132,11 @@ func (v *UserSessionView) AppendEvent(event *models.Event) error {
|
||||
return err
|
||||
}
|
||||
if v.UserAgentID == data.UserAgentID {
|
||||
v.setSecondFactorVerification(event.CreationDate, domain.MFATypeTOTP)
|
||||
v.setSecondFactorVerification(event.CreatedAt(), domain.MFATypeTOTP)
|
||||
}
|
||||
case user.UserV1MFAOTPCheckSucceededType,
|
||||
user.HumanMFAOTPCheckSucceededType:
|
||||
v.setSecondFactorVerification(event.CreationDate, domain.MFATypeTOTP)
|
||||
v.setSecondFactorVerification(event.CreatedAt(), domain.MFATypeTOTP)
|
||||
case user.HumanOTPSMSCheckSucceededType:
|
||||
data := new(es_model.OTPVerified)
|
||||
err := data.SetData(event)
|
||||
@@ -146,7 +144,7 @@ func (v *UserSessionView) AppendEvent(event *models.Event) error {
|
||||
return err
|
||||
}
|
||||
if v.UserAgentID == data.UserAgentID {
|
||||
v.setSecondFactorVerification(event.CreationDate, domain.MFATypeOTPSMS)
|
||||
v.setSecondFactorVerification(event.CreatedAt(), domain.MFATypeOTPSMS)
|
||||
}
|
||||
case user.HumanOTPEmailCheckSucceededType:
|
||||
data := new(es_model.OTPVerified)
|
||||
@@ -155,7 +153,7 @@ func (v *UserSessionView) AppendEvent(event *models.Event) error {
|
||||
return err
|
||||
}
|
||||
if v.UserAgentID == data.UserAgentID {
|
||||
v.setSecondFactorVerification(event.CreationDate, domain.MFATypeOTPEmail)
|
||||
v.setSecondFactorVerification(event.CreatedAt(), domain.MFATypeOTPEmail)
|
||||
}
|
||||
case user.UserV1MFAOTPCheckFailedType,
|
||||
user.UserV1MFAOTPRemovedType,
|
||||
@@ -173,10 +171,10 @@ func (v *UserSessionView) AppendEvent(event *models.Event) error {
|
||||
return err
|
||||
}
|
||||
if v.UserAgentID == data.UserAgentID {
|
||||
v.setSecondFactorVerification(event.CreationDate, domain.MFATypeU2F)
|
||||
v.setSecondFactorVerification(event.CreatedAt(), domain.MFATypeU2F)
|
||||
}
|
||||
case user.HumanU2FTokenCheckSucceededType:
|
||||
v.setSecondFactorVerification(event.CreationDate, domain.MFATypeU2F)
|
||||
v.setSecondFactorVerification(event.CreatedAt(), domain.MFATypeU2F)
|
||||
case user.UserV1SignedOutType,
|
||||
user.HumanSignedOutType,
|
||||
user.UserLockedType,
|
||||
@@ -210,49 +208,49 @@ func (v *UserSessionView) setSecondFactorVerification(verificationTime time.Time
|
||||
v.State = int32(domain.UserSessionStateActive)
|
||||
}
|
||||
|
||||
func avatarKeyFromEvent(event *models.Event) (string, error) {
|
||||
func avatarKeyFromEvent(event eventstore.Event) (string, error) {
|
||||
data := make(map[string]string)
|
||||
if err := json.Unmarshal(event.Data, &data); err != nil {
|
||||
if err := event.Unmarshal(&data); err != nil {
|
||||
logging.Log("EVEN-Sfew2").WithError(err).Error("could not unmarshal event data")
|
||||
return "", caos_errs.ThrowInternal(err, "MODEL-SFw2q", "could not unmarshal event")
|
||||
}
|
||||
return data["storeKey"], nil
|
||||
}
|
||||
|
||||
func (v *UserSessionView) EventTypes() []models.EventType {
|
||||
return []models.EventType{
|
||||
models.EventType(user.UserV1PasswordCheckSucceededType),
|
||||
models.EventType(user.HumanPasswordCheckSucceededType),
|
||||
models.EventType(user.UserIDPLoginCheckSucceededType),
|
||||
models.EventType(user.HumanPasswordlessTokenCheckSucceededType),
|
||||
models.EventType(user.HumanPasswordlessTokenCheckFailedType),
|
||||
models.EventType(user.HumanPasswordlessTokenRemovedType),
|
||||
models.EventType(user.UserV1PasswordCheckFailedType),
|
||||
models.EventType(user.HumanPasswordCheckFailedType),
|
||||
models.EventType(user.UserV1PasswordChangedType),
|
||||
models.EventType(user.HumanPasswordChangedType),
|
||||
models.EventType(user.HumanMFAOTPVerifiedType),
|
||||
models.EventType(user.UserV1MFAOTPCheckSucceededType),
|
||||
models.EventType(user.HumanMFAOTPCheckSucceededType),
|
||||
models.EventType(user.UserV1MFAOTPCheckFailedType),
|
||||
models.EventType(user.UserV1MFAOTPRemovedType),
|
||||
models.EventType(user.HumanMFAOTPCheckFailedType),
|
||||
models.EventType(user.HumanMFAOTPRemovedType),
|
||||
models.EventType(user.HumanOTPSMSCheckSucceededType),
|
||||
models.EventType(user.HumanOTPSMSCheckFailedType),
|
||||
models.EventType(user.HumanOTPEmailCheckSucceededType),
|
||||
models.EventType(user.HumanOTPEmailCheckFailedType),
|
||||
models.EventType(user.HumanU2FTokenCheckFailedType),
|
||||
models.EventType(user.HumanU2FTokenRemovedType),
|
||||
models.EventType(user.HumanU2FTokenVerifiedType),
|
||||
models.EventType(user.HumanU2FTokenCheckSucceededType),
|
||||
models.EventType(user.UserV1SignedOutType),
|
||||
models.EventType(user.HumanSignedOutType),
|
||||
models.EventType(user.UserLockedType),
|
||||
models.EventType(user.UserDeactivatedType),
|
||||
models.EventType(user.UserIDPLinkRemovedType),
|
||||
models.EventType(user.UserIDPLinkCascadeRemovedType),
|
||||
models.EventType(user.HumanAvatarAddedType),
|
||||
models.EventType(user.HumanAvatarRemovedType),
|
||||
func (v *UserSessionView) EventTypes() []eventstore.EventType {
|
||||
return []eventstore.EventType{
|
||||
user.UserV1PasswordCheckSucceededType,
|
||||
user.HumanPasswordCheckSucceededType,
|
||||
user.UserIDPLoginCheckSucceededType,
|
||||
user.HumanPasswordlessTokenCheckSucceededType,
|
||||
user.HumanPasswordlessTokenCheckFailedType,
|
||||
user.HumanPasswordlessTokenRemovedType,
|
||||
user.UserV1PasswordCheckFailedType,
|
||||
user.HumanPasswordCheckFailedType,
|
||||
user.UserV1PasswordChangedType,
|
||||
user.HumanPasswordChangedType,
|
||||
user.HumanMFAOTPVerifiedType,
|
||||
user.UserV1MFAOTPCheckSucceededType,
|
||||
user.HumanMFAOTPCheckSucceededType,
|
||||
user.UserV1MFAOTPCheckFailedType,
|
||||
user.UserV1MFAOTPRemovedType,
|
||||
user.HumanMFAOTPCheckFailedType,
|
||||
user.HumanMFAOTPRemovedType,
|
||||
user.HumanOTPSMSCheckSucceededType,
|
||||
user.HumanOTPSMSCheckFailedType,
|
||||
user.HumanOTPEmailCheckSucceededType,
|
||||
user.HumanOTPEmailCheckFailedType,
|
||||
user.HumanU2FTokenCheckFailedType,
|
||||
user.HumanU2FTokenRemovedType,
|
||||
user.HumanU2FTokenVerifiedType,
|
||||
user.HumanU2FTokenCheckSucceededType,
|
||||
user.UserV1SignedOutType,
|
||||
user.HumanSignedOutType,
|
||||
user.UserLockedType,
|
||||
user.UserDeactivatedType,
|
||||
user.UserIDPLinkRemovedType,
|
||||
user.UserIDPLinkCascadeRemovedType,
|
||||
user.HumanAvatarAddedType,
|
||||
user.HumanAvatarRemovedType,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user