Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions api/src/backend/api/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,24 @@ class Meta:
}


class ScanSummaryFilter(FilterSet):
class ProviderIdAdapterMixin:
"""Mixin to adapt 'provider' parameter to 'provider_id' for backwards compatibility.

This allows using 'provider' as an alias for 'provider_id' in filter parameters.
Will be removed in a future version when 'provider' becomes the primary parameter.
"""

def __init__(self, data=None, *args, **kwargs):
if data is not None:
data = data.copy()
if "provider" in data and "provider_id" not in data:
data["provider_id"] = data.pop("provider")
if "provider__in" in data and "provider_id__in" not in data:
data["provider_id__in"] = data.pop("provider__in")
super().__init__(data, *args, **kwargs)


class ScanSummaryFilter(ProviderIdAdapterMixin, FilterSet):
inserted_at = DateFilter(field_name="inserted_at", lookup_expr="date")
provider_id = UUIDFilter(field_name="scan__provider__id", lookup_expr="exact")
provider_id__in = UUIDInFilter(field_name="scan__provider__id", lookup_expr="in")
Expand All @@ -803,7 +820,7 @@ class Meta:
}


class DailySeveritySummaryFilter(FilterSet):
class DailySeveritySummaryFilter(ProviderIdAdapterMixin, FilterSet):
"""Filter for findings_severity/timeseries endpoint."""

MAX_DATE_RANGE_DAYS = 365
Expand Down
23 changes: 4 additions & 19 deletions ui/app/(prowler)/_overview/_components/accounts-selector.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useRouter, useSearchParams } from "next/navigation";
import { ReactNode } from "react";

