1
0
forked from baron/baron-sso

애플리케이션(RP) 관리 기능 구현 및 Ory Keto 권한 연동

This commit is contained in:
2026-02-04 14:56:16 +09:00
parent bf469b1eb4
commit 066ea86f46
14 changed files with 232 additions and 48 deletions

View File

@@ -3208,7 +3208,9 @@ func (h *AuthHandler) ListLinkedRps(c *fiber.Ctx) error {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid session"})
}
var sessions []service.HydraConsentSession
var sessions []domain.HydraConsentSession
var lastErr error
hasSuccess := false
for _, subject := range subjects {

View File

@@ -1,6 +1,7 @@
package handler
import (
"baron-sso-backend/internal/domain"
"baron-sso-backend/internal/service"
"errors"
"strings"
@@ -230,7 +231,7 @@ func (h *DevHandler) CreateClient(c *fiber.Ctx) error {
}
}
clientReq := service.HydraClient{
clientReq := domain.HydraClient{
ClientID: clientID,
ClientName: name,
RedirectURIs: redirectURIs,
@@ -329,7 +330,7 @@ func (h *DevHandler) UpdateClient(c *fiber.Ctx) error {
metadata["status"] = status
}
updated := service.HydraClient{
updated := domain.HydraClient{
ClientID: current.ClientID,
ClientName: valueOr(req.Name, current.ClientName),
RedirectURIs: derefSlice(req.RedirectURIs, current.RedirectURIs),
@@ -438,7 +439,7 @@ func (h *DevHandler) RevokeConsents(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusNoContent)
}
func (h *DevHandler) mapClientSummary(client service.HydraClient) clientSummary {
func (h *DevHandler) mapClientSummary(client domain.HydraClient) clientSummary {
status := "active"
if client.Metadata != nil {
if value, ok := client.Metadata["status"].(string); ok && strings.ToLower(value) == "inactive" {

View File

@@ -404,6 +404,12 @@ func (h *UserHandler) UpdateUser(c *fiber.Ctx) error {
// [New] Local DB Sync
if h.UserRepo != nil {
if localUser, err := h.UserRepo.FindByID(c.Context(), userID); err == nil && localUser != nil {
oldRole := localUser.Role
oldTenantID := ""
if localUser.TenantID != nil {
oldTenantID = *localUser.TenantID
}
if req.Name != nil {
localUser.Name = *req.Name
}
@@ -428,7 +434,26 @@ func (h *UserHandler) UpdateUser(c *fiber.Ctx) error {
if req.Metadata != nil {
localUser.Metadata = req.Metadata
}
if err := h.UserRepo.Update(c.Context(), localUser); err != nil {
if err := h.UserRepo.Update(c.Context(), localUser); err == nil {
// [Keto Sync on Role Change]
if h.KetoService != nil && req.Role != nil && *req.Role != oldRole {
go func(uID, oldR, newR, tID string) {
ctx := context.Background()
if oldR == domain.RoleSuperAdmin {
_ = h.KetoService.DeleteRelation(ctx, "System", "global", "super_admins", uID)
} else if oldR == domain.RoleTenantAdmin && tID != "" {
_ = h.KetoService.DeleteRelation(ctx, "Tenant", tID, "admins", uID)
}
if newR == domain.RoleSuperAdmin {
_ = h.KetoService.CreateRelation(ctx, "System", "global", "super_admins", uID)
} else if newR == domain.RoleTenantAdmin && tID != "" {
_ = h.KetoService.CreateRelation(ctx, "Tenant", tID, "admins", uID)
}
}(userID, oldRole, *req.Role, oldTenantID)
}
} else {
slog.Error("[UserHandler] Failed to sync user update to local DB", "userID", userID, "error", err)
}
}
@@ -471,13 +496,14 @@ func (h *UserHandler) DeleteUser(c *fiber.Ctx) error {
// [Keto] Cleanup relations (Best effort)
if h.KetoService != nil {
go func() {
go func(uID string) {
ctx := context.Background()
// Note: Proper cleanup requires searching all relations,
// here we just cleanup known common ones or rely on subject cleanup if Keto supported it.
_ = h.KetoService.DeleteRelation(ctx, "System", "global", "super_admins", userID)
// For tenants, we'd need to know which tenant they were in.
}()
// Fetch user from DB before cleanup if needed, but here we cleanup common namespaces
_ = h.KetoService.DeleteRelation(ctx, "System", "global", "super_admins", uID)
// If we had more complex relations, we would query Keto first or use user metadata
slog.Info("Keto relations cleaned up for user", "userID", uID)
}(userID)
}
return c.SendStatus(fiber.StatusNoContent)