Skip to content

Consolidate UI list handler filter parsing (ui_iocs.go, ui_sources.go, ui_sites.go) #142

@cawalch

Description

@cawalch

Summary

Three UI list handlers follow an identical pattern: define a filter struct, parse from query params, call handleList(), and enrich data. The filter structs differ only in which categories are valid, but the parsing and enrichment logic is duplicated.

Current Pattern (repeated 3x)

// ui_iocs.go
type iocFilter struct { Category, Search, Status, SortBy, SortOrder, Page, PageSize string }
func parseIOCFilter(r *http.Request) iocFilter { ... }
func (h *UIHandlers) HandleListIOCs(w, r) { filter := parseIOCFilter(r); handleList(...); enrichIOCData(...) }

// ui_sources.go — IDENTICAL STRUCT
type sourceFilter struct { Category, Search, Status, SortBy, SortOrder, Page, PageSize string }
func parseSourceFilter(r *http.Request) sourceFilter { ... }

// ui_sites.go — IDENTICAL STRUCT
type siteFilter struct { Category, Search, Status, SortBy, SortOrder, Page, PageSize string }
func parseSiteFilter(r *http.Request) siteFilter { ... }

Proposed Solution

Define a common filter interface and generic parser:

// ui_base.go

// BaseFilter holds common filter fields shared across list pages.
type BaseFilter struct {
    Search    string
    Status    string
    SortBy    string
    SortOrder string
    Page      string
    PageSize  string
}

// FilterParser parses common fields from query params.
func ParseBaseFilter(r *http.Request) BaseFilter {
    return BaseFilter{
        Search:    r.URL.Query().Get("search"),
        Status:    r.URL.Query().Get("status"),
        SortBy:    r.URL.Query().Get("sort_by"),
        SortOrder: r.URL.Query().Get("sort_order"),
        Page:      r.URL.Query().Get("page"),
        PageSize:  r.URL.Query().Get("page_size"),
    }
}

// CategoryFilter adds category filtering on top of BaseFilter.
type CategoryFilter struct {
    BaseFilter
    Category        string
    ValidCategories []string
}

Each handler then only defines its category-specific logic:

func (h *UIHandlers) HandleListIOCs(w, r) {
    base := ParseBaseFilter(r)
    filter := CategoryFilter{
        BaseFilter:      base,
        Category:        r.URL.Query().Get("category"),
        ValidCategories: []string{"domain", "hash", "url", ...},
    }
    // ... handleList with filter ...
}

Impact

  • Lines saved: ~50 per file (~150 total across 3 files)
  • Risk: Medium — filter parsing is tested, need to verify equivalence
  • Benefit: Single source of truth for filter parsing, easier to add new filter fields

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestgoPull requests that update go code

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions