mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-24 00:28:18 +00:00
bc9a85daf3
* feat(import): add functionality to import data into an instance * feat(import): move import to admin api and additional checks for nil pointer * fix(export): export implementation with filtered members and grants * fix: export and import implementation * fix: add possibility to export hashed passwords with the user * fix(import): import with structure of v1 and v2 * docs: add v1 proto * fix(import): check im imported user is already existing * fix(import): add otp import function * fix(import): add external idps, domains, custom text and messages * fix(import): correct usage of default values from login policy * fix(export): fix renaming of add project function * fix(import): move checks for unit tests * expect filter * fix(import): move checks for unit tests * fix(import): move checks for unit tests * fix(import): produce prerelease from branch * fix(import): correctly use provided user id for machine user imports * fix(import): corrected otp import and added guide for export and import * fix: import verified and primary domains * fix(import): add reading from gcs, s3 and localfile with tracing * fix(import): gcs and s3, file size correction and error logging * Delete docker-compose.yml * fix(import): progress logging and count of resources * fix(import): progress logging and count of resources * log subscription * fix(import): incorporate review * fix(import): incorporate review * docs: add suggestion for import Co-authored-by: Fabi <38692350+hifabienne@users.noreply.github.com> * fix(import): add verification otp event and handling of deleted but existing users Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Fabienne <fabienne.gerschwiler@gmail.com> Co-authored-by: Silvan <silvan.reusser@gmail.com> Co-authored-by: Fabi <38692350+hifabienne@users.noreply.github.com>
247 lines
8.5 KiB
Go
247 lines
8.5 KiB
Go
package command
|
|
|
|
import (
|
|
"context"
|
|
"sort"
|
|
|
|
"github.com/zitadel/zitadel/internal/domain"
|
|
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
|
"github.com/zitadel/zitadel/internal/eventstore"
|
|
"github.com/zitadel/zitadel/internal/repository/action"
|
|
"github.com/zitadel/zitadel/internal/repository/org"
|
|
)
|
|
|
|
func (c *Commands) AddActionWithID(ctx context.Context, addAction *domain.Action, resourceOwner, actionID string) (_ string, _ *domain.ObjectDetails, err error) {
|
|
existingAction, err := c.getActionWriteModelByID(ctx, actionID, resourceOwner)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
if existingAction.State != domain.ActionStateUnspecified {
|
|
return "", nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-nau2k", "Errors.Action.AlreadyExisting")
|
|
}
|
|
|
|
return c.addActionWithID(ctx, addAction, resourceOwner, actionID)
|
|
}
|
|
|
|
func (c *Commands) AddAction(ctx context.Context, addAction *domain.Action, resourceOwner string) (_ string, _ *domain.ObjectDetails, err error) {
|
|
if !addAction.IsValid() {
|
|
return "", nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-eg2gf", "Errors.Action.Invalid")
|
|
}
|
|
|
|
actionID, err := c.idGenerator.Next()
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
return c.addActionWithID(ctx, addAction, resourceOwner, actionID)
|
|
}
|
|
|
|
func (c *Commands) addActionWithID(ctx context.Context, addAction *domain.Action, resourceOwner, actionID string) (_ string, _ *domain.ObjectDetails, err error) {
|
|
addAction.AggregateID = actionID
|
|
actionModel := NewActionWriteModel(addAction.AggregateID, resourceOwner)
|
|
actionAgg := ActionAggregateFromWriteModel(&actionModel.WriteModel)
|
|
|
|
pushedEvents, err := c.eventstore.Push(ctx, action.NewAddedEvent(
|
|
ctx,
|
|
actionAgg,
|
|
addAction.Name,
|
|
addAction.Script,
|
|
addAction.Timeout,
|
|
addAction.AllowedToFail,
|
|
))
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
err = AppendAndReduce(actionModel, pushedEvents...)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
return actionModel.AggregateID, writeModelToObjectDetails(&actionModel.WriteModel), nil
|
|
}
|
|
|
|
func (c *Commands) ChangeAction(ctx context.Context, actionChange *domain.Action, resourceOwner string) (*domain.ObjectDetails, error) {
|
|
if !actionChange.IsValid() || actionChange.AggregateID == "" {
|
|
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-Df2f3", "Errors.Action.Invalid")
|
|
}
|
|
|
|
existingAction, err := c.getActionWriteModelByID(ctx, actionChange.AggregateID, resourceOwner)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !existingAction.State.Exists() {
|
|
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-Sfg2t", "Errors.Action.NotFound")
|
|
}
|
|
|
|
actionAgg := ActionAggregateFromWriteModel(&existingAction.WriteModel)
|
|
changedEvent, err := existingAction.NewChangedEvent(
|
|
ctx,
|
|
actionAgg,
|
|
actionChange.Name,
|
|
actionChange.Script,
|
|
actionChange.Timeout,
|
|
actionChange.AllowedToFail)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
pushedEvents, err := c.eventstore.Push(ctx, changedEvent)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = AppendAndReduce(existingAction, pushedEvents...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return writeModelToObjectDetails(&existingAction.WriteModel), nil
|
|
}
|
|
|
|
func (c *Commands) DeactivateAction(ctx context.Context, actionID string, resourceOwner string) (*domain.ObjectDetails, error) {
|
|
if actionID == "" || resourceOwner == "" {
|
|
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-DAhk5", "Errors.IDMissing")
|
|
}
|
|
|
|
existingAction, err := c.getActionWriteModelByID(ctx, actionID, resourceOwner)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !existingAction.State.Exists() {
|
|
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-NRmhu", "Errors.Action.NotFound")
|
|
}
|
|
if existingAction.State != domain.ActionStateActive {
|
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-Dgj92", "Errors.Action.NotActive")
|
|
}
|
|
actionAgg := ActionAggregateFromWriteModel(&existingAction.WriteModel)
|
|
events := []eventstore.Command{
|
|
action.NewDeactivatedEvent(ctx, actionAgg),
|
|
}
|
|
pushedEvents, err := c.eventstore.Push(ctx, events...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = AppendAndReduce(existingAction, pushedEvents...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return writeModelToObjectDetails(&existingAction.WriteModel), nil
|
|
}
|
|
|
|
func (c *Commands) ReactivateAction(ctx context.Context, actionID string, resourceOwner string) (*domain.ObjectDetails, error) {
|
|
if actionID == "" || resourceOwner == "" {
|
|
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-BNm56", "Errors.IDMissing")
|
|
}
|
|
|
|
existingAction, err := c.getActionWriteModelByID(ctx, actionID, resourceOwner)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !existingAction.State.Exists() {
|
|
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-Aa22g", "Errors.Action.NotFound")
|
|
}
|
|
if existingAction.State != domain.ActionStateInactive {
|
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-J53zh", "Errors.Action.NotInactive")
|
|
}
|
|
|
|
actionAgg := ActionAggregateFromWriteModel(&existingAction.WriteModel)
|
|
events := []eventstore.Command{
|
|
action.NewReactivatedEvent(ctx, actionAgg),
|
|
}
|
|
pushedEvents, err := c.eventstore.Push(ctx, events...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = AppendAndReduce(existingAction, pushedEvents...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return writeModelToObjectDetails(&existingAction.WriteModel), nil
|
|
}
|
|
|
|
func (c *Commands) DeleteAction(ctx context.Context, actionID, resourceOwner string, flowTypes ...domain.FlowType) (*domain.ObjectDetails, error) {
|
|
if actionID == "" || resourceOwner == "" {
|
|
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-Gfg3g", "Errors.IDMissing")
|
|
}
|
|
|
|
existingAction, err := c.getActionWriteModelByID(ctx, actionID, resourceOwner)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !existingAction.State.Exists() {
|
|
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-Dgh4h", "Errors.Action.NotFound")
|
|
}
|
|
actionAgg := ActionAggregateFromWriteModel(&existingAction.WriteModel)
|
|
events := []eventstore.Command{
|
|
action.NewRemovedEvent(ctx, actionAgg, existingAction.Name),
|
|
}
|
|
orgAgg := org.NewAggregate(resourceOwner).Aggregate
|
|
for _, flowType := range flowTypes {
|
|
events = append(events, org.NewTriggerActionsCascadeRemovedEvent(ctx, &orgAgg, flowType, actionID))
|
|
}
|
|
pushedEvents, err := c.eventstore.Push(ctx, events...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = AppendAndReduce(existingAction, pushedEvents...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return writeModelToObjectDetails(&existingAction.WriteModel), nil
|
|
}
|
|
|
|
func (c *Commands) removeActionsFromOrg(ctx context.Context, resourceOwner string) ([]eventstore.Command, error) {
|
|
existingActions, err := c.getActionsByOrgWriteModelByID(ctx, resourceOwner)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(existingActions.Actions) == 0 {
|
|
return nil, nil
|
|
}
|
|
events := make([]eventstore.Command, 0, len(existingActions.Actions))
|
|
for id, existingAction := range existingActions.Actions {
|
|
actionAgg := NewActionAggregate(id, resourceOwner)
|
|
events = append(events, action.NewRemovedEvent(ctx, actionAgg, existingAction.Name))
|
|
}
|
|
return events, nil
|
|
}
|
|
|
|
func (c *Commands) deactivateNotAllowedActionsFromOrg(ctx context.Context, resourceOwner string, maxAllowed int) ([]eventstore.Command, error) {
|
|
existingActions, err := c.getActionsByOrgWriteModelByID(ctx, resourceOwner)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
activeActions := make([]*ActionWriteModel, 0, len(existingActions.Actions))
|
|
for _, existingAction := range existingActions.Actions {
|
|
if existingAction.State == domain.ActionStateActive {
|
|
activeActions = append(activeActions, existingAction)
|
|
}
|
|
}
|
|
if len(activeActions) <= maxAllowed {
|
|
return nil, nil
|
|
}
|
|
sort.Slice(activeActions, func(i, j int) bool {
|
|
return activeActions[i].WriteModel.ChangeDate.Before(activeActions[j].WriteModel.ChangeDate)
|
|
})
|
|
events := make([]eventstore.Command, 0, len(existingActions.Actions))
|
|
for i := maxAllowed; i < len(activeActions); i++ {
|
|
actionAgg := NewActionAggregate(activeActions[i].AggregateID, resourceOwner)
|
|
events = append(events, action.NewDeactivatedEvent(ctx, actionAgg))
|
|
}
|
|
return events, nil
|
|
}
|
|
|
|
func (c *Commands) getActionWriteModelByID(ctx context.Context, actionID string, resourceOwner string) (*ActionWriteModel, error) {
|
|
actionWriteModel := NewActionWriteModel(actionID, resourceOwner)
|
|
err := c.eventstore.FilterToQueryReducer(ctx, actionWriteModel)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return actionWriteModel, nil
|
|
}
|
|
|
|
func (c *Commands) getActionsByOrgWriteModelByID(ctx context.Context, resourceOwner string) (*ActionsListByOrgModel, error) {
|
|
actionWriteModel := NewActionsListByOrgModel(resourceOwner)
|
|
err := c.eventstore.FilterToQueryReducer(ctx, actionWriteModel)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return actionWriteModel, nil
|
|
}
|