Livio Spring 15902f5bc7
fix(cache): prevent org cache overwrite by other instances (#10012)
# Which Problems Are Solved

A customer reported that randomly certain login flows, such as automatic
redirect to the only configured IdP would not work. During the
investigation it was discovered that they used that same primary domain
on two different instances. As they used the domain for preselecting the
organization, one would always overwrite the other in the cache. Since
The organization and especially it's policies could not be retrieved on
the other instance, it would fallback to the default organization
settings, where the external login and the corresponding IdP were not
configured.

# How the Problems Are Solved

Include the instance id in the cache key for organizations to prevent
overwrites.

# Additional Changes

None

# Additional Context

- found because of a support request
- requires backport to 2.70.x, 2.71.x and 3.x
2025-06-03 14:48:15 +02:00

71 lines
1.6 KiB
Go

package readmodel
import (
"time"
"github.com/zitadel/zitadel/internal/v2/eventstore"
"github.com/zitadel/zitadel/internal/v2/org"
"github.com/zitadel/zitadel/internal/v2/projection"
)
type Org struct {
ID string
Name string
PrimaryDomain *projection.OrgPrimaryDomain
State *projection.OrgState
Sequence uint32
CreationDate time.Time
ChangeDate time.Time
Owner string
InstanceID string
}
func NewOrg(id string) *Org {
return &Org{
ID: id,
State: projection.NewStateProjection(id),
PrimaryDomain: projection.NewOrgPrimaryDomain(id),
}
}
func (rm *Org) Filter() []*eventstore.Filter {
return []*eventstore.Filter{
// we don't need the filters of the projections as we filter all events of the read model
eventstore.NewFilter(
eventstore.AppendAggregateFilter(
org.AggregateType,
eventstore.SetAggregateID(rm.ID),
),
),
}
}
func (rm *Org) Reduce(events ...*eventstore.StorageEvent) error {
for _, event := range events {
switch event.Type {
case org.AddedType:
added, err := org.AddedEventFromStorage(event)
if err != nil {
return err
}
rm.Name = added.Payload.Name
rm.Owner = event.Aggregate.Owner
rm.CreationDate = event.CreatedAt
case org.ChangedType:
changed, err := org.ChangedEventFromStorage(event)
if err != nil {
return err
}
rm.Name = changed.Payload.Name
}
rm.Sequence = event.Sequence
rm.ChangeDate = event.CreatedAt
rm.InstanceID = event.Aggregate.Instance
}
if err := rm.State.Reduce(events...); err != nil {
return err
}
return rm.PrimaryDomain.Reduce(events...)
}