forked from baron/baron-sso
애플리케이션(RP) 관리 기능 구현 및 Ory Keto 권한 연동
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user