1
0
forked from baron/baron-sso

Linked API에 Audit Log 스캔을 통한 과거 이력 보강 로직 추가

This commit is contained in:
2026-02-09 11:18:32 +09:00
parent 4b7264217d
commit bb78c8e572

View File

@@ -3386,6 +3386,84 @@ func (h *AuthHandler) ListLinkedRps(c *fiber.Ctx) error {
}
}
// [New] Audit Log Scan for recent history fallback (timeline 200 items)
// Hydra 세션이나 로컬 DB(ConsentRepo)에 없지만 최근 활동 이력이 있는 앱을 보강
if h.AuditRepo != nil {
for _, subject := range subjects {
auditLogs, err := h.AuditRepo.FindByUserAndEvents(c.Context(), subject, []string{"consent.granted", "consent.revoked"}, 200)
if err != nil {
slog.Error("failed to scan audit logs for linked rps", "error", err, "subject", subject)
continue
}
for _, log := range auditLogs {
var details struct {
ClientID string `json:"client_id"`
ClientName string `json:"client_name"`
Scopes interface{} `json:"scopes"`
}
// 로그 Details 파싱
if err := json.Unmarshal([]byte(log.Details), &details); err != nil {
continue
}
if details.ClientID == "" {
continue
}
// 이미 records에 있으면(Active or ConsentRepo) 패스
if _, exists := records[details.ClientID]; exists {
continue
}
// 스코프 추출 (consent.granted인 경우)
scopes := []string{}
if sList, ok := details.Scopes.([]interface{}); ok {
for _, s := range sList {
if str, ok := s.(string); ok {
scopes = append(scopes, str)
}
}
}
// 기본 레코드 생성
record := &linkedRpRecord{
linkedRpSummary: linkedRpSummary{
ID: details.ClientID,
Name: details.ClientName, // revoked 로그일 경우 비어있을 수 있음
Status: "inactive",
Scopes: scopes,
},
lastAuth: log.Timestamp,
}
// Hydra에서 최신 메타데이터 조회 시도
client, err := h.Hydra.GetClient(c.Context(), details.ClientID)
if err == nil {
name := strings.TrimSpace(client.ClientName)
if name == "" {
name = client.ClientID
}
record.Name = name
record.Logo = extractHydraClientLogo(client.Metadata)
clientURL := strings.TrimSpace(client.ClientURI)
if clientURL == "" && len(client.RedirectURIs) > 0 {
if parsed, err := url.Parse(client.RedirectURIs[0]); err == nil {
clientURL = fmt.Sprintf("%s://%s", parsed.Scheme, parsed.Host)
}
}
record.URL = clientURL
} else {
// Hydra 정보 없음 (삭제됨 등) -> Audit 정보나 ID로 대체
if record.Name == "" {
record.Name = details.ClientID
}
}
records[details.ClientID] = record
}
}
}
ordered := make([]*linkedRpRecord, 0, len(records))
for _, record := range records {
ordered = append(ordered, record)