첫 커밋: 로컬 프로젝트 업로드
This commit is contained in:
84
baron-sso/backend/internal/bootstrap/keto_sync.go
Normal file
84
baron-sso/backend/internal/bootstrap/keto_sync.go
Normal file
@@ -0,0 +1,84 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user