forked from baron/baron-sso
Linked API에 Audit Log 스캔을 통한 과거 이력 보강 로직 추가
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user