mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 11:57:36 +00:00
fix: instance remove (#4602)
This commit is contained in:
@@ -150,6 +150,12 @@ func (m *Styling) processLabelPolicy(event *models.Event) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = m.generateStylingFile(policy)
|
err = m.generateStylingFile(policy)
|
||||||
|
case instance.InstanceRemovedEventType:
|
||||||
|
err = m.deleteInstanceFilesFromStorage(event.InstanceID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return m.view.DeleteInstanceStyling(event)
|
||||||
default:
|
default:
|
||||||
return m.view.ProcessedStylingSequence(event)
|
return m.view.ProcessedStylingSequence(event)
|
||||||
}
|
}
|
||||||
@@ -262,6 +268,10 @@ func (m *Styling) uploadFilesToStorage(instanceID, aggregateID, contentType stri
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Styling) deleteInstanceFilesFromStorage(instanceID string) error {
|
||||||
|
return m.static.RemoveInstanceObjects(context.Background(), instanceID)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Styling) generateColorPaletteRGBA255(hex string) map[string]string {
|
func (m *Styling) generateColorPaletteRGBA255(hex string) map[string]string {
|
||||||
palette := make(map[string]string)
|
palette := make(map[string]string)
|
||||||
defaultColor := gamut.Hex(hex)
|
defaultColor := gamut.Hex(hex)
|
||||||
|
@@ -23,6 +23,14 @@ func (v *View) PutStyling(policy *model.LabelPolicyView, event *models.Event) er
|
|||||||
return v.ProcessedStylingSequence(event)
|
return v.ProcessedStylingSequence(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteInstanceStyling(event *models.Event) error {
|
||||||
|
err := view.DeleteInstanceStyling(v.Db, stylingTyble, event.InstanceID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedStylingSequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestStylingSequence(instanceID string) (*global_view.CurrentSequence, error) {
|
func (v *View) GetLatestStylingSequence(instanceID string) (*global_view.CurrentSequence, error) {
|
||||||
return v.latestSequence(stylingTyble, instanceID)
|
return v.latestSequence(stylingTyble, instanceID)
|
||||||
}
|
}
|
||||||
|
@@ -63,6 +63,7 @@ func (s *Server) UpdateInstance(ctx context.Context, req *system_pb.UpdateInstan
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) RemoveInstance(ctx context.Context, req *system_pb.RemoveInstanceRequest) (*system_pb.RemoveInstanceResponse, error) {
|
func (s *Server) RemoveInstance(ctx context.Context, req *system_pb.RemoveInstanceRequest) (*system_pb.RemoveInstanceResponse, error) {
|
||||||
|
ctx = authz.WithInstanceID(ctx, req.InstanceId)
|
||||||
details, err := s.command.RemoveInstance(ctx, req.InstanceId)
|
details, err := s.command.RemoveInstance(ctx, req.InstanceId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@@ -117,6 +117,8 @@ func (i *IDPConfig) processIdpConfig(providerType iam_model.IDPProviderType, eve
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return i.view.DeleteIDPConfig(idp.IDPConfigID, event)
|
return i.view.DeleteIDPConfig(idp.IDPConfigID, event)
|
||||||
|
case instance.InstanceRemovedEventType:
|
||||||
|
return i.view.DeleteInstanceIDPs(event)
|
||||||
default:
|
default:
|
||||||
return i.view.ProcessedIDPConfigSequence(event)
|
return i.view.ProcessedIDPConfigSequence(event)
|
||||||
}
|
}
|
||||||
|
@@ -138,6 +138,8 @@ func (i *IDPProvider) processIdpProvider(event *models.Event) (err error) {
|
|||||||
return i.view.PutIDPProviders(event, providers...)
|
return i.view.PutIDPProviders(event, providers...)
|
||||||
case org.LoginPolicyRemovedEventType:
|
case org.LoginPolicyRemovedEventType:
|
||||||
return i.view.DeleteIDPProvidersByAggregateID(event.AggregateID, event.InstanceID, event)
|
return i.view.DeleteIDPProvidersByAggregateID(event.AggregateID, event.InstanceID, event)
|
||||||
|
case instance.InstanceRemovedEventType:
|
||||||
|
return i.view.DeleteInstanceIDPs(event)
|
||||||
default:
|
default:
|
||||||
return i.view.ProcessedIDPProviderSequence(event)
|
return i.view.ProcessedIDPProviderSequence(event)
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/eventstore/v1/query"
|
"github.com/zitadel/zitadel/internal/eventstore/v1/query"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/v1/spooler"
|
"github.com/zitadel/zitadel/internal/eventstore/v1/spooler"
|
||||||
view_model "github.com/zitadel/zitadel/internal/project/repository/view/model"
|
view_model "github.com/zitadel/zitadel/internal/project/repository/view/model"
|
||||||
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
"github.com/zitadel/zitadel/internal/repository/project"
|
"github.com/zitadel/zitadel/internal/repository/project"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ func (p *OrgProjectMapping) Subscription() *v1.Subscription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (_ *OrgProjectMapping) AggregateTypes() []es_models.AggregateType {
|
func (_ *OrgProjectMapping) AggregateTypes() []es_models.AggregateType {
|
||||||
return []es_models.AggregateType{project.AggregateType}
|
return []es_models.AggregateType{project.AggregateType, instance.AggregateType}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *OrgProjectMapping) CurrentSequence(instanceID string) (uint64, error) {
|
func (p *OrgProjectMapping) CurrentSequence(instanceID string) (uint64, error) {
|
||||||
@@ -96,6 +97,8 @@ func (p *OrgProjectMapping) Reduce(event *es_models.Event) (err error) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
return p.view.ProcessedOrgProjectMappingSequence(event)
|
return p.view.ProcessedOrgProjectMappingSequence(event)
|
||||||
}
|
}
|
||||||
|
case instance.InstanceRemovedEventType:
|
||||||
|
return p.view.DeleteInstanceOrgProjectMappings(event)
|
||||||
default:
|
default:
|
||||||
return p.view.ProcessedOrgProjectMappingSequence(event)
|
return p.view.ProcessedOrgProjectMappingSequence(event)
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,7 @@ import (
|
|||||||
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
|
es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/v1/query"
|
"github.com/zitadel/zitadel/internal/eventstore/v1/query"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/v1/spooler"
|
"github.com/zitadel/zitadel/internal/eventstore/v1/spooler"
|
||||||
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
"github.com/zitadel/zitadel/internal/repository/project"
|
"github.com/zitadel/zitadel/internal/repository/project"
|
||||||
"github.com/zitadel/zitadel/internal/repository/user"
|
"github.com/zitadel/zitadel/internal/repository/user"
|
||||||
view_model "github.com/zitadel/zitadel/internal/user/repository/view/model"
|
view_model "github.com/zitadel/zitadel/internal/user/repository/view/model"
|
||||||
@@ -55,7 +56,7 @@ func (t *RefreshToken) Subscription() *v1.Subscription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *RefreshToken) AggregateTypes() []es_models.AggregateType {
|
func (t *RefreshToken) AggregateTypes() []es_models.AggregateType {
|
||||||
return []es_models.AggregateType{user.AggregateType, project.AggregateType}
|
return []es_models.AggregateType{user.AggregateType, project.AggregateType, instance.AggregateType}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RefreshToken) CurrentSequence(instanceID string) (uint64, error) {
|
func (t *RefreshToken) CurrentSequence(instanceID string) (uint64, error) {
|
||||||
@@ -109,6 +110,8 @@ func (t *RefreshToken) Reduce(event *es_models.Event) (err error) {
|
|||||||
user.UserDeactivatedType,
|
user.UserDeactivatedType,
|
||||||
user.UserRemovedType:
|
user.UserRemovedType:
|
||||||
return t.view.DeleteUserRefreshTokens(event.AggregateID, event.InstanceID, event)
|
return t.view.DeleteUserRefreshTokens(event.AggregateID, event.InstanceID, event)
|
||||||
|
case instance.InstanceRemovedEventType:
|
||||||
|
return t.view.DeleteInstanceRefreshTokens(event)
|
||||||
default:
|
default:
|
||||||
return t.view.ProcessedRefreshTokenSequence(event)
|
return t.view.ProcessedRefreshTokenSequence(event)
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,7 @@ import (
|
|||||||
proj_model "github.com/zitadel/zitadel/internal/project/model"
|
proj_model "github.com/zitadel/zitadel/internal/project/model"
|
||||||
project_es_model "github.com/zitadel/zitadel/internal/project/repository/eventsourcing/model"
|
project_es_model "github.com/zitadel/zitadel/internal/project/repository/eventsourcing/model"
|
||||||
proj_view "github.com/zitadel/zitadel/internal/project/repository/view"
|
proj_view "github.com/zitadel/zitadel/internal/project/repository/view"
|
||||||
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
"github.com/zitadel/zitadel/internal/repository/project"
|
"github.com/zitadel/zitadel/internal/repository/project"
|
||||||
"github.com/zitadel/zitadel/internal/repository/user"
|
"github.com/zitadel/zitadel/internal/repository/user"
|
||||||
user_repo "github.com/zitadel/zitadel/internal/repository/user"
|
user_repo "github.com/zitadel/zitadel/internal/repository/user"
|
||||||
@@ -61,7 +62,7 @@ func (t *Token) Subscription() *v1.Subscription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (_ *Token) AggregateTypes() []es_models.AggregateType {
|
func (_ *Token) AggregateTypes() []es_models.AggregateType {
|
||||||
return []es_models.AggregateType{user.AggregateType, project.AggregateType}
|
return []es_models.AggregateType{user.AggregateType, project.AggregateType, instance.AggregateType}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Token) CurrentSequence(instanceID string) (uint64, error) {
|
func (p *Token) CurrentSequence(instanceID string) (uint64, error) {
|
||||||
@@ -144,6 +145,8 @@ func (t *Token) Reduce(event *es_models.Event) (err error) {
|
|||||||
applicationsIDs = append(applicationsIDs, app.AppID)
|
applicationsIDs = append(applicationsIDs, app.AppID)
|
||||||
}
|
}
|
||||||
return t.view.DeleteApplicationTokens(event, applicationsIDs...)
|
return t.view.DeleteApplicationTokens(event, applicationsIDs...)
|
||||||
|
case instance.InstanceRemovedEventType:
|
||||||
|
return t.view.DeleteInstanceTokens(event)
|
||||||
default:
|
default:
|
||||||
return t.view.ProcessedTokenSequence(event)
|
return t.view.ProcessedTokenSequence(event)
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,7 @@ import (
|
|||||||
org_es_model "github.com/zitadel/zitadel/internal/org/repository/eventsourcing/model"
|
org_es_model "github.com/zitadel/zitadel/internal/org/repository/eventsourcing/model"
|
||||||
"github.com/zitadel/zitadel/internal/org/repository/view"
|
"github.com/zitadel/zitadel/internal/org/repository/view"
|
||||||
query2 "github.com/zitadel/zitadel/internal/query"
|
query2 "github.com/zitadel/zitadel/internal/query"
|
||||||
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
"github.com/zitadel/zitadel/internal/repository/org"
|
"github.com/zitadel/zitadel/internal/repository/org"
|
||||||
user_repo "github.com/zitadel/zitadel/internal/repository/user"
|
user_repo "github.com/zitadel/zitadel/internal/repository/user"
|
||||||
usr_view "github.com/zitadel/zitadel/internal/user/repository/view"
|
usr_view "github.com/zitadel/zitadel/internal/user/repository/view"
|
||||||
@@ -63,7 +64,7 @@ func (u *User) Subscription() *v1.Subscription {
|
|||||||
return u.subscription
|
return u.subscription
|
||||||
}
|
}
|
||||||
func (_ *User) AggregateTypes() []es_models.AggregateType {
|
func (_ *User) AggregateTypes() []es_models.AggregateType {
|
||||||
return []es_models.AggregateType{user_repo.AggregateType, org.AggregateType}
|
return []es_models.AggregateType{user_repo.AggregateType, org.AggregateType, instance.AggregateType}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) CurrentSequence(instanceID string) (uint64, error) {
|
func (u *User) CurrentSequence(instanceID string) (uint64, error) {
|
||||||
@@ -88,6 +89,8 @@ func (u *User) Reduce(event *es_models.Event) (err error) {
|
|||||||
return u.ProcessUser(event)
|
return u.ProcessUser(event)
|
||||||
case org.AggregateType:
|
case org.AggregateType:
|
||||||
return u.ProcessOrg(event)
|
return u.ProcessOrg(event)
|
||||||
|
case instance.AggregateType:
|
||||||
|
return u.ProcessInstance(event)
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -229,6 +232,15 @@ func (u *User) ProcessOrg(event *es_models.Event) (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *User) ProcessInstance(event *es_models.Event) (err error) {
|
||||||
|
switch eventstore.EventType(event.Type) {
|
||||||
|
case instance.InstanceRemovedEventType:
|
||||||
|
return u.view.DeleteInstanceUsers(event)
|
||||||
|
default:
|
||||||
|
return u.view.ProcessedUserSequence(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (u *User) fillLoginNamesOnOrgUsers(event *es_models.Event) error {
|
func (u *User) fillLoginNamesOnOrgUsers(event *es_models.Event) error {
|
||||||
userLoginMustBeDomain, _, domains, err := u.loginNameInformation(context.Background(), event.ResourceOwner, event.InstanceID)
|
userLoginMustBeDomain, _, domains, err := u.loginNameInformation(context.Background(), event.ResourceOwner, event.InstanceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -150,6 +150,8 @@ func (i *ExternalIDP) processIdpConfig(event *es_models.Event) (err error) {
|
|||||||
i.fillConfigData(provider, config)
|
i.fillConfigData(provider, config)
|
||||||
}
|
}
|
||||||
return i.view.PutExternalIDPs(event, exterinalIDPs...)
|
return i.view.PutExternalIDPs(event, exterinalIDPs...)
|
||||||
|
case instance.InstanceRemovedEventType:
|
||||||
|
return i.view.DeleteInstanceExternalIDPs(event)
|
||||||
default:
|
default:
|
||||||
return i.view.ProcessedExternalIDPSequence(event)
|
return i.view.ProcessedExternalIDPSequence(event)
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,7 @@ import (
|
|||||||
org_es_model "github.com/zitadel/zitadel/internal/org/repository/eventsourcing/model"
|
org_es_model "github.com/zitadel/zitadel/internal/org/repository/eventsourcing/model"
|
||||||
"github.com/zitadel/zitadel/internal/org/repository/view"
|
"github.com/zitadel/zitadel/internal/org/repository/view"
|
||||||
query2 "github.com/zitadel/zitadel/internal/query"
|
query2 "github.com/zitadel/zitadel/internal/query"
|
||||||
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
"github.com/zitadel/zitadel/internal/repository/org"
|
"github.com/zitadel/zitadel/internal/repository/org"
|
||||||
"github.com/zitadel/zitadel/internal/repository/user"
|
"github.com/zitadel/zitadel/internal/repository/user"
|
||||||
view_model "github.com/zitadel/zitadel/internal/user/repository/view/model"
|
view_model "github.com/zitadel/zitadel/internal/user/repository/view/model"
|
||||||
@@ -61,7 +62,7 @@ func (u *UserSession) Subscription() *v1.Subscription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (_ *UserSession) AggregateTypes() []models.AggregateType {
|
func (_ *UserSession) AggregateTypes() []models.AggregateType {
|
||||||
return []models.AggregateType{user.AggregateType, org.AggregateType}
|
return []models.AggregateType{user.AggregateType, org.AggregateType, instance.AggregateType}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserSession) CurrentSequence(instanceID string) (uint64, error) {
|
func (u *UserSession) CurrentSequence(instanceID string) (uint64, error) {
|
||||||
@@ -153,6 +154,8 @@ func (u *UserSession) Reduce(event *models.Event) (err error) {
|
|||||||
return u.fillLoginNamesOnOrgUsers(event)
|
return u.fillLoginNamesOnOrgUsers(event)
|
||||||
case user.UserRemovedType:
|
case user.UserRemovedType:
|
||||||
return u.view.DeleteUserSessions(event.AggregateID, event.InstanceID, event)
|
return u.view.DeleteUserSessions(event.AggregateID, event.InstanceID, event)
|
||||||
|
case instance.InstanceRemovedEventType:
|
||||||
|
return u.view.DeleteInstanceUserSessions(event)
|
||||||
default:
|
default:
|
||||||
return u.view.ProcessedUserSessionSequence(event)
|
return u.view.ProcessedUserSessionSequence(event)
|
||||||
}
|
}
|
||||||
|
@@ -56,6 +56,14 @@ func (v *View) DeleteExternalIDPsByUserID(userID, instanceID string, event *mode
|
|||||||
return v.ProcessedExternalIDPSequence(event)
|
return v.ProcessedExternalIDPSequence(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteInstanceExternalIDPs(event *models.Event) error {
|
||||||
|
err := view.DeleteInstanceExternalIDPs(v.Db, externalIDPTable, event.InstanceID)
|
||||||
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedExternalIDPSequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestExternalIDPSequence(instanceID string) (*global_view.CurrentSequence, error) {
|
func (v *View) GetLatestExternalIDPSequence(instanceID string) (*global_view.CurrentSequence, error) {
|
||||||
return v.latestSequence(externalIDPTable, instanceID)
|
return v.latestSequence(externalIDPTable, instanceID)
|
||||||
}
|
}
|
||||||
|
@@ -41,6 +41,14 @@ func (v *View) DeleteIDPConfig(idpID string, event *models.Event) error {
|
|||||||
return v.ProcessedIDPConfigSequence(event)
|
return v.ProcessedIDPConfigSequence(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteInstanceIDPs(event *models.Event) error {
|
||||||
|
err := view.DeleteInstanceIDPs(v.Db, idpConfigTable, event.InstanceID)
|
||||||
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedIDPConfigSequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestIDPConfigSequence(instanceID string) (*global_view.CurrentSequence, error) {
|
func (v *View) GetLatestIDPConfigSequence(instanceID string) (*global_view.CurrentSequence, error) {
|
||||||
return v.latestSequence(idpConfigTable, instanceID)
|
return v.latestSequence(idpConfigTable, instanceID)
|
||||||
}
|
}
|
||||||
|
@@ -61,6 +61,14 @@ func (v *View) DeleteIDPProvidersByAggregateID(aggregateID, instanceID string, e
|
|||||||
return v.ProcessedIDPProviderSequence(event)
|
return v.ProcessedIDPProviderSequence(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteInstanceIDPProviders(event *models.Event) error {
|
||||||
|
err := view.DeleteInstanceIDPProviders(v.Db, idpProviderTable, event.InstanceID)
|
||||||
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedIDPProviderSequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestIDPProviderSequence(instanceID string) (*global_view.CurrentSequence, error) {
|
func (v *View) GetLatestIDPProviderSequence(instanceID string) (*global_view.CurrentSequence, error) {
|
||||||
return v.latestSequence(idpProviderTable, instanceID)
|
return v.latestSequence(idpProviderTable, instanceID)
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,14 @@ func (v *View) DeleteOrgProjectMapping(orgID, projectID, instanceID string, even
|
|||||||
return v.ProcessedOrgProjectMappingSequence(event)
|
return v.ProcessedOrgProjectMappingSequence(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteInstanceOrgProjectMappings(event *models.Event) error {
|
||||||
|
err := view.DeleteInstanceOrgProjectMappings(v.Db, orgPrgojectMappingTable, event.InstanceID)
|
||||||
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedOrgProjectMappingSequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
func (v *View) DeleteOrgProjectMappingsByProjectID(projectID, instanceID string) error {
|
func (v *View) DeleteOrgProjectMappingsByProjectID(projectID, instanceID string) error {
|
||||||
return view.DeleteOrgProjectMappingsByProjectID(v.Db, orgPrgojectMappingTable, projectID, instanceID)
|
return view.DeleteOrgProjectMappingsByProjectID(v.Db, orgPrgojectMappingTable, projectID, instanceID)
|
||||||
}
|
}
|
||||||
|
@@ -65,6 +65,14 @@ func (v *View) DeleteApplicationRefreshTokens(event *models.Event, ids ...string
|
|||||||
return v.ProcessedRefreshTokenSequence(event)
|
return v.ProcessedRefreshTokenSequence(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteInstanceRefreshTokens(event *models.Event) error {
|
||||||
|
err := usr_view.DeleteInstanceRefreshTokens(v.Db, refreshTokenTable, event.InstanceID)
|
||||||
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedRefreshTokenSequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestRefreshTokenSequence(instanceID string) (*repository.CurrentSequence, error) {
|
func (v *View) GetLatestRefreshTokenSequence(instanceID string) (*repository.CurrentSequence, error) {
|
||||||
return v.latestSequence(refreshTokenTable, instanceID)
|
return v.latestSequence(refreshTokenTable, instanceID)
|
||||||
}
|
}
|
||||||
|
@@ -76,6 +76,14 @@ func (v *View) DeleteTokensFromRefreshToken(refreshTokenID, instanceID string, e
|
|||||||
return v.ProcessedTokenSequence(event)
|
return v.ProcessedTokenSequence(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteInstanceTokens(event *models.Event) error {
|
||||||
|
err := usr_view.DeleteInstanceTokens(v.Db, tokenTable, event.InstanceID)
|
||||||
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedTokenSequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestTokenSequence(instanceID string) (*repository.CurrentSequence, error) {
|
func (v *View) GetLatestTokenSequence(instanceID string) (*repository.CurrentSequence, error) {
|
||||||
return v.latestSequence(tokenTable, instanceID)
|
return v.latestSequence(tokenTable, instanceID)
|
||||||
}
|
}
|
||||||
|
@@ -181,6 +181,14 @@ func (v *View) DeleteUser(userID, instanceID string, event *models.Event) error
|
|||||||
return v.ProcessedUserSequence(event)
|
return v.ProcessedUserSequence(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteInstanceUsers(event *models.Event) error {
|
||||||
|
err := view.DeleteInstanceUsers(v.Db, userTable, event.InstanceID)
|
||||||
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedUserSequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestUserSequence(instanceID string) (*repository.CurrentSequence, error) {
|
func (v *View) GetLatestUserSequence(instanceID string) (*repository.CurrentSequence, error) {
|
||||||
return v.latestSequence(userTable, instanceID)
|
return v.latestSequence(userTable, instanceID)
|
||||||
}
|
}
|
||||||
|
@@ -56,6 +56,14 @@ func (v *View) DeleteUserSessions(userID, instanceID string, event *models.Event
|
|||||||
return v.ProcessedUserSessionSequence(event)
|
return v.ProcessedUserSessionSequence(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *View) DeleteInstanceUserSessions(event *models.Event) error {
|
||||||
|
err := view.DeleteInstanceUserSessions(v.Db, userSessionTable, event.InstanceID)
|
||||||
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return v.ProcessedUserSessionSequence(event)
|
||||||
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestUserSessionSequence(instanceID string) (*repository.CurrentSequence, error) {
|
func (v *View) GetLatestUserSessionSequence(instanceID string) (*repository.CurrentSequence, error) {
|
||||||
return v.latestSequence(userSessionTable, instanceID)
|
return v.latestSequence(userSessionTable, instanceID)
|
||||||
}
|
}
|
||||||
|
@@ -550,7 +550,7 @@ func (c *Commands) prepareUpdateInstance(a *instance.Aggregate, name string) pre
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if writeModel.State == domain.InstanceStateUnspecified {
|
if !writeModel.State.Exists() {
|
||||||
return nil, errors.ThrowNotFound(nil, "INST-nuso2m", "Errors.Instance.NotFound")
|
return nil, errors.ThrowNotFound(nil, "INST-nuso2m", "Errors.Instance.NotFound")
|
||||||
}
|
}
|
||||||
if writeModel.Name == name {
|
if writeModel.Name == name {
|
||||||
@@ -631,17 +631,16 @@ func (c *Commands) prepareRemoveInstance(a *instance.Aggregate) preparation.Vali
|
|||||||
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||||
writeModel, err := c.getInstanceWriteModelByID(ctx, a.ID)
|
writeModel, err := c.getInstanceWriteModelByID(ctx, a.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.ThrowPreconditionFailed(err, "COMMA-pax9m3", "Errors.Instance.NotFound")
|
return nil, errors.ThrowNotFound(err, "COMMA-pax9m3", "Errors.Instance.NotFound")
|
||||||
}
|
}
|
||||||
events := []eventstore.Command{instance.NewInstanceRemovedEvent(ctx, &a.Aggregate, writeModel.Name)}
|
if !writeModel.State.Exists() {
|
||||||
|
return nil, errors.ThrowNotFound(err, "COMMA-AE3GS", "Errors.Instance.NotFound")
|
||||||
domainsWriteModel, err := c.getInstanceDomainsWriteModel(ctx, a.ID)
|
|
||||||
if err == nil {
|
|
||||||
for _, domainName := range domainsWriteModel.Domains {
|
|
||||||
events = append(events, instance.NewDomainRemovedEvent(ctx, &a.Aggregate, domainName))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return events, nil
|
return []eventstore.Command{instance.NewInstanceRemovedEvent(ctx,
|
||||||
|
&a.Aggregate,
|
||||||
|
writeModel.Name,
|
||||||
|
writeModel.Domains)},
|
||||||
|
nil
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@ type InstanceWriteModel struct {
|
|||||||
Name string
|
Name string
|
||||||
State domain.InstanceState
|
State domain.InstanceState
|
||||||
GeneratedDomain string
|
GeneratedDomain string
|
||||||
|
Domains []string
|
||||||
|
|
||||||
DefaultOrgID string
|
DefaultOrgID string
|
||||||
ProjectID string
|
ProjectID string
|
||||||
@@ -41,10 +42,16 @@ func (wm *InstanceWriteModel) Reduce() error {
|
|||||||
case *instance.InstanceRemovedEvent:
|
case *instance.InstanceRemovedEvent:
|
||||||
wm.State = domain.InstanceStateRemoved
|
wm.State = domain.InstanceStateRemoved
|
||||||
case *instance.DomainAddedEvent:
|
case *instance.DomainAddedEvent:
|
||||||
if !e.Generated {
|
if e.Generated {
|
||||||
continue
|
wm.GeneratedDomain = e.Domain
|
||||||
|
}
|
||||||
|
wm.Domains = append(wm.Domains, e.Domain)
|
||||||
|
case *instance.DomainRemovedEvent:
|
||||||
|
for _, customDomain := range wm.Domains {
|
||||||
|
if customDomain == e.Domain {
|
||||||
|
wm.Domains = removeDomainFromDomains(wm.Domains, e.Domain)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
wm.GeneratedDomain = e.Domain
|
|
||||||
case *instance.ProjectSetEvent:
|
case *instance.ProjectSetEvent:
|
||||||
wm.ProjectID = e.ProjectID
|
wm.ProjectID = e.ProjectID
|
||||||
case *instance.DefaultOrgSetEvent:
|
case *instance.DefaultOrgSetEvent:
|
||||||
|
@@ -14,14 +14,13 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCommandSide_ChangeInstance(t *testing.T) {
|
func TestCommandSide_UpdateInstance(t *testing.T) {
|
||||||
type fields struct {
|
type fields struct {
|
||||||
eventstore *eventstore.Eventstore
|
eventstore *eventstore.Eventstore
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
name string
|
name string
|
||||||
instanceID string
|
|
||||||
}
|
}
|
||||||
type res struct {
|
type res struct {
|
||||||
want *domain.ObjectDetails
|
want *domain.ObjectDetails
|
||||||
@@ -41,9 +40,8 @@ func TestCommandSide_ChangeInstance(t *testing.T) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
instanceID: "INSTANCE",
|
name: "",
|
||||||
name: "",
|
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: caos_errs.IsErrorInvalidArgument,
|
err: caos_errs.IsErrorInvalidArgument,
|
||||||
@@ -58,17 +56,15 @@ func TestCommandSide_ChangeInstance(t *testing.T) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
instanceID: "INSTANCE",
|
name: "INSTANCE_CHANGED",
|
||||||
name: "INSTANCE_CHANGED",
|
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: caos_errs.IsNotFound,
|
err: caos_errs.IsNotFound,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
/* instance removed is not yet implemented
|
|
||||||
{
|
{
|
||||||
name: "generator removed, not found error",
|
name: "instance removed, not found error",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
eventstore: eventstoreExpect(
|
eventstore: eventstoreExpect(
|
||||||
t,
|
t,
|
||||||
@@ -84,6 +80,7 @@ func TestCommandSide_ChangeInstance(t *testing.T) {
|
|||||||
instance.NewInstanceRemovedEvent(context.Background(),
|
instance.NewInstanceRemovedEvent(context.Background(),
|
||||||
&instance.NewAggregate("INSTANCE").Aggregate,
|
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||||
"INSTANCE",
|
"INSTANCE",
|
||||||
|
nil,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -96,7 +93,7 @@ func TestCommandSide_ChangeInstance(t *testing.T) {
|
|||||||
res: res{
|
res: res{
|
||||||
err: caos_errs.IsNotFound,
|
err: caos_errs.IsNotFound,
|
||||||
},
|
},
|
||||||
},*/
|
},
|
||||||
{
|
{
|
||||||
name: "no changes, precondition error",
|
name: "no changes, precondition error",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@@ -114,9 +111,8 @@ func TestCommandSide_ChangeInstance(t *testing.T) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
instanceID: "INSTANCE",
|
name: "INSTANCE",
|
||||||
name: "INSTANCE",
|
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
err: caos_errs.IsPreconditionFailed,
|
err: caos_errs.IsPreconditionFailed,
|
||||||
@@ -178,3 +174,148 @@ func TestCommandSide_ChangeInstance(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCommandSide_RemoveInstance(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
eventstore *eventstore.Eventstore
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
instanceID string
|
||||||
|
}
|
||||||
|
type res struct {
|
||||||
|
want *domain.ObjectDetails
|
||||||
|
err func(error) bool
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
res res
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "instance not existing, not found error",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(
|
||||||
|
t,
|
||||||
|
expectFilter(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
|
instanceID: "INSTANCE",
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
err: caos_errs.IsNotFound,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "instance removed, not found error",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(
|
||||||
|
t,
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
instance.NewInstanceAddedEvent(
|
||||||
|
context.Background(),
|
||||||
|
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||||
|
"INSTANCE",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
eventFromEventPusher(
|
||||||
|
instance.NewInstanceRemovedEvent(context.Background(),
|
||||||
|
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||||
|
"INSTANCE",
|
||||||
|
nil,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
|
instanceID: "INSTANCE",
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
err: caos_errs.IsNotFound,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "instance remove, ok",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(
|
||||||
|
t,
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusherWithInstanceID(
|
||||||
|
"INSTANCE",
|
||||||
|
instance.NewInstanceAddedEvent(context.Background(),
|
||||||
|
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||||
|
"INSTANCE",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
eventFromEventPusherWithInstanceID(
|
||||||
|
"INSTANCE",
|
||||||
|
instance.NewDomainAddedEvent(context.Background(),
|
||||||
|
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||||
|
"instance.domain",
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
eventFromEventPusherWithInstanceID(
|
||||||
|
"INSTANCE",
|
||||||
|
instance.NewDomainAddedEvent(context.Background(),
|
||||||
|
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||||
|
"custom.domain",
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
expectPush(
|
||||||
|
[]*repository.Event{
|
||||||
|
eventFromEventPusherWithInstanceID(
|
||||||
|
"INSTANCE",
|
||||||
|
instance.NewInstanceRemovedEvent(context.Background(),
|
||||||
|
&instance.NewAggregate("INSTANCE").Aggregate,
|
||||||
|
"INSTANCE",
|
||||||
|
[]string{
|
||||||
|
"instance.domain",
|
||||||
|
"custom.domain",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
uniqueConstraintsFromEventConstraint(instance.NewRemoveInstanceDomainUniqueConstraint("instance.domain")),
|
||||||
|
uniqueConstraintsFromEventConstraint(instance.NewRemoveInstanceDomainUniqueConstraint("custom.domain")),
|
||||||
|
uniqueConstraintsFromEventConstraintWithInstanceID("INSTANCE", eventstore.NewRemoveInstanceUniqueConstraints()),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: authz.WithInstanceID(context.Background(), "INSTANCE"),
|
||||||
|
instanceID: "INSTANCE",
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
want: &domain.ObjectDetails{
|
||||||
|
ResourceOwner: "INSTANCE",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
r := &Commands{
|
||||||
|
eventstore: tt.fields.eventstore,
|
||||||
|
}
|
||||||
|
got, err := r.RemoveInstance(tt.args.ctx, tt.args.instanceID)
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
if tt.res.err != nil && !tt.res.err(err) {
|
||||||
|
t.Errorf("got wrong err: %v ", err)
|
||||||
|
}
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.Equal(t, tt.res.want, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -14,6 +14,10 @@ const (
|
|||||||
instanceStateCount
|
instanceStateCount
|
||||||
)
|
)
|
||||||
|
|
||||||
func (f InstanceState) Valid() bool {
|
func (s InstanceState) Valid() bool {
|
||||||
return f >= 0 && f < instanceStateCount
|
return s >= 0 && s < instanceStateCount
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s InstanceState) Exists() bool {
|
||||||
|
return s != InstanceStateUnspecified && s != InstanceStateRemoved
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Eventstore abstracts all functions needed to store valid events
|
// Eventstore abstracts all functions needed to store valid events
|
||||||
// and filters the stored events
|
// and filters the stored events
|
||||||
type Eventstore struct {
|
type Eventstore struct {
|
||||||
repo repository.Repository
|
repo repository.Repository
|
||||||
@@ -32,13 +32,13 @@ func NewEventstore(repo repository.Repository) *Eventstore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Health checks if the eventstore can properly work
|
// Health checks if the eventstore can properly work
|
||||||
// It checks if the repository can serve load
|
// It checks if the repository can serve load
|
||||||
func (es *Eventstore) Health(ctx context.Context) error {
|
func (es *Eventstore) Health(ctx context.Context) error {
|
||||||
return es.repo.Health(ctx)
|
return es.repo.Health(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Push pushes the events in a single transaction
|
// Push pushes the events in a single transaction
|
||||||
// an event needs at least an aggregate
|
// an event needs at least an aggregate
|
||||||
func (es *Eventstore) Push(ctx context.Context, cmds ...Command) ([]Event, error) {
|
func (es *Eventstore) Push(ctx context.Context, cmds ...Command) ([]Event, error) {
|
||||||
events, constraints, err := commandsToRepository(authz.GetInstance(ctx).InstanceID(), cmds)
|
events, constraints, err := commandsToRepository(authz.GetInstance(ctx).InstanceID(), cmds)
|
||||||
@@ -119,7 +119,7 @@ func uniqueConstraintsToRepository(instanceID string, constraints []*EventUnique
|
|||||||
return uniqueConstraints
|
return uniqueConstraints
|
||||||
}
|
}
|
||||||
|
|
||||||
//Filter filters the stored events based on the searchQuery
|
// Filter filters the stored events based on the searchQuery
|
||||||
// and maps the events to the defined event structs
|
// and maps the events to the defined event structs
|
||||||
func (es *Eventstore) Filter(ctx context.Context, queryFactory *SearchQueryBuilder) ([]Event, error) {
|
func (es *Eventstore) Filter(ctx context.Context, queryFactory *SearchQueryBuilder) ([]Event, error) {
|
||||||
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
|
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
|
||||||
@@ -165,7 +165,7 @@ type reducer interface {
|
|||||||
AppendEvents(...Event)
|
AppendEvents(...Event)
|
||||||
}
|
}
|
||||||
|
|
||||||
//FilterToReducer filters the events based on the search query, appends all events to the reducer and calls it's reduce function
|
// FilterToReducer filters the events based on the search query, appends all events to the reducer and calls it's reduce function
|
||||||
func (es *Eventstore) FilterToReducer(ctx context.Context, searchQuery *SearchQueryBuilder, r reducer) error {
|
func (es *Eventstore) FilterToReducer(ctx context.Context, searchQuery *SearchQueryBuilder, r reducer) error {
|
||||||
events, err := es.Filter(ctx, searchQuery)
|
events, err := es.Filter(ctx, searchQuery)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -177,7 +177,7 @@ func (es *Eventstore) FilterToReducer(ctx context.Context, searchQuery *SearchQu
|
|||||||
return r.Reduce()
|
return r.Reduce()
|
||||||
}
|
}
|
||||||
|
|
||||||
//LatestSequence filters the latest sequence for the given search query
|
// LatestSequence filters the latest sequence for the given search query
|
||||||
func (es *Eventstore) LatestSequence(ctx context.Context, queryFactory *SearchQueryBuilder) (uint64, error) {
|
func (es *Eventstore) LatestSequence(ctx context.Context, queryFactory *SearchQueryBuilder) (uint64, error) {
|
||||||
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
|
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -186,7 +186,7 @@ func (es *Eventstore) LatestSequence(ctx context.Context, queryFactory *SearchQu
|
|||||||
return es.repo.LatestSequence(ctx, query)
|
return es.repo.LatestSequence(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
//InstanceIDs returns the instance ids found by the search query
|
// InstanceIDs returns the instance ids found by the search query
|
||||||
func (es *Eventstore) InstanceIDs(ctx context.Context, queryFactory *SearchQueryBuilder) ([]string, error) {
|
func (es *Eventstore) InstanceIDs(ctx context.Context, queryFactory *SearchQueryBuilder) ([]string, error) {
|
||||||
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
|
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -201,7 +201,7 @@ type QueryReducer interface {
|
|||||||
Query() *SearchQueryBuilder
|
Query() *SearchQueryBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
//FilterToQueryReducer filters the events based on the search query of the query function,
|
// FilterToQueryReducer filters the events based on the search query of the query function,
|
||||||
// appends all events to the reducer and calls it's reduce function
|
// appends all events to the reducer and calls it's reduce function
|
||||||
func (es *Eventstore) FilterToQueryReducer(ctx context.Context, r QueryReducer) error {
|
func (es *Eventstore) FilterToQueryReducer(ctx context.Context, r QueryReducer) error {
|
||||||
events, err := es.Filter(ctx, r.Query())
|
events, err := es.Filter(ctx, r.Query())
|
||||||
@@ -213,7 +213,7 @@ func (es *Eventstore) FilterToQueryReducer(ctx context.Context, r QueryReducer)
|
|||||||
return r.Reduce()
|
return r.Reduce()
|
||||||
}
|
}
|
||||||
|
|
||||||
//RegisterFilterEventMapper registers a function for mapping an eventstore event to an event
|
// RegisterFilterEventMapper registers a function for mapping an eventstore event to an event
|
||||||
func (es *Eventstore) RegisterFilterEventMapper(eventType EventType, mapper func(*repository.Event) (Event, error)) *Eventstore {
|
func (es *Eventstore) RegisterFilterEventMapper(eventType EventType, mapper func(*repository.Event) (Event, error)) *Eventstore {
|
||||||
if mapper == nil || eventType == "" {
|
if mapper == nil || eventType == "" {
|
||||||
return es
|
return es
|
||||||
@@ -258,6 +258,8 @@ func uniqueConstraintActionToRepository(action UniqueConstraintAction) repositor
|
|||||||
return repository.UniqueConstraintAdd
|
return repository.UniqueConstraintAdd
|
||||||
case UniqueConstraintRemove:
|
case UniqueConstraintRemove:
|
||||||
return repository.UniqueConstraintRemoved
|
return repository.UniqueConstraintRemoved
|
||||||
|
case UniqueConstraintInstanceRemove:
|
||||||
|
return repository.UniqueConstraintInstanceRemoved
|
||||||
default:
|
default:
|
||||||
return repository.UniqueConstraintAdd
|
return repository.UniqueConstraintAdd
|
||||||
}
|
}
|
||||||
|
@@ -92,6 +92,8 @@ const (
|
|||||||
|
|
||||||
uniqueDelete = `DELETE FROM eventstore.unique_constraints
|
uniqueDelete = `DELETE FROM eventstore.unique_constraints
|
||||||
WHERE unique_type = $1 and unique_field = $2 and instance_id = $3`
|
WHERE unique_type = $1 and unique_field = $2 and instance_id = $3`
|
||||||
|
uniqueDeleteInstance = `DELETE FROM eventstore.unique_constraints
|
||||||
|
WHERE instance_id = $1`
|
||||||
)
|
)
|
||||||
|
|
||||||
type CRDB struct {
|
type CRDB struct {
|
||||||
@@ -193,7 +195,7 @@ func (db *CRDB) handleUniqueConstraints(ctx context.Context, tx *sql.Tx, uniqueC
|
|||||||
return caos_errs.ThrowAlreadyExists(err, "SQL-M0dsf", uniqueConstraint.ErrorMessage)
|
return caos_errs.ThrowAlreadyExists(err, "SQL-M0dsf", uniqueConstraint.ErrorMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
return caos_errs.ThrowInternal(err, "SQL-dM9ds", "unable to create unique constraint ")
|
return caos_errs.ThrowInternal(err, "SQL-dM9ds", "unable to create unique constraint")
|
||||||
}
|
}
|
||||||
case repository.UniqueConstraintRemoved:
|
case repository.UniqueConstraintRemoved:
|
||||||
_, err := tx.ExecContext(ctx, uniqueDelete, uniqueConstraint.UniqueType, uniqueConstraint.UniqueField, uniqueConstraint.InstanceID)
|
_, err := tx.ExecContext(ctx, uniqueDelete, uniqueConstraint.UniqueType, uniqueConstraint.UniqueField, uniqueConstraint.InstanceID)
|
||||||
@@ -201,7 +203,14 @@ func (db *CRDB) handleUniqueConstraints(ctx context.Context, tx *sql.Tx, uniqueC
|
|||||||
logging.WithFields(
|
logging.WithFields(
|
||||||
"unique_type", uniqueConstraint.UniqueType,
|
"unique_type", uniqueConstraint.UniqueType,
|
||||||
"unique_field", uniqueConstraint.UniqueField).WithError(err).Info("delete unique constraint failed")
|
"unique_field", uniqueConstraint.UniqueField).WithError(err).Info("delete unique constraint failed")
|
||||||
return caos_errs.ThrowInternal(err, "SQL-6n88i", "unable to remove unique constraint ")
|
return caos_errs.ThrowInternal(err, "SQL-6n88i", "unable to remove unique constraint")
|
||||||
|
}
|
||||||
|
case repository.UniqueConstraintInstanceRemoved:
|
||||||
|
_, err := tx.ExecContext(ctx, uniqueDeleteInstance, uniqueConstraint.InstanceID)
|
||||||
|
if err != nil {
|
||||||
|
logging.WithFields(
|
||||||
|
"instance_id", uniqueConstraint.InstanceID).WithError(err).Info("delete instance unique constraints failed")
|
||||||
|
return caos_errs.ThrowInternal(err, "SQL-6n88i", "unable to remove unique constraints of instance")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -379,24 +379,28 @@ func TestCRDB_Push_OneAggregate(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "push 1 event and add asset",
|
name: "push 1 event and remove instance unique constraints",
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
events: []*repository.Event{
|
events: []*repository.Event{
|
||||||
generateEvent(t, "12"),
|
generateEvent(t, "12"),
|
||||||
},
|
},
|
||||||
|
uniqueConstraints: generateRemoveInstanceUniqueConstraints(t, "instanceID"),
|
||||||
|
uniqueDataType: "usernames",
|
||||||
|
uniqueDataField: "testremove",
|
||||||
|
uniqueDataInstanceID: "instanceID",
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
eventsRes: eventsRes{
|
eventsRes: eventsRes{
|
||||||
pushedEventsCount: 1,
|
pushedEventsCount: 1,
|
||||||
assetCount: 1,
|
uniqueCount: 0,
|
||||||
aggID: []string{"12"},
|
aggID: []string{"12"},
|
||||||
aggType: repository.AggregateType(t.Name()),
|
aggType: repository.AggregateType(t.Name()),
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "push 1 event and remove asset",
|
name: "push 1 event and add asset",
|
||||||
args: args{
|
args: args{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
events: []*repository.Event{
|
events: []*repository.Event{
|
||||||
@@ -407,11 +411,28 @@ func TestCRDB_Push_OneAggregate(t *testing.T) {
|
|||||||
wantErr: false,
|
wantErr: false,
|
||||||
eventsRes: eventsRes{
|
eventsRes: eventsRes{
|
||||||
pushedEventsCount: 1,
|
pushedEventsCount: 1,
|
||||||
assetCount: 0,
|
assetCount: 1,
|
||||||
aggID: []string{"13"},
|
aggID: []string{"13"},
|
||||||
aggType: repository.AggregateType(t.Name()),
|
aggType: repository.AggregateType(t.Name()),
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "push 1 event and remove asset",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
events: []*repository.Event{
|
||||||
|
generateEvent(t, "14"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
wantErr: false,
|
||||||
|
eventsRes: eventsRes{
|
||||||
|
pushedEventsCount: 1,
|
||||||
|
assetCount: 0,
|
||||||
|
aggID: []string{"14"},
|
||||||
|
aggType: repository.AggregateType(t.Name()),
|
||||||
|
}},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
@@ -1201,3 +1222,13 @@ func generateRemoveUniqueConstraint(t *testing.T, table, uniqueField string) *re
|
|||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateRemoveInstanceUniqueConstraints(t *testing.T, instanceID string) *repository.UniqueConstraint {
|
||||||
|
t.Helper()
|
||||||
|
e := &repository.UniqueConstraint{
|
||||||
|
InstanceID: instanceID,
|
||||||
|
Action: repository.UniqueConstraintInstanceRemoved,
|
||||||
|
}
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
//UniqueCheck represents all information about a unique attribute
|
// UniqueCheck represents all information about a unique attribute
|
||||||
type UniqueConstraint struct {
|
type UniqueConstraint struct {
|
||||||
//UniqueField is the field which should be unique
|
//UniqueField is the field which should be unique
|
||||||
UniqueField string
|
UniqueField string
|
||||||
@@ -23,6 +23,7 @@ type UniqueConstraintAction int32
|
|||||||
const (
|
const (
|
||||||
UniqueConstraintAdd UniqueConstraintAction = iota
|
UniqueConstraintAdd UniqueConstraintAction = iota
|
||||||
UniqueConstraintRemoved
|
UniqueConstraintRemoved
|
||||||
|
UniqueConstraintInstanceRemoved
|
||||||
|
|
||||||
uniqueConstraintActionCount
|
uniqueConstraintActionCount
|
||||||
)
|
)
|
||||||
|
@@ -18,6 +18,7 @@ type UniqueConstraintAction int32
|
|||||||
const (
|
const (
|
||||||
UniqueConstraintAdd UniqueConstraintAction = iota
|
UniqueConstraintAdd UniqueConstraintAction = iota
|
||||||
UniqueConstraintRemove
|
UniqueConstraintRemove
|
||||||
|
UniqueConstraintInstanceRemove
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewAddEventUniqueConstraint(
|
func NewAddEventUniqueConstraint(
|
||||||
@@ -42,6 +43,12 @@ func NewRemoveEventUniqueConstraint(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewRemoveInstanceUniqueConstraints() *EventUniqueConstraint {
|
||||||
|
return &EventUniqueConstraint{
|
||||||
|
Action: UniqueConstraintInstanceRemove,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func NewAddGlobalEventUniqueConstraint(
|
func NewAddGlobalEventUniqueConstraint(
|
||||||
uniqueType,
|
uniqueType,
|
||||||
uniqueField,
|
uniqueField,
|
||||||
|
@@ -112,3 +112,8 @@ func DeleteIDPProvidersByAggregateID(db *gorm.DB, table, aggregateID, instanceID
|
|||||||
)
|
)
|
||||||
return delete(db)
|
return delete(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeleteInstanceIDPProviders(db *gorm.DB, table, instanceID string) error {
|
||||||
|
delete := repository.PrepareDeleteByKey(table, model.IDPProviderSearchKey(iam_model.IDPProviderSearchKeyInstanceID), instanceID)
|
||||||
|
return delete(db)
|
||||||
|
}
|
||||||
|
@@ -63,6 +63,10 @@ func DeleteIDP(db *gorm.DB, table, idpID, instanceID string) error {
|
|||||||
repository.Key{model.IDPConfigSearchKey(iam_model.IDPConfigSearchKeyIdpConfigID), idpID},
|
repository.Key{model.IDPConfigSearchKey(iam_model.IDPConfigSearchKeyIdpConfigID), idpID},
|
||||||
repository.Key{model.IDPConfigSearchKey(iam_model.IDPConfigSearchKeyInstanceID), instanceID},
|
repository.Key{model.IDPConfigSearchKey(iam_model.IDPConfigSearchKeyInstanceID), instanceID},
|
||||||
)
|
)
|
||||||
|
return delete(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteInstanceIDPs(db *gorm.DB, table, instanceID string) error {
|
||||||
|
delete := repository.PrepareDeleteByKey(table, model.IDPConfigSearchKey(iam_model.IDPConfigSearchKeyInstanceID), instanceID)
|
||||||
return delete(db)
|
return delete(db)
|
||||||
}
|
}
|
||||||
|
@@ -28,8 +28,7 @@ func PutStyling(db *gorm.DB, table string, policy *model.LabelPolicyView) error
|
|||||||
return save(db, policy)
|
return save(db, policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteStyling(db *gorm.DB, table, aggregateID string) error {
|
func DeleteInstanceStyling(db *gorm.DB, table, instanceID string) error {
|
||||||
delete := repository.PrepareDeleteByKey(table, model.LabelPolicySearchKey(iam_model.LabelPolicySearchKeyAggregateID), aggregateID)
|
delete := repository.PrepareDeleteByKey(table, model.LabelPolicySearchKey(iam_model.LabelPolicySearchKeyInstanceID), instanceID)
|
||||||
|
|
||||||
return delete(db)
|
return delete(db)
|
||||||
}
|
}
|
||||||
|
@@ -37,6 +37,11 @@ func DeleteOrgProjectMapping(db *gorm.DB, table, orgID, projectID, instanceID st
|
|||||||
return delete(db)
|
return delete(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeleteInstanceOrgProjectMappings(db *gorm.DB, table, instanceID string) error {
|
||||||
|
delete := repository.PrepareDeleteByKey(table, model.OrgProjectMappingSearchKey(proj_model.OrgProjectMappingSearchKeyInstanceID), instanceID)
|
||||||
|
return delete(db)
|
||||||
|
}
|
||||||
|
|
||||||
func DeleteOrgProjectMappingsByProjectID(db *gorm.DB, table, projectID, instanceID string) error {
|
func DeleteOrgProjectMappingsByProjectID(db *gorm.DB, table, projectID, instanceID string) error {
|
||||||
delete := repository.PrepareDeleteByKeys(table,
|
delete := repository.PrepareDeleteByKeys(table,
|
||||||
repository.Key{model.OrgProjectMappingSearchKey(proj_model.OrgProjectMappingSearchKeyProjectID), projectID},
|
repository.Key{model.OrgProjectMappingSearchKey(proj_model.OrgProjectMappingSearchKeyProjectID), projectID},
|
||||||
|
@@ -179,7 +179,7 @@ func TestActionProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(ActionInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(ActionInstanceIDCol),
|
||||||
|
@@ -220,7 +220,7 @@ func TestAppProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(AppColumnInstanceID),
|
reduce: reduceInstanceRemovedHelper(AppColumnInstanceID),
|
||||||
|
@@ -226,7 +226,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(AuthNKeyInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(AuthNKeyInstanceIDCol),
|
||||||
|
@@ -132,7 +132,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(CustomTextInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(CustomTextInstanceIDCol),
|
||||||
|
@@ -217,7 +217,7 @@ func TestDebugNotificationProviderProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(DebugNotificationProviderInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(DebugNotificationProviderInstanceIDCol),
|
||||||
|
@@ -129,7 +129,7 @@ func TestDomainPolicyProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(DomainPolicyInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(DomainPolicyInstanceIDCol),
|
||||||
|
@@ -109,7 +109,7 @@ func TestFlowProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(FlowInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(FlowInstanceIDCol),
|
||||||
|
@@ -190,7 +190,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(IDPUserLinkInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(IDPUserLinkInstanceIDCol),
|
||||||
|
@@ -201,7 +201,7 @@ func TestIDPProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(IDPInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(IDPInstanceIDCol),
|
||||||
|
@@ -154,7 +154,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(IDPUserLinkInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(IDPUserLinkInstanceIDCol),
|
||||||
|
@@ -85,7 +85,7 @@ func TestInstanceDomainProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(InstanceDomainInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(InstanceDomainInstanceIDCol),
|
||||||
|
@@ -178,7 +178,7 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(MemberInstanceID),
|
reduce: reduceInstanceRemovedHelper(MemberInstanceID),
|
||||||
|
@@ -56,7 +56,7 @@ func TestInstanceProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(InstanceColumnID),
|
reduce: reduceInstanceRemovedHelper(InstanceColumnID),
|
||||||
|
@@ -106,7 +106,7 @@ func TestKeyProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(KeyColumnInstanceID),
|
reduce: reduceInstanceRemovedHelper(KeyColumnInstanceID),
|
||||||
|
@@ -131,7 +131,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(LabelPolicyInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(LabelPolicyInstanceIDCol),
|
||||||
|
@@ -125,7 +125,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(LockoutPolicyInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(LockoutPolicyInstanceIDCol),
|
||||||
|
@@ -213,7 +213,7 @@ func (p *loginNameProjection) reducers() []handler.AggregateReducer {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Event: instance.InstanceRemovedEventType,
|
Event: instance.InstanceRemovedEventType,
|
||||||
Reduce: reduceInstanceRemovedHelper(LoginNameUserInstanceIDCol),
|
Reduce: p.reduceInstanceRemoved,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -432,3 +432,32 @@ func (p *loginNameProjection) reduceDomainRemoved(event eventstore.Event) (*hand
|
|||||||
crdb.WithTableSuffix(loginNameDomainSuffix),
|
crdb.WithTableSuffix(loginNameDomainSuffix),
|
||||||
), nil
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *loginNameProjection) reduceInstanceRemoved(event eventstore.Event) (*handler.Statement, error) {
|
||||||
|
e, ok := event.(*instance.InstanceRemovedEvent)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-ASeg3", "reduce.wrong.event.type %s", instance.InstanceRemovedEventType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return crdb.NewMultiStatement(
|
||||||
|
event,
|
||||||
|
crdb.AddDeleteStatement(
|
||||||
|
[]handler.Condition{
|
||||||
|
handler.NewCond(LoginNameDomainInstanceIDCol, e.Aggregate().ID),
|
||||||
|
},
|
||||||
|
crdb.WithTableSuffix(loginNameDomainSuffix),
|
||||||
|
),
|
||||||
|
crdb.AddDeleteStatement(
|
||||||
|
[]handler.Condition{
|
||||||
|
handler.NewCond(LoginNamePoliciesInstanceIDCol, e.Aggregate().ID),
|
||||||
|
},
|
||||||
|
crdb.WithTableSuffix(loginNamePolicySuffix),
|
||||||
|
),
|
||||||
|
crdb.AddDeleteStatement(
|
||||||
|
[]handler.Condition{
|
||||||
|
handler.NewCond(LoginNameUserInstanceIDCol, e.Aggregate().ID),
|
||||||
|
},
|
||||||
|
crdb.WithTableSuffix(loginNameUserSuffix),
|
||||||
|
),
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
@@ -486,10 +486,10 @@ func TestLoginNameProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(LoginNameUserInstanceIDCol),
|
reduce: (&loginNameProjection{}).reduceInstanceRemoved,
|
||||||
want: wantReduce{
|
want: wantReduce{
|
||||||
aggregateType: eventstore.AggregateType("instance"),
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
sequence: 15,
|
sequence: 15,
|
||||||
@@ -497,7 +497,19 @@ func TestLoginNameProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "DELETE FROM projections.login_names WHERE (instance_id = $1)",
|
expectedStmt: "DELETE FROM projections.login_names_domains WHERE (instance_id = $1)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"agg-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expectedStmt: "DELETE FROM projections.login_names_policies WHERE (instance_id = $1)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"agg-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expectedStmt: "DELETE FROM projections.login_names_users WHERE (instance_id = $1)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"agg-id",
|
"agg-id",
|
||||||
},
|
},
|
||||||
|
@@ -543,7 +543,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(LoginPolicyInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(LoginPolicyInstanceIDCol),
|
||||||
|
@@ -82,11 +82,6 @@ func (p *mailTemplateProjection) reducers() []handler.AggregateReducer {
|
|||||||
Event: instance.MailTemplateChangedEventType,
|
Event: instance.MailTemplateChangedEventType,
|
||||||
Reduce: p.reduceChanged,
|
Reduce: p.reduceChanged,
|
||||||
},
|
},
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Aggregate: instance.AggregateType,
|
|
||||||
EventRedusers: []handler.EventReducer{
|
|
||||||
{
|
{
|
||||||
Event: instance.InstanceRemovedEventType,
|
Event: instance.InstanceRemovedEventType,
|
||||||
Reduce: reduceInstanceRemovedHelper(MailTemplateInstanceIDCol),
|
Reduce: reduceInstanceRemovedHelper(MailTemplateInstanceIDCol),
|
||||||
|
@@ -120,7 +120,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(MailTemplateInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(MailTemplateInstanceIDCol),
|
||||||
|
@@ -336,7 +336,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(MessageTextInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(MessageTextInstanceIDCol),
|
||||||
|
@@ -66,11 +66,6 @@ func (p *oidcSettingsProjection) reducers() []handler.AggregateReducer {
|
|||||||
Event: instance.OIDCSettingsChangedEventType,
|
Event: instance.OIDCSettingsChangedEventType,
|
||||||
Reduce: p.reduceOIDCSettingsChanged,
|
Reduce: p.reduceOIDCSettingsChanged,
|
||||||
},
|
},
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Aggregate: instance.AggregateType,
|
|
||||||
EventRedusers: []handler.EventReducer{
|
|
||||||
{
|
{
|
||||||
Event: instance.InstanceRemovedEventType,
|
Event: instance.InstanceRemovedEventType,
|
||||||
Reduce: reduceInstanceRemovedHelper(OIDCSettingsColumnInstanceID),
|
Reduce: reduceInstanceRemovedHelper(OIDCSettingsColumnInstanceID),
|
||||||
|
@@ -94,7 +94,7 @@ func TestOIDCSettingsProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(OIDCSettingsColumnInstanceID),
|
reduce: reduceInstanceRemovedHelper(OIDCSettingsColumnInstanceID),
|
||||||
|
@@ -194,7 +194,7 @@ func TestOrgDomainProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(OrgDomainInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(OrgDomainInstanceIDCol),
|
||||||
|
@@ -208,7 +208,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(MemberInstanceID),
|
reduce: reduceInstanceRemovedHelper(MemberInstanceID),
|
||||||
|
@@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/handler"
|
"github.com/zitadel/zitadel/internal/eventstore/handler"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
|
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
|
||||||
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
"github.com/zitadel/zitadel/internal/repository/org"
|
"github.com/zitadel/zitadel/internal/repository/org"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -73,6 +74,15 @@ func (p *orgMetadataProjection) reducers() []handler.AggregateReducer {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Aggregate: instance.AggregateType,
|
||||||
|
EventRedusers: []handler.EventReducer{
|
||||||
|
{
|
||||||
|
Event: instance.InstanceRemovedEventType,
|
||||||
|
Reduce: reduceInstanceRemovedHelper(OrgMetadataColumnInstanceID),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/handler"
|
"github.com/zitadel/zitadel/internal/eventstore/handler"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
"github.com/zitadel/zitadel/internal/eventstore/repository"
|
||||||
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
"github.com/zitadel/zitadel/internal/repository/org"
|
"github.com/zitadel/zitadel/internal/repository/org"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -137,6 +138,32 @@ func TestOrgMetadataProjection_reduces(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "reduceInstanceRemoved",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(testEvent(
|
||||||
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
|
instance.AggregateType,
|
||||||
|
nil,
|
||||||
|
), instance.InstanceRemovedEventMapper),
|
||||||
|
},
|
||||||
|
reduce: reduceInstanceRemovedHelper(MemberInstanceID),
|
||||||
|
want: wantReduce{
|
||||||
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
|
sequence: 15,
|
||||||
|
previousSequence: 10,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "DELETE FROM projections.org_metadata WHERE (instance_id = $1)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"agg-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
@@ -194,7 +194,7 @@ func TestOrgProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(OrgColumnInstanceID),
|
reduce: reduceInstanceRemovedHelper(OrgColumnInstanceID),
|
||||||
|
@@ -125,7 +125,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(AgePolicyInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(AgePolicyInstanceIDCol),
|
||||||
|
@@ -137,7 +137,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(ComplexityPolicyInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(ComplexityPolicyInstanceIDCol),
|
||||||
|
@@ -128,7 +128,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(PrivacyPolicyInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(PrivacyPolicyInstanceIDCol),
|
||||||
|
@@ -216,7 +216,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(MemberInstanceID),
|
reduce: reduceInstanceRemovedHelper(MemberInstanceID),
|
||||||
|
@@ -55,7 +55,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(ProjectGrantColumnInstanceID),
|
reduce: reduceInstanceRemovedHelper(ProjectGrantColumnInstanceID),
|
||||||
|
@@ -209,7 +209,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(MemberInstanceID),
|
reduce: reduceInstanceRemovedHelper(MemberInstanceID),
|
||||||
|
@@ -53,7 +53,7 @@ func TestProjectRoleProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(ProjectRoleColumnInstanceID),
|
reduce: reduceInstanceRemovedHelper(ProjectRoleColumnInstanceID),
|
||||||
|
@@ -54,7 +54,7 @@ func TestProjectProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(ProjectColumnInstanceID),
|
reduce: reduceInstanceRemovedHelper(ProjectColumnInstanceID),
|
||||||
|
@@ -76,6 +76,10 @@ func (p *secretGeneratorProjection) reducers() []handler.AggregateReducer {
|
|||||||
Event: instance.SecretGeneratorRemovedEventType,
|
Event: instance.SecretGeneratorRemovedEventType,
|
||||||
Reduce: p.reduceSecretGeneratorRemoved,
|
Reduce: p.reduceSecretGeneratorRemoved,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Event: instance.InstanceRemovedEventType,
|
||||||
|
Reduce: reduceInstanceRemovedHelper(SecretGeneratorColumnInstanceID),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@@ -122,6 +122,32 @@ func TestSecretGeneratorProjection_reduces(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "reduceInstanceRemoved",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(testEvent(
|
||||||
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
|
instance.AggregateType,
|
||||||
|
nil,
|
||||||
|
), instance.InstanceRemovedEventMapper),
|
||||||
|
},
|
||||||
|
reduce: reduceInstanceRemovedHelper(MemberInstanceID),
|
||||||
|
want: wantReduce{
|
||||||
|
aggregateType: eventstore.AggregateType("instance"),
|
||||||
|
sequence: 15,
|
||||||
|
previousSequence: 10,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "DELETE FROM projections.secret_generators2 WHERE (instance_id = $1)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"agg-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
@@ -271,7 +271,7 @@ func TestSMSProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(SMSColumnInstanceID),
|
reduce: reduceInstanceRemovedHelper(SMSColumnInstanceID),
|
||||||
|
@@ -151,7 +151,7 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(SMTPConfigColumnInstanceID),
|
reduce: reduceInstanceRemovedHelper(SMTPConfigColumnInstanceID),
|
||||||
|
@@ -244,7 +244,7 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(UserAuthMethodInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(UserAuthMethodInstanceIDCol),
|
||||||
|
@@ -159,7 +159,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(UserGrantInstanceID),
|
reduce: reduceInstanceRemovedHelper(UserGrantInstanceID),
|
||||||
|
@@ -144,7 +144,7 @@ func TestUserMetadataProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(UserMetadataColumnInstanceID),
|
reduce: reduceInstanceRemovedHelper(UserMetadataColumnInstanceID),
|
||||||
|
@@ -115,7 +115,7 @@ func TestPersonalAccessTokenProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(PersonalAccessTokenColumnInstanceID),
|
reduce: reduceInstanceRemovedHelper(PersonalAccessTokenColumnInstanceID),
|
||||||
|
@@ -1623,7 +1623,7 @@ func TestUserProjection_reduces(t *testing.T) {
|
|||||||
event: getEvent(testEvent(
|
event: getEvent(testEvent(
|
||||||
repository.EventType(instance.InstanceRemovedEventType),
|
repository.EventType(instance.InstanceRemovedEventType),
|
||||||
instance.AggregateType,
|
instance.AggregateType,
|
||||||
[]byte(`{"name": "Name"}`),
|
nil,
|
||||||
), instance.InstanceRemovedEventMapper),
|
), instance.InstanceRemovedEventMapper),
|
||||||
},
|
},
|
||||||
reduce: reduceInstanceRemovedHelper(UserInstanceIDCol),
|
reduce: reduceInstanceRemovedHelper(UserInstanceIDCol),
|
||||||
|
@@ -92,35 +92,36 @@ func InstanceChangedEventMapper(event *repository.Event) (eventstore.Event, erro
|
|||||||
type InstanceRemovedEvent struct {
|
type InstanceRemovedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
name string
|
name string
|
||||||
|
domains []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *InstanceRemovedEvent) Data() interface{} {
|
func (e *InstanceRemovedEvent) Data() interface{} {
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *InstanceRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInstanceRemovedEvent(ctx context.Context, aggregate *eventstore.Aggregate, name string) *InstanceRemovedEvent {
|
func (e *InstanceRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||||
|
constraints := make([]*eventstore.EventUniqueConstraint, len(e.domains)+1)
|
||||||
|
for i, domain := range e.domains {
|
||||||
|
constraints[i] = NewRemoveInstanceDomainUniqueConstraint(domain)
|
||||||
|
}
|
||||||
|
constraints[len(e.domains)] = eventstore.NewRemoveInstanceUniqueConstraints()
|
||||||
|
return constraints
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInstanceRemovedEvent(ctx context.Context, aggregate *eventstore.Aggregate, name string, domains []string) *InstanceRemovedEvent {
|
||||||
return &InstanceRemovedEvent{
|
return &InstanceRemovedEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
aggregate,
|
aggregate,
|
||||||
InstanceRemovedEventType,
|
InstanceRemovedEventType,
|
||||||
),
|
),
|
||||||
name: name,
|
name: name,
|
||||||
|
domains: domains,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func InstanceRemovedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
func InstanceRemovedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||||
instanceRemoved := &InstanceRemovedEvent{
|
return &InstanceRemovedEvent{
|
||||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
}
|
}, nil
|
||||||
err := json.Unmarshal(event.Data, instanceRemoved)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.ThrowInternal(err, "INSTANCE-39jlW", "unable to unmarshal instance removed")
|
|
||||||
}
|
|
||||||
|
|
||||||
return instanceRemoved, nil
|
|
||||||
}
|
}
|
||||||
|
@@ -180,3 +180,20 @@ func (c *crdbStorage) RemoveObjects(ctx context.Context, instanceID, resourceOwn
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *crdbStorage) RemoveInstanceObjects(ctx context.Context, instanceID string) error {
|
||||||
|
stmt, args, err := squirrel.Delete(assetsTable).
|
||||||
|
Where(squirrel.Eq{
|
||||||
|
AssetColInstanceID: instanceID,
|
||||||
|
}).
|
||||||
|
PlaceholderFormat(squirrel.Dollar).
|
||||||
|
ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return caos_errors.ThrowInternal(err, "DATAB-Sfgeq", "Errors.Internal")
|
||||||
|
}
|
||||||
|
_, err = c.client.ExecContext(ctx, stmt, args...)
|
||||||
|
if err != nil {
|
||||||
|
return caos_errors.ThrowInternal(err, "DATAB-Efgt2", "Errors.Assets.Object.RemoveFailed")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@@ -35,6 +35,8 @@ const (
|
|||||||
" WHERE asset_type = $1" +
|
" WHERE asset_type = $1" +
|
||||||
" AND instance_id = $2" +
|
" AND instance_id = $2" +
|
||||||
" AND resource_owner = $3"
|
" AND resource_owner = $3"
|
||||||
|
removeInstanceObjectsStmt = "DELETE FROM system.assets" +
|
||||||
|
" WHERE instance_id = $1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_crdbStorage_CreateObject(t *testing.T) {
|
func Test_crdbStorage_CreateObject(t *testing.T) {
|
||||||
@@ -224,6 +226,50 @@ func Test_crdbStorage_RemoveObjects(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func Test_crdbStorage_RemoveInstanceObjects(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
client db
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
instanceID string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"remove ok",
|
||||||
|
fields{
|
||||||
|
client: prepareDB(t,
|
||||||
|
expectExec(
|
||||||
|
removeInstanceObjectsStmt,
|
||||||
|
nil,
|
||||||
|
"instanceID",
|
||||||
|
)),
|
||||||
|
},
|
||||||
|
args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
instanceID: "instanceID",
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
c := &crdbStorage{
|
||||||
|
client: tt.fields.client.db,
|
||||||
|
}
|
||||||
|
err := c.RemoveInstanceObjects(tt.args.ctx, tt.args.instanceID)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("RemoveInstanceObjects() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type db struct {
|
type db struct {
|
||||||
mock sqlmock.Sqlmock
|
mock sqlmock.Sqlmock
|
||||||
|
@@ -82,6 +82,20 @@ func (mr *MockStorageMockRecorder) PutObject(ctx, instanceID, location, resource
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObject", reflect.TypeOf((*MockStorage)(nil).PutObject), ctx, instanceID, location, resourceOwner, name, contentType, objectType, object, objectSize)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObject", reflect.TypeOf((*MockStorage)(nil).PutObject), ctx, instanceID, location, resourceOwner, name, contentType, objectType, object, objectSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveInstanceObjects mocks base method.
|
||||||
|
func (m *MockStorage) RemoveInstanceObjects(ctx context.Context, instanceID string) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "RemoveInstanceObjects", ctx, instanceID)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveInstanceObjects indicates an expected call of RemoveInstanceObjects.
|
||||||
|
func (mr *MockStorageMockRecorder) RemoveInstanceObjects(ctx, instanceID interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveInstanceObjects", reflect.TypeOf((*MockStorage)(nil).RemoveInstanceObjects), ctx, instanceID)
|
||||||
|
}
|
||||||
|
|
||||||
// RemoveObject mocks base method.
|
// RemoveObject mocks base method.
|
||||||
func (m *MockStorage) RemoveObject(ctx context.Context, instanceID, resourceOwner, name string) error {
|
func (m *MockStorage) RemoveObject(ctx context.Context, instanceID, resourceOwner, name string) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
@@ -136,6 +136,11 @@ func (m *Minio) RemoveObjects(ctx context.Context, instanceID, resourceOwner str
|
|||||||
return g.Wait()
|
return g.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Minio) RemoveInstanceObjects(ctx context.Context, instanceID string) error {
|
||||||
|
bucketName := m.prefixBucketName(instanceID)
|
||||||
|
return m.Client.RemoveBucket(ctx, bucketName)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Minio) createBucket(ctx context.Context, name, location string) error {
|
func (m *Minio) createBucket(ctx context.Context, name, location string) error {
|
||||||
if location == "" {
|
if location == "" {
|
||||||
location = m.Location
|
location = m.Location
|
||||||
|
@@ -15,6 +15,7 @@ type Storage interface {
|
|||||||
GetObjectInfo(ctx context.Context, instanceID, resourceOwner, name string) (*Asset, error)
|
GetObjectInfo(ctx context.Context, instanceID, resourceOwner, name string) (*Asset, error)
|
||||||
RemoveObject(ctx context.Context, instanceID, resourceOwner, name string) error
|
RemoveObject(ctx context.Context, instanceID, resourceOwner, name string) error
|
||||||
RemoveObjects(ctx context.Context, instanceID, resourceOwner string, objectType ObjectType) error
|
RemoveObjects(ctx context.Context, instanceID, resourceOwner string, objectType ObjectType) error
|
||||||
|
RemoveInstanceObjects(ctx context.Context, instanceID string) error
|
||||||
//TODO: add functionality to move asset location
|
//TODO: add functionality to move asset location
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -115,3 +115,8 @@ func DeleteExternalIDPsByUserID(db *gorm.DB, table, userID, instanceID string) e
|
|||||||
)
|
)
|
||||||
return delete(db)
|
return delete(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeleteInstanceExternalIDPs(db *gorm.DB, table, instanceID string) error {
|
||||||
|
delete := repository.PrepareDeleteByKey(table, model.ExternalIDPSearchKey(usr_model.ExternalIDPSearchKeyInstanceID), instanceID)
|
||||||
|
return delete(db)
|
||||||
|
}
|
||||||
|
@@ -94,3 +94,8 @@ func DeleteApplicationRefreshTokens(db *gorm.DB, table string, appIDs []string)
|
|||||||
delete := repository.PrepareDeleteByKey(table, usr_model.RefreshTokenSearchKey(model.RefreshTokenSearchKeyApplicationID), appIDs)
|
delete := repository.PrepareDeleteByKey(table, usr_model.RefreshTokenSearchKey(model.RefreshTokenSearchKeyApplicationID), appIDs)
|
||||||
return delete(db)
|
return delete(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeleteInstanceRefreshTokens(db *gorm.DB, table string, instanceID string) error {
|
||||||
|
delete := repository.PrepareDeleteByKey(table, usr_model.RefreshTokenSearchKey(model.RefreshTokenSearchKeyInstanceID), instanceID)
|
||||||
|
return delete(db)
|
||||||
|
}
|
||||||
|
@@ -97,3 +97,8 @@ func DeleteApplicationTokens(db *gorm.DB, table, instanceID string, appIDs []str
|
|||||||
)
|
)
|
||||||
return delete(db)
|
return delete(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeleteInstanceTokens(db *gorm.DB, table, instanceID string) error {
|
||||||
|
delete := repository.PrepareDeleteByKey(table, usr_model.TokenSearchKey(model.TokenSearchKeyInstanceID), instanceID)
|
||||||
|
return delete(db)
|
||||||
|
}
|
||||||
|
@@ -125,3 +125,8 @@ func DeleteUserSessions(db *gorm.DB, table, userID, instanceID string) error {
|
|||||||
)
|
)
|
||||||
return delete(db)
|
return delete(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeleteInstanceUserSessions(db *gorm.DB, table, instanceID string) error {
|
||||||
|
delete := repository.PrepareDeleteByKey(table, model.UserSessionSearchKey(usr_model.UserSessionSearchKeyInstanceID), instanceID)
|
||||||
|
return delete(db)
|
||||||
|
}
|
||||||
|
@@ -204,3 +204,8 @@ func DeleteUser(db *gorm.DB, table, userID, instanceID string) error {
|
|||||||
)
|
)
|
||||||
return delete(db)
|
return delete(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeleteInstanceUsers(db *gorm.DB, table, instanceID string) error {
|
||||||
|
delete := repository.PrepareDeleteByKey(table, model.UserSearchKey(usr_model.UserSearchKeyInstanceID), instanceID)
|
||||||
|
return delete(db)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user