forked from baron/baron-sso
53 lines
1.4 KiB
Go
53 lines
1.4 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
"baron-sso-backend/internal/domain"
|
|
"baron-sso-backend/internal/service"
|
|
"context"
|
|
"log/slog"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// SyncKetoRelations synchronizes all existing DB users and tenants to Ory Keto.
|
|
// This ensures data consistency for existing data when ReBAC is introduced.
|
|
func SyncKetoRelations(db *gorm.DB, keto service.KetoService) error {
|
|
slog.Info("🚀 Starting Keto ReBAC relation synchronization...")
|
|
ctx := context.Background()
|
|
|
|
// 1. Sync All Tenants (Ensure they exist in Keto if needed)
|
|
var tenants []domain.Tenant
|
|
if err := db.Find(&tenants).Error; err != nil {
|
|
return err
|
|
}
|
|
slog.Info("Syncing tenants to Keto", "count", len(tenants))
|
|
for _, t := range tenants {
|
|
if t.ParentID != nil {
|
|
_ = keto.CreateRelation(ctx, "Tenant", t.ID, "parent", *t.ParentID)
|
|
}
|
|
}
|
|
|
|
// 2. Sync All Users
|
|
var users []domain.User
|
|
if err := db.Find(&users).Error; err != nil {
|
|
return err
|
|
}
|
|
slog.Info("Syncing users to Keto", "count", len(users))
|
|
for _, u := range users {
|
|
// Membership
|
|
if u.TenantID != nil {
|
|
_ = keto.CreateRelation(ctx, "Tenant", *u.TenantID, "members", u.ID)
|
|
}
|
|
|
|
// Roles
|
|
if u.Role == domain.RoleSuperAdmin {
|
|
_ = keto.CreateRelation(ctx, "System", "global", "super_admins", u.ID)
|
|
} else if u.Role == domain.RoleTenantAdmin && u.TenantID != nil {
|
|
_ = keto.CreateRelation(ctx, "Tenant", *u.TenantID, "admins", u.ID)
|
|
}
|
|
}
|
|
|
|
slog.Info("✅ Keto ReBAC synchronization completed.")
|
|
return nil
|
|
}
|