1
0
forked from baron/baron-sso

코드 테스트 실패 수정

This commit is contained in:
2026-06-11 08:55:41 +09:00
parent 4d77060b5d
commit 0bb3ccb850
13 changed files with 517 additions and 382 deletions

View File

@@ -573,6 +573,30 @@ func (h *DevHandler) canManageClientRelations(c *fiber.Ctx, profile *domain.User
return canAccessClientByLegacyScope(profile, summary)
}
func (h *DevHandler) canManageRPUserMetadata(c *fiber.Ctx, profile *domain.UserProfileResponse, summary clientSummary) bool {
if profile == nil {
return false
}
if normalizeUserRole(profile.Role) == domain.RoleSuperAdmin {
return true
}
return h.canOperateClientByPermit(c, profile, summary, "manage")
}
func (h *DevHandler) canSelfUpdateRPUserMetadata(c *fiber.Ctx, profile *domain.UserProfileResponse, summary clientSummary) bool {
if profile == nil {
return false
}
if normalizeUserRole(profile.Role) == domain.RoleSuperAdmin {
return true
}
if h.Keto == nil {
return true
}
allowed, err := h.checkProfileKetoPermission(c, profile, "RelyingParty", summary.ID, "access")
return err == nil && allowed
}
func (h *DevHandler) auditClientIDsByPermit(c *fiber.Ctx, profile *domain.UserProfileResponse, clientFilter string) map[string]struct{} {
ids := make(map[string]struct{})
if profile == nil || h.Hydra == nil {
@@ -1612,7 +1636,7 @@ func (h *DevHandler) UpsertRPUserMetadata(c *fiber.Ctx) error {
if err != nil {
return errorJSON(c, fiber.StatusNotFound, "client not found")
}
if !h.canManageClientRelations(c, profile, summary) {
if !h.canManageRPUserMetadata(c, profile, summary) {
return errorJSON(c, fiber.StatusForbidden, "forbidden: insufficient permission to update client metadata")
}
@@ -1645,6 +1669,73 @@ func (h *DevHandler) UpsertRPUserMetadata(c *fiber.Ctx) error {
return c.JSON(row)
}
func (h *DevHandler) SelfUpdateRPUserMetadata(c *fiber.Ctx) error {
clientID := strings.TrimSpace(c.Params("id"))
if clientID == "" {
return errorJSON(c, fiber.StatusBadRequest, "client id is required")
}
if h.RPUserMetadataRepo == nil {
return errorJSON(c, fiber.StatusServiceUnavailable, "rp user metadata repository unavailable")
}
profile := h.getCurrentProfile(c)
if profile == nil || strings.TrimSpace(profile.ID) == "" {
return errorJSON(c, fiber.StatusUnauthorized, "unauthorized: authentication required")
}
summary, err := h.loadClientSummary(c.Context(), clientID)
if err != nil {
return errorJSON(c, fiber.StatusNotFound, "client not found")
}
if !h.canSelfUpdateRPUserMetadata(c, profile, summary) {
return errorJSON(c, fiber.StatusForbidden, "forbidden: insufficient permission to update own client metadata")
}
var req struct {
Metadata map[string]any `json:"metadata"`
}
if err := c.BodyParser(&req); err != nil {
return errorJSON(c, fiber.StatusBadRequest, "invalid request body")
}
if req.Metadata == nil {
req.Metadata = map[string]any{}
}
filteredMetadata, err := filterSelfWritableRPUserMetadata(req.Metadata, summary.Metadata)
if err != nil {
return errorJSON(c, fiber.StatusForbidden, err.Error())
}
normalizedMetadata, err := normalizeRPUserMetadataForClient(filteredMetadata, summary.Metadata)
if err != nil {
return errorJSON(c, fiber.StatusBadRequest, err.Error())
}
userID := strings.TrimSpace(profile.ID)
mergedMetadata := domain.JSONMap{}
if existing, err := h.RPUserMetadataRepo.Get(c.Context(), clientID, userID); err == nil && existing != nil {
for key, value := range existing.Metadata {
mergedMetadata[key] = value
}
}
for key, value := range normalizedMetadata {
mergedMetadata[key] = value
}
row := &domain.RPUserMetadata{
ClientID: clientID,
UserID: userID,
Metadata: mergedMetadata,
}
if err := h.RPUserMetadataRepo.Upsert(c.Context(), row); err != nil {
return errorJSON(c, fiber.StatusInternalServerError, err.Error())
}
if err := h.syncRPUserMetadataToKratos(c.Context(), userID, clientID, mergedMetadata); err != nil {
return errorJSON(c, fiber.StatusInternalServerError, err.Error())
}
return c.JSON(row)
}
func (h *DevHandler) syncRPUserMetadataToKratos(ctx context.Context, userID string, clientID string, metadata domain.JSONMap) error {
if h == nil || h.KratosAdmin == nil {
return nil
@@ -1769,6 +1860,33 @@ func normalizeRPUserMetadataForClient(metadata map[string]any, clientMetadata ma
return normalized, nil
}
func filterSelfWritableRPUserMetadata(metadata map[string]any, clientMetadata map[string]any) (map[string]any, error) {
schemas, err := rpUserMetadataClaimSchemas(clientMetadata)
if err != nil {
return nil, err
}
filtered := map[string]any{}
for rawKey, rawValue := range metadata {
key := strings.TrimSpace(rawKey)
if key == "" || isEmptyRPUserMetadataValue(rawValue) {
continue
}
if strings.HasSuffix(key, "_permissions") {
return nil, fmt.Errorf("rp user metadata permission cannot be updated by user: %s", key)
}
schema, ok := schemas[key]
if !ok {
return nil, fmt.Errorf("rp user metadata claim is not configured: %s", key)
}
if normalizeCustomClaimPermission(schema.WritePermission) != "user_and_admin" {
return nil, fmt.Errorf("rp user metadata claim is admin only: %s", key)
}
filtered[key] = rawValue
}
return filtered, nil
}
func rpUserMetadataClaimSchemas(clientMetadata map[string]any) (map[string]rpUserMetadataClaimSchema, error) {
rawClaims, ok := clientMetadata[domain.MetadataIDTokenClaims]
if !ok || rawClaims == nil {