mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-01-25 02:08:11 +00:00
feat(ui): add MongoDB Atlas provider support (#9253)
Co-authored-by: Alan Buscaglia <gentlemanprogramming@gmail.com>
This commit is contained in:
committed by
GitHub
parent
6e135abaa0
commit
ed5f6b3af6
@@ -8,6 +8,7 @@ import {
|
||||
IacProviderBadge,
|
||||
KS8ProviderBadge,
|
||||
M365ProviderBadge,
|
||||
MongoDBAtlasProviderBadge,
|
||||
OracleCloudProviderBadge,
|
||||
} from "../icons/providers-badge";
|
||||
|
||||
@@ -38,6 +39,15 @@ export const CustomProviderInputM365 = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const CustomProviderInputMongoDBAtlas = () => {
|
||||
return (
|
||||
<div className="flex items-center gap-x-2">
|
||||
<MongoDBAtlasProviderBadge width={25} height={25} />
|
||||
<p className="text-sm">MongoDB Atlas</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const CustomProviderInputGCP = () => {
|
||||
return (
|
||||
<div className="flex items-center gap-x-2">
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
CustomProviderInputIac,
|
||||
CustomProviderInputKubernetes,
|
||||
CustomProviderInputM365,
|
||||
CustomProviderInputMongoDBAtlas,
|
||||
CustomProviderInputOracleCloud,
|
||||
} from "./custom-provider-inputs";
|
||||
|
||||
@@ -25,21 +26,13 @@ const providerDisplayData: Record<
|
||||
label: "Amazon Web Services",
|
||||
component: <CustomProviderInputAWS />,
|
||||
},
|
||||
gcp: {
|
||||
label: "Google Cloud Platform",
|
||||
component: <CustomProviderInputGCP />,
|
||||
},
|
||||
azure: {
|
||||
label: "Microsoft Azure",
|
||||
component: <CustomProviderInputAzure />,
|
||||
},
|
||||
m365: {
|
||||
label: "Microsoft 365",
|
||||
component: <CustomProviderInputM365 />,
|
||||
},
|
||||
kubernetes: {
|
||||
label: "Kubernetes",
|
||||
component: <CustomProviderInputKubernetes />,
|
||||
gcp: {
|
||||
label: "Google Cloud Platform",
|
||||
component: <CustomProviderInputGCP />,
|
||||
},
|
||||
github: {
|
||||
label: "GitHub",
|
||||
@@ -49,6 +42,18 @@ const providerDisplayData: Record<
|
||||
label: "Infrastructure as Code",
|
||||
component: <CustomProviderInputIac />,
|
||||
},
|
||||
kubernetes: {
|
||||
label: "Kubernetes",
|
||||
component: <CustomProviderInputKubernetes />,
|
||||
},
|
||||
m365: {
|
||||
label: "Microsoft 365",
|
||||
component: <CustomProviderInputM365 />,
|
||||
},
|
||||
mongodbatlas: {
|
||||
label: "MongoDB Atlas",
|
||||
component: <CustomProviderInputMongoDBAtlas />,
|
||||
},
|
||||
oraclecloud: {
|
||||
label: "Oracle Cloud Infrastructure",
|
||||
component: <CustomProviderInputOracleCloud />,
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
import { CONNECTION_STATUS_MAPPING } from "@/lib/helper-filters";
|
||||
import { FilterOption, FilterType } from "@/types/filters";
|
||||
import { PROVIDER_TYPES } from "@/types/providers";
|
||||
import {
|
||||
PROVIDER_DISPLAY_NAMES,
|
||||
PROVIDER_TYPES,
|
||||
ProviderType,
|
||||
} from "@/types/providers";
|
||||
|
||||
// Create a mapping for provider types to display with icons and labels
|
||||
const PROVIDER_TYPE_MAPPING = PROVIDER_TYPES.map((providerType) => ({
|
||||
[providerType]: {
|
||||
provider: providerType as ProviderType,
|
||||
uid: "",
|
||||
alias: PROVIDER_DISPLAY_NAMES[providerType],
|
||||
},
|
||||
}));
|
||||
|
||||
export const filterProviders: FilterOption[] = [
|
||||
{
|
||||
@@ -13,6 +26,7 @@ export const filterProviders: FilterOption[] = [
|
||||
key: "provider__in",
|
||||
labelCheckboxGroup: "Cloud Provider",
|
||||
values: [...PROVIDER_TYPES],
|
||||
valueLabelMapping: PROVIDER_TYPE_MAPPING,
|
||||
},
|
||||
// Add more filter categories as needed
|
||||
];
|
||||
@@ -22,6 +36,7 @@ export const filterScans = [
|
||||
key: "provider_type__in",
|
||||
labelCheckboxGroup: "Cloud Provider",
|
||||
values: [...PROVIDER_TYPES],
|
||||
valueLabelMapping: PROVIDER_TYPE_MAPPING,
|
||||
index: 0,
|
||||
},
|
||||
{
|
||||
@@ -64,6 +79,7 @@ export const filterFindings = [
|
||||
key: FilterType.PROVIDER_TYPE,
|
||||
labelCheckboxGroup: "Cloud Provider",
|
||||
values: [...PROVIDER_TYPES],
|
||||
valueLabelMapping: PROVIDER_TYPE_MAPPING,
|
||||
index: 5,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ import { GitHubProviderBadge } from "./github-provider-badge";
|
||||
import { IacProviderBadge } from "./iac-provider-badge";
|
||||
import { KS8ProviderBadge } from "./ks8-provider-badge";
|
||||
import { M365ProviderBadge } from "./m365-provider-badge";
|
||||
import { MongoDBAtlasProviderBadge } from "./mongodbatlas-provider-badge";
|
||||
import { OracleCloudProviderBadge } from "./oraclecloud-provider-badge";
|
||||
|
||||
export {
|
||||
@@ -17,6 +18,7 @@ export {
|
||||
IacProviderBadge,
|
||||
KS8ProviderBadge,
|
||||
M365ProviderBadge,
|
||||
MongoDBAtlasProviderBadge,
|
||||
OracleCloudProviderBadge,
|
||||
};
|
||||
|
||||
@@ -30,4 +32,5 @@ export const PROVIDER_ICONS: Record<string, React.FC<IconSvgProps>> = {
|
||||
GitHub: GitHubProviderBadge,
|
||||
"Infrastructure as Code": IacProviderBadge,
|
||||
"Oracle Cloud Infrastructure": OracleCloudProviderBadge,
|
||||
"MongoDB Atlas": MongoDBAtlasProviderBadge,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import * as React from "react";
|
||||
|
||||
import { IconSvgProps } from "@/types";
|
||||
|
||||
export const MongoDBAtlasProviderBadge: React.FC<IconSvgProps> = ({
|
||||
size,
|
||||
width,
|
||||
height,
|
||||
...props
|
||||
}) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-hidden="true"
|
||||
fill="none"
|
||||
focusable="false"
|
||||
height={size || height}
|
||||
role="presentation"
|
||||
viewBox="0 0 256 256"
|
||||
width={size || width}
|
||||
{...props}
|
||||
>
|
||||
<g fill="none">
|
||||
<rect width="256" height="256" fill="#e6f4ec" rx="60" />
|
||||
<g transform="translate(128 128) scale(7.25) translate(-16 -16)">
|
||||
<path
|
||||
d="M15.9.087l.854 1.604c.192.296.4.558.645.802.715.715 1.394 1.464 2.004 2.266 1.447 1.9 2.423 4.01 3.12 6.292.418 1.394.645 2.824.662 4.27.07 4.323-1.412 8.035-4.4 11.12-.488.488-1.01.94-1.57 1.342-.296 0-.436-.227-.558-.436-.227-.383-.366-.82-.436-1.255-.105-.523-.174-1.046-.14-1.586v-.244C16.057 24.21 15.796.21 15.9.087z"
|
||||
fill="#599636"
|
||||
/>
|
||||
<path
|
||||
d="M15.9.034c-.035-.07-.07-.017-.105.017.017.35-.105.662-.296.96-.21.296-.488.523-.767.767-1.55 1.342-2.77 2.963-3.747 4.776-1.3 2.44-1.97 5.055-2.16 7.808-.087.993.314 4.497.627 5.508.854 2.684 2.388 4.933 4.375 6.885.488.47 1.01.906 1.55 1.325.157 0 .174-.14.21-.244a4.78 4.78 0 0 0 .157-.68l.35-2.614L15.9.034z"
|
||||
fill="#6cac48"
|
||||
/>
|
||||
<path
|
||||
d="M16.754 28.845c.035-.4.227-.732.436-1.063-.21-.087-.366-.26-.488-.453-.105-.174-.192-.383-.26-.575-.244-.732-.296-1.5-.366-2.248v-.453c-.087.07-.105.662-.105.75a17.37 17.37 0 0 1-.314 2.353c-.052.314-.087.627-.28.906 0 .035 0 .07.017.122.314.924.4 1.865.453 2.824v.35c0 .418-.017.33.33.47.14.052.296.07.436.174.105 0 .122-.087.122-.157l-.052-.575v-1.604c-.017-.28.035-.558.07-.82z"
|
||||
fill="#c2bfbf"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
@@ -19,6 +19,7 @@ const providerTypeLabels: Record<ProviderType, string> = {
|
||||
github: "GitHub",
|
||||
iac: "Infrastructure as Code",
|
||||
oraclecloud: "Oracle Cloud Infrastructure",
|
||||
mongodbatlas: "MongoDB Atlas",
|
||||
};
|
||||
|
||||
interface EnhancedProviderSelectorProps {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Tooltip } from "@heroui/tooltip";
|
||||
import React from "react";
|
||||
|
||||
import { ProviderType } from "@/types";
|
||||
|
||||
import { ConnectionFalse, ConnectionPending, ConnectionTrue } from "../icons";
|
||||
import { getProviderLogo } from "../ui/entities";
|
||||
|
||||
interface ProviderInfoProps {
|
||||
connected: boolean | null;
|
||||
provider: ProviderType;
|
||||
@@ -12,12 +12,12 @@ interface ProviderInfoProps {
|
||||
providerUID?: string;
|
||||
}
|
||||
|
||||
export const ProviderInfo: React.FC<ProviderInfoProps> = ({
|
||||
export const ProviderInfo = ({
|
||||
connected,
|
||||
provider,
|
||||
providerAlias,
|
||||
providerUID,
|
||||
}) => {
|
||||
}: ProviderInfoProps) => {
|
||||
const getIcon = () => {
|
||||
switch (connected) {
|
||||
case true:
|
||||
@@ -31,8 +31,8 @@ export const ProviderInfo: React.FC<ProviderInfoProps> = ({
|
||||
case false:
|
||||
return (
|
||||
<Tooltip content="Provider connection failed" className="text-xs">
|
||||
<div className="rounded-medium border-danger bg-system-error-lighter flex items-center justify-center border-2 p-1">
|
||||
<ConnectionFalse className="text-text-error" size={24} />
|
||||
<div className="rounded-medium border-border-error flex items-center justify-center border-2 p-1">
|
||||
<ConnectionFalse className="text-text-error-primary" size={24} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
IacProviderBadge,
|
||||
KS8ProviderBadge,
|
||||
M365ProviderBadge,
|
||||
MongoDBAtlasProviderBadge,
|
||||
OracleCloudProviderBadge,
|
||||
} from "../icons/providers-badge";
|
||||
import { CustomRadio } from "../ui/custom";
|
||||
@@ -68,6 +69,12 @@ export const RadioGroupProvider: React.FC<RadioGroupProviderProps> = ({
|
||||
<span className="ml-2">Microsoft 365</span>
|
||||
</div>
|
||||
</CustomRadio>
|
||||
<CustomRadio description="MongoDB Atlas" value="mongodbatlas">
|
||||
<div className="flex items-center">
|
||||
<MongoDBAtlasProviderBadge size={26} />
|
||||
<span className="ml-2">MongoDB Atlas</span>
|
||||
</div>
|
||||
</CustomRadio>
|
||||
<CustomRadio description="Kubernetes" value="kubernetes">
|
||||
<div className="flex items-center">
|
||||
<KS8ProviderBadge size={26} />
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
KubernetesCredentials,
|
||||
M365CertificateCredentials,
|
||||
M365ClientSecretCredentials,
|
||||
MongoDBAtlasCredentials,
|
||||
OCICredentials,
|
||||
ProviderType,
|
||||
} from "@/types";
|
||||
@@ -37,6 +38,7 @@ import { AzureCredentialsForm } from "./via-credentials/azure-credentials-form";
|
||||
import { GitHubCredentialsForm } from "./via-credentials/github-credentials-form";
|
||||
import { IacCredentialsForm } from "./via-credentials/iac-credentials-form";
|
||||
import { KubernetesCredentialsForm } from "./via-credentials/k8s-credentials-form";
|
||||
import { MongoDBAtlasCredentialsForm } from "./via-credentials/mongodbatlas-credentials-form";
|
||||
import { OracleCloudCredentialsForm } from "./via-credentials/oraclecloud-credentials-form";
|
||||
|
||||
type BaseCredentialsFormProps = {
|
||||
@@ -172,6 +174,13 @@ export const BaseCredentialsForm = ({
|
||||
control={form.control as unknown as Control<OCICredentials>}
|
||||
/>
|
||||
)}
|
||||
{providerType === "mongodbatlas" && (
|
||||
<MongoDBAtlasCredentialsForm
|
||||
control={
|
||||
form.control as unknown as Control<MongoDBAtlasCredentials>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="flex w-full justify-end gap-4">
|
||||
{showBackButton && requiresBackButton(searchParamsObj.get("via")) && (
|
||||
|
||||
@@ -62,6 +62,11 @@ const getProviderFieldDetails = (providerType?: ProviderType) => {
|
||||
label: "Tenancy OCID",
|
||||
placeholder: "e.g. ocid1.tenancy.oc1..aaaaaaa...",
|
||||
};
|
||||
case "mongodbatlas":
|
||||
return {
|
||||
label: "Organization ID",
|
||||
placeholder: "e.g. 5f43a8c4e1234567890abcde",
|
||||
};
|
||||
default:
|
||||
return {
|
||||
label: "Provider UID",
|
||||
|
||||
@@ -45,7 +45,7 @@ export const TestConnectionForm = ({
|
||||
};
|
||||
provider: ProviderType;
|
||||
alias: string;
|
||||
scanner_args: Record<string, any>;
|
||||
scanner_args: Record<string, unknown>;
|
||||
};
|
||||
relationships: {
|
||||
secret: {
|
||||
@@ -239,27 +239,27 @@ export const TestConnectionForm = ({
|
||||
</div>
|
||||
|
||||
{apiErrorMessage && (
|
||||
<div className="text-text-error mt-4 rounded-md bg-red-100 p-3">
|
||||
<div className="text-text-error-primary mt-4 rounded-md p-3">
|
||||
<p>{`Provider ID ${apiErrorMessage?.toLowerCase()}. Please check and try again.`}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{connectionStatus && !connectionStatus.connected && (
|
||||
<>
|
||||
<div className="flex items-center gap-4 rounded-lg border border-red-200 bg-red-50 p-4">
|
||||
<div className="flex items-center">
|
||||
<div className="border-border-error flex items-start gap-4 rounded-lg border p-4">
|
||||
<div className="flex shrink-0 items-center">
|
||||
<Icon
|
||||
icon="heroicons:exclamation-circle"
|
||||
className="text-text-error h-5 w-5"
|
||||
className="text-text-error-primary h-5 w-5"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<p className="text-small text-text-error">
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="text-small text-text-error-primary break-words">
|
||||
{connectionStatus.error || "Unknown error"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-small text-text-error">
|
||||
<p className="text-small text-text-error-primary">
|
||||
It seems there was an issue with your credentials. Please review
|
||||
your credentials and try again.
|
||||
</p>
|
||||
|
||||
@@ -2,3 +2,4 @@ export * from "./azure-credentials-form";
|
||||
export * from "./github-credentials-form";
|
||||
export * from "./iac-credentials-form";
|
||||
export * from "./k8s-credentials-form";
|
||||
export * from "./mongodbatlas-credentials-form";
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { Control } from "react-hook-form";
|
||||
|
||||
import { CustomInput } from "@/components/ui/custom";
|
||||
import { ProviderCredentialFields } from "@/lib/provider-credentials/provider-credential-fields";
|
||||
import { MongoDBAtlasCredentials } from "@/types";
|
||||
|
||||
export const MongoDBAtlasCredentialsForm = ({
|
||||
control,
|
||||
}: {
|
||||
control: Control<MongoDBAtlasCredentials>;
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-md text-default-foreground leading-9 font-bold">
|
||||
Connect via API Keys
|
||||
</div>
|
||||
<div className="text-default-500 text-sm">
|
||||
Provide an organization-level MongoDB Atlas API public and private key
|
||||
with read access to the resources you want Prowler to assess.
|
||||
</div>
|
||||
</div>
|
||||
<CustomInput
|
||||
control={control}
|
||||
name={ProviderCredentialFields.ATLAS_PUBLIC_KEY}
|
||||
type="text"
|
||||
label="Atlas Public Key"
|
||||
labelPlacement="inside"
|
||||
placeholder="e.g. abcdefgh"
|
||||
variant="bordered"
|
||||
isRequired
|
||||
/>
|
||||
<CustomInput
|
||||
control={control}
|
||||
name={ProviderCredentialFields.ATLAS_PRIVATE_KEY}
|
||||
type="password"
|
||||
label="Atlas Private Key"
|
||||
labelPlacement="inside"
|
||||
placeholder="Enter the private key"
|
||||
variant="bordered"
|
||||
isRequired
|
||||
/>
|
||||
<div className="text-default-400 text-xs">
|
||||
Keys never leave your browser unencrypted and are stored as secrets in
|
||||
the backend. Rotate the key from MongoDB Atlas anytime if needed.
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
IacProviderBadge,
|
||||
KS8ProviderBadge,
|
||||
M365ProviderBadge,
|
||||
MongoDBAtlasProviderBadge,
|
||||
OracleCloudProviderBadge,
|
||||
} from "@/components/icons/providers-badge";
|
||||
import { ProviderType } from "@/types";
|
||||
@@ -30,6 +31,8 @@ export const getProviderLogo = (provider: ProviderType) => {
|
||||
return <IacProviderBadge width={35} height={35} />;
|
||||
case "oraclecloud":
|
||||
return <OracleCloudProviderBadge width={35} height={35} />;
|
||||
case "mongodbatlas":
|
||||
return <MongoDBAtlasProviderBadge width={35} height={35} />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -53,6 +56,8 @@ export const getProviderName = (provider: ProviderType): string => {
|
||||
return "Infrastructure as Code";
|
||||
case "oraclecloud":
|
||||
return "Oracle Cloud Infrastructure";
|
||||
case "mongodbatlas":
|
||||
return "MongoDB Atlas";
|
||||
default:
|
||||
return "Unknown Provider";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user