1
0
forked from baron/baron-sso
Files
baron-sso/backend/internal/bootstrap/keto_sync.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
}