Generalize logic to ensure macos_settings always filtered with a team_id; Apply to 3 places (#10472)

## Addresses [this
discussion](https://github.com/fleetdm/fleet/pull/10385#discussion_r1134668601)

## Implements

Abstract logic to ensure a team_id is always passed with the
macos_settings filter, allowing general usage and keeping that logic in
sync everywhere it is used.

Uses this in 3 places.

## Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [x] Added/updated tests
- [x] Manual QA

---------

Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
This commit is contained in:
Jacob Shandling 2023-03-15 15:44:48 -07:00 committed by GitHub
parent 50994e4695
commit 6f9dd8e40b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 12 deletions

View file

@ -6,7 +6,9 @@ import {
buildQueryStringFromParams,
getLabelParam,
reconcileMutuallyExclusiveHostParams,
reconcileMutuallyInclusiveHostParams,
} from "utilities/url";
import { MacSettingsStatusQueryParam } from "./hosts";
export interface ISortOption {
key: string;
@ -22,6 +24,7 @@ export interface IHostCountLoadOptions {
teamId?: number;
policyId?: number;
policyResponse?: string;
macSettingsStatus?: MacSettingsStatusQueryParam;
softwareId?: number;
lowDiskSpaceHosts?: number;
mdmId?: number;
@ -40,6 +43,7 @@ export default {
const globalFilter = options?.globalFilter || "";
const teamId = options?.teamId;
const softwareId = options?.softwareId;
const macSettingsStatus = options?.macSettingsStatus;
const status = options?.status;
const mdmId = options?.mdmId;
const mdmEnrollmentStatus = options?.mdmEnrollmentStatus;
@ -52,7 +56,7 @@ export default {
const queryParams = {
query: globalFilter,
team_id: teamId,
...reconcileMutuallyInclusiveHostParams({ teamId, macSettingsStatus }),
...reconcileMutuallyExclusiveHostParams({
label,
policyId,

View file

@ -6,6 +6,7 @@ import {
buildQueryStringFromParams,
getLabelParam,
reconcileMutuallyExclusiveHostParams,
reconcileMutuallyInclusiveHostParams,
} from "utilities/url";
import { ISelectedPlatform } from "interfaces/platform";
@ -161,7 +162,7 @@ export default {
order_key: sortBy[0].key,
order_direction: sortBy[0].direction,
query: globalFilter,
team_id: teamId,
...reconcileMutuallyInclusiveHostParams({ teamId, macSettingsStatus }),
...reconcileMutuallyExclusiveHostParams({
label,
policyId,
@ -208,22 +209,18 @@ export default {
const label = getLabel(selectedLabels);
const sortParams = getSortParams(sortBy);
// ensure macos_settings filter is always applied in
// conjuction with a team_id, 0 (no teams) by default
if (macSettingsStatus) {
teamId = teamId ?? 0;
}
const queryParams = {
page,
per_page: perPage,
query: globalFilter,
team_id: teamId,
device_mapping,
order_key: sortParams.order_key,
order_direction: sortParams.order_direction,
status,
macos_settings: macSettingsStatus,
...reconcileMutuallyInclusiveHostParams({
teamId,
macSettingsStatus,
}),
...reconcileMutuallyExclusiveHostParams({
label,
policyId,

View file

@ -1,10 +1,16 @@
import { isEmpty, reduce, omitBy, Dictionary } from "lodash";
import { MacSettingsStatusQueryParam } from "services/entities/hosts";
type QueryValues = string | number | boolean | undefined | null;
export type QueryParams = Record<string, QueryValues>;
type FilteredQueryValues = string | number | boolean;
type FilteredQueryParams = Record<string, FilteredQueryValues>;
interface IMutuallyInclusiveHostParams {
teamId?: number;
macSettingsStatus?: MacSettingsStatusQueryParam;
}
interface IMutuallyExclusiveHostParams {
label?: string;
policyId?: number;
@ -54,6 +60,18 @@ export const buildQueryStringFromParams = (queryParams: QueryParams) => {
return queryString;
};
export const reconcileMutuallyInclusiveHostParams = ({
teamId,
macSettingsStatus,
}: IMutuallyInclusiveHostParams): Record<string, unknown> => {
// ensure macos_settings filter is always applied in
// conjuction with a team_id, 0 (no teams) by default
const reconciled = { macos_settings: macSettingsStatus, team_id: teamId };
if (macSettingsStatus) {
reconciled.team_id = teamId ?? 0;
}
return reconciled;
};
export const reconcileMutuallyExclusiveHostParams = ({
label,
policyId,

View file

@ -1,6 +1,47 @@
import { buildQueryStringFromParams } from ".";
import {
buildQueryStringFromParams,
reconcileMutuallyInclusiveHostParams,
} from ".";
describe("url utilites", () => {
describe("url utilities > reconcileMutuallyInclusiveHostParams", () => {
it("leaves macSettingsStatus and teamId unchanged when both are present", () => {
const [macSettingsStatus, teamId] = ["pending" as const, 1];
expect(
reconcileMutuallyInclusiveHostParams({ macSettingsStatus, teamId })
).toEqual({
macos_settings: "pending",
team_id: 1,
});
});
it("adds team_id: 0 when macSettingsStatus is present and teamId is not", () => {
const [macSettingsStatus, teamId] = ["pending" as const, undefined];
expect(
reconcileMutuallyInclusiveHostParams({
macSettingsStatus,
teamId,
})
).toEqual({ macos_settings: "pending", team_id: 0 });
});
it("does not add macos_settings when teamId is present and macSettingsStatus is not", () => {
const [macSettingsStatus, teamId] = [undefined, 1];
expect(
reconcileMutuallyInclusiveHostParams({ macSettingsStatus, teamId })
).toEqual({
team_id: 1,
});
});
it("adds nothing when neither macSettingsStatus nor teamId are present", () => {
const [macSettingsStatus, teamId] = [undefined, undefined];
expect(
reconcileMutuallyInclusiveHostParams({ macSettingsStatus, teamId })
).toEqual({});
});
});
describe("url utilites > buildQueryStringFromParams", () => {
it("creates a query string from a params object", () => {
const params = {
query: "test",