Files
zitadel/apps/api/cmd/setup/sync_role_permissions.go
2025-08-05 15:20:32 -07:00

77 lines
2.5 KiB
Go

package setup
import (
"context"
_ "embed"
"fmt"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/instance"
)
// SyncRolePermissions is a repeatable step which synchronizes the InternalAuthZ
// RolePermissionMappings from the configuration to the database.
// This is needed until role permissions are manageable over the API.
type SyncRolePermissions struct {
commands *command.Commands
eventstore *eventstore.Eventstore
rolePermissionMappings []authz.RoleMapping
}
func (mig *SyncRolePermissions) Execute(ctx context.Context, _ eventstore.Event) error {
if err := mig.executeSystem(ctx); err != nil {
return err
}
return mig.executeInstances(ctx)
}
func (mig *SyncRolePermissions) executeSystem(ctx context.Context) error {
logging.WithFields("migration", mig.String()).Info("prepare system role permission sync events")
details, err := mig.commands.SynchronizeRolePermission(ctx, "SYSTEM", mig.rolePermissionMappings)
if err != nil {
return err
}
logging.WithFields("migration", mig.String(), "sequence", details.Sequence).Info("pushed system role permission sync events")
return nil
}
func (mig *SyncRolePermissions) executeInstances(ctx context.Context) error {
instances, err := mig.eventstore.InstanceIDs(
ctx,
eventstore.NewSearchQueryBuilder(eventstore.ColumnsInstanceIDs).
OrderDesc().
AddQuery().
AggregateTypes(instance.AggregateType).
EventTypes(instance.InstanceAddedEventType).
Builder().
ExcludeAggregateIDs().
AggregateTypes(instance.AggregateType).
EventTypes(instance.InstanceRemovedEventType).
Builder(),
)
if err != nil {
return err
}
for i, instanceID := range instances {
logging.WithFields("instance_id", instanceID, "migration", mig.String(), "progress", fmt.Sprintf("%d/%d", i+1, len(instances))).Info("prepare instance role permission sync events")
details, err := mig.commands.SynchronizeRolePermission(ctx, instanceID, mig.rolePermissionMappings)
if err != nil {
return err
}
logging.WithFields("instance_id", instanceID, "migration", mig.String(), "sequence", details.Sequence).Info("pushed instance role permission sync events")
}
return nil
}
func (*SyncRolePermissions) String() string {
return "repeatable_sync_role_permissions"
}
func (*SyncRolePermissions) Check(lastRun map[string]interface{}) bool {
return true
}