import {
Expand Down Expand Up @@ -43,21 +43,10 @@ interface AccountsSelectorProps {

export function AccountsSelector({ providers }: AccountsSelectorProps) {
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();

// Determine which filter key to use based on the current page
// - /findings uses provider__in (API expects this)
// - /overview and others use provider_id__in
const isFindingsPage = pathname?.startsWith("/findings");
const filterKey = isFindingsPage
? "filter[provider__in]"
: "filter[provider_id__in]";

// Read from both keys to support navigation between pages
const providerIn = searchParams.get("filter[provider__in]") || "";
const providerIdIn = searchParams.get("filter[provider_id__in]") || "";
const current = providerIn || providerIdIn;
const filterKey = "filter[provider_id__in]";
const current = searchParams.get(filterKey) || "";
const selectedTypes = searchParams.get("filter[provider_type__in]") || "";
const selectedTypesList = selectedTypes
? selectedTypes.split(",").filter(Boolean)
Expand All @@ -73,13 +62,9 @@ export function AccountsSelector({ providers }: AccountsSelectorProps) {

const handleMultiValueChange = (ids: string[]) => {
const params = new URLSearchParams(searchParams.toString());

// Clean up both potential provider filter keys first
params.delete("filter[provider_id__in]");
params.delete("filter[provider__in]");
params.delete(filterKey);

if (ids.length > 0) {
// Use the appropriate filter key for the current page
params.set(filterKey, ids.join(","));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ export const ProviderTypeSelector = ({
// Clear account selection when changing provider types
// User should manually select accounts if they want to filter by specific accounts
params.delete("filter[provider_id__in]");
params.delete("filter[provider__in]");

router.push(`?${params.toString()}`, { scroll: false });
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import Link from "next/link";

import { AttackSurfaceItem } from "@/actions/overview";
import { Card, CardContent } from "@/components/shadcn";
import { mapProviderFiltersForFindings } from "@/lib";

interface AttackSurfaceCardItemProps {
item: AttackSurfaceItem;
Expand All @@ -29,9 +28,6 @@ export function AttackSurfaceCardItem({
}
});

// Map provider filters for findings page compatibility
mapProviderFiltersForFindings(params);

return `/findings?${params.toString()}`;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { LinkToFindings } from "@/components/overview";
import { ColumnNewFindingsToDate } from "@/components/overview/new-findings-table/table/column-new-findings-to-date";
import { DataTable } from "@/components/ui/table";
import { createDict } from "@/lib/helper";
import { mapProviderFiltersForFindingsObject } from "@/lib/provider-helpers";
import { FindingProps, SearchParamsProps } from "@/types";

import { pickFilterParams } from "../../_lib/filter-params";
Expand All @@ -27,8 +26,7 @@ export async function FindingsViewSSR({ searchParams }: FindingsViewSSRProps) {
};

const filters = pickFilterParams(searchParams);
const mappedFilters = mapProviderFiltersForFindingsObject(filters);
const combinedFilters = { ...defaultFilters, ...mappedFilters };
const combinedFilters = { ...defaultFilters, ...filters };

const findingsData = await getLatestFindings({
query: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { HorizontalBarChart } from "@/components/graphs/horizontal-bar-chart";
import { ScatterPlot } from "@/components/graphs/scatter-plot";
import { AlertPill } from "@/components/graphs/shared/alert-pill";
import type { BarDataPoint } from "@/components/graphs/types";
import { mapProviderFiltersForFindings } from "@/lib/provider-helpers";
import { SEVERITY_FILTER_MAP } from "@/types/severities";

// Score color thresholds (0-100 scale, higher = better)
Expand Down Expand Up @@ -42,17 +41,14 @@ export function RiskPlotClient({ data }: RiskPlotClientProps) {
// Build the URL with current filters
const params = new URLSearchParams(searchParams.toString());

// Transform provider filters (provider_id__in -> provider__in)
mapProviderFiltersForFindings(params);

// Add severity filter
const severity = SEVERITY_FILTER_MAP[dataPoint.name];
if (severity) {
params.set("filter[severity__in]", severity);
}

// Add provider filter for the selected point
params.set("filter[provider__in]", selectedPoint.providerId);
params.set("filter[provider_id__in]", selectedPoint.providerId);

// Add exclude muted findings filter
params.set("filter[muted]", "false");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { useRouter, useSearchParams } from "next/navigation";
import { HorizontalBarChart } from "@/components/graphs/horizontal-bar-chart";
import { BarDataPoint } from "@/components/graphs/types";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/shadcn";
import { mapProviderFiltersForFindings } from "@/lib/provider-helpers";
import { calculatePercentage } from "@/lib/utils";
import { SEVERITY_FILTER_MAP } from "@/types/severities";

Expand All @@ -31,8 +30,6 @@ export const RiskSeverityChart = ({
// Build the URL with current filters plus severity and muted
const params = new URLSearchParams(searchParams.toString());

mapProviderFiltersForFindings(params);

const severity = SEVERITY_FILTER_MAP[dataPoint.name];
if (severity) {
params.set("filter[severity__in]", severity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const FindingSeverityOverTime = ({
params.set("filter[provider_type__in]", providerType);
}
if (providerId) {
params.set("filter[provider__in]", providerId);
params.set("filter[provider_id__in]", providerId);
}

router.push(`/findings?${params.toString()}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
CardVariant,
ResourceStatsCard,
} from "@/components/shadcn";
import { mapProviderFiltersForFindings } from "@/lib/provider-helpers";
import { calculatePercentage } from "@/lib/utils";
interface FindingsData {
total: number;
Expand All @@ -39,8 +38,6 @@ export const StatusChart = ({
// Build the URL with current filters plus status and muted
const params = new URLSearchParams(searchParams.toString());

mapProviderFiltersForFindings(params);

// Add status filter based on which segment was clicked
if (dataPoint.name === "Fail Findings") {
params.set("filter[status__in]", "FAIL");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { useRouter, useSearchParams } from "next/navigation";
import { useState } from "react";

import { ServiceOverview } from "@/actions/overview";
import { mapProviderFiltersForFindings } from "@/lib/provider-helpers";

import { SortToggleButton } from "./sort-toggle-button";
import { WatchlistCard, WatchlistItem } from "./watchlist-card";
Expand All @@ -29,9 +28,6 @@ export const ServiceWatchlist = ({ items }: { items: ServiceOverview[] }) => {

const handleItemClick = (item: WatchlistItem) => {
const params = new URLSearchParams(searchParams.toString());

mapProviderFiltersForFindings(params);

params.set("filter[service__in]", item.key);
params.set("filter[status__in]", "FAIL");
router.push(`/findings?${params.toString()}`);
Expand Down
10 changes: 2 additions & 8 deletions ui/components/graphs/sankey-chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { Rectangle, ResponsiveContainer, Sankey, Tooltip } from "recharts";

import { PROVIDER_ICONS } from "@/components/icons/providers-badge";
import { initializeChartColors } from "@/lib/charts/colors";
import { mapProviderFiltersForFindings } from "@/lib/provider-helpers";
import { PROVIDER_DISPLAY_NAMES } from "@/types/providers";
import { SEVERITY_FILTER_MAP } from "@/types/severities";

Expand Down Expand Up @@ -463,9 +462,6 @@ export function SankeyChart({
const severityFilter = SEVERITY_FILTER_MAP[nodeName];
if (severityFilter) {
const params = new URLSearchParams(searchParams.toString());

mapProviderFiltersForFindings(params);

params.set("filter[severity__in]", severityFilter);
params.set("filter[status__in]", "FAIL");
params.set("filter[muted]", "false");
Expand All @@ -480,12 +476,10 @@ export function SankeyChart({
if (severityFilter) {
const params = new URLSearchParams(searchParams.toString());

mapProviderFiltersForFindings(params);

// Always set provider_type filter based on the clicked link's source (provider)
// This ensures clicking "AWS → High" filters by AWS even when no global filter is set
const hasProviderIdFilter = searchParams.has("filter[provider_id__in]");
if (providerType && !hasProviderIdFilter) {
const hasProviderFilter = searchParams.has("filter[provider_id__in]");
if (providerType && !hasProviderFilter) {
params.set("filter[provider_type__in]", providerType);
}

Expand Down
2 changes: 0 additions & 2 deletions ui/components/graphs/threat-map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { useRouter, useSearchParams } from "next/navigation";
import { useEffect, useRef, useState } from "react";

import { Card } from "@/components/shadcn/card/card";
import { mapProviderFiltersForFindings } from "@/lib/provider-helpers";

import { HorizontalBarChart } from "./horizontal-bar-chart";
import {
Expand Down Expand Up @@ -399,7 +398,6 @@ export function ThreatMap({
providerType?: string,
) => {
const params = new URLSearchParams(searchParams.toString());
mapProviderFiltersForFindings(params);
if (providerType) params.set("filter[provider_type__in]", providerType);
params.set("filter[region__in]", regionCode);
params.set("filter[status__in]", status);
Expand Down
40 changes: 0 additions & 40 deletions ui/lib/provider-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,6 @@ import {
ProviderType,
} from "@/types/providers";

/**
* Maps overview provider filters to findings page provider filters.
* Converts provider_id__in to provider__in and removes provider_type__in
* since provider__in is more specific.
*/
export const mapProviderFiltersForFindings = (
params: URLSearchParams,
): void => {
const providerIds = params.get("filter[provider_id__in]");
if (providerIds) {
params.delete("filter[provider_id__in]");
params.delete("filter[provider_type__in]");
params.set("filter[provider__in]", providerIds);
}
};

/**
* Maps overview provider filters to findings page provider filters (object version).
* Converts provider_id__in to provider__in and removes provider_type__in
* since provider__in is more specific.
*/
export const mapProviderFiltersForFindingsObject = <
T extends Record<string, unknown>,
>(
filters: T,
): T => {
const result = { ...filters };
const providerIdKey = "filter[provider_id__in]";
const providerTypeKey = "filter[provider_type__in]";
const providerKey = "filter[provider__in]";

if (providerIdKey in result) {
result[providerKey as keyof T] = result[providerIdKey as keyof T];
delete result[providerIdKey as keyof T];
delete result[providerTypeKey as keyof T];
}

return result;
};

export const extractProviderUIDs = (
providersData: ProvidersApiResponse,
): string[] => {
Expand Down