forked from baron/baron-sso
85 lines
2.4 KiB
Go
85 lines
2.4 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
"baron-sso-backend/internal/domain"
|
|
"baron-sso-backend/internal/repository"
|
|
"context"
|
|
"log/slog"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// SyncKetoRelations synchronizes all existing DB users, tenants and RPs to Ory Keto via Outbox.
|
|
// This ensures data consistency for existing data when ReBAC is introduced.
|
|
func SyncKetoRelations(db *gorm.DB, outbox repository.KetoOutboxRepository) error {
|
|
slog.Info("🚀 Starting Keto ReBAC relation synchronization (via Outbox)...")
|
|
ctx := context.Background()
|
|
|
|
// 1. Sync All Tenants
|
|
var tenants []domain.Tenant
|
|
if err := db.Find(&tenants).Error; err != nil {
|
|
return err
|
|
}
|
|
slog.Info("Syncing tenants to Keto Outbox", "count", len(tenants))
|
|
for _, t := range tenants {
|
|
// Global Super Admin access to every tenant
|
|
_ = outbox.Create(ctx, &domain.KetoOutbox{
|
|
Namespace: "Tenant",
|
|
Object: t.ID,
|
|
Relation: "admins",
|
|
Subject: "System:global#super_admins",
|
|
Action: domain.KetoOutboxActionCreate,
|
|
})
|
|
|
|
if t.ParentID != nil {
|
|
_ = outbox.Create(ctx, &domain.KetoOutbox{
|
|
Namespace: "Tenant",
|
|
Object: t.ID,
|
|
Relation: "parents",
|
|
Subject: "Tenant:" + *t.ParentID,
|
|
Action: domain.KetoOutboxActionCreate,
|
|
})
|
|
}
|
|
}
|
|
|
|
// 2. Sync All RelyingParties (if needed)
|
|
// Note: We'll need a way to list them from Hydra or local DB if we had them.
|
|
// Assuming they are in a table domain.RelyingParty (though it was removed, let's see)
|
|
// Actually, the comment said SSOT is Hydra. But we might have them in a local table for metadata.
|
|
// If not, we skip for now or fetch from Hydra.
|
|
|
|
// 3. Sync All Users Roles and Tenant Memberships
|
|
var users []domain.User
|
|
if err := db.Find(&users).Error; err != nil {
|
|
return err
|
|
}
|
|
slog.Info("Syncing users to Keto Outbox", "count", len(users))
|
|
for _, u := range users {
|
|
// Tenant Membership
|
|
if u.TenantID != nil {
|
|
_ = outbox.Create(ctx, &domain.KetoOutbox{
|
|
Namespace: "Tenant",
|
|
Object: *u.TenantID,
|
|
Relation: "members",
|
|
Subject: "User:" + u.ID,
|
|
Action: domain.KetoOutboxActionCreate,
|
|
})
|
|
}
|
|
|
|
// Roles
|
|
role := domain.NormalizeRole(u.Role)
|
|
if role == domain.RoleSuperAdmin {
|
|
_ = outbox.Create(ctx, &domain.KetoOutbox{
|
|
Namespace: "System",
|
|
Object: "global",
|
|
Relation: "super_admins",
|
|
Subject: "User:" + u.ID,
|
|
Action: domain.KetoOutboxActionCreate,
|
|
})
|
|
}
|
|
}
|
|
|
|
slog.Info("✅ Keto ReBAC synchronization items added to Outbox.")
|
|
return nil
|
|
}
|