From 37343750cd719f933db441e8e9b87709fccadc28 Mon Sep 17 00:00:00 2001 From: Pablo Lara Date: Wed, 30 Oct 2024 17:26:34 +0100 Subject: [PATCH] chore: add form for add-credentials-providers --- actions/providers/providers.ts | 58 +++++++++- .../add-credentials/page.tsx | 8 +- .../workflow/forms/add-credentials-form.tsx | 105 +++++++++++++----- .../workflow/forms/connect-account-form.tsx | 6 +- types/components.ts | 29 +++++ types/formSchemas.ts | 10 +- 6 files changed, 182 insertions(+), 34 deletions(-) diff --git a/actions/providers/providers.ts b/actions/providers/providers.ts index bbf1fbc844..842dec1f59 100644 --- a/actions/providers/providers.ts +++ b/actions/providers/providers.ts @@ -148,9 +148,63 @@ export const addProvider = async (formData: FormData) => { }; } }; +export const addCredentialsProvider = async (formData: FormData) => { + const session = await auth(); + const keyServer = process.env.API_BASE_URL; + const url = new URL(`${keyServer}/providers/secrets`); + + const aws_access_key_id = formData.get("aws_access_key_id"); + const aws_secret_access_key = formData.get("aws_secret_access_key"); + const aws_session_token = formData.get("aws_session_token"); + const secretName = formData.get("secretName"); + const providerId = formData.get("providerId"); + + const bodyData = { + data: { + type: "ProviderSecret", + attributes: { + secret_type: "static", + secret: { + aws_access_key_id: aws_access_key_id, + aws_secret_access_key: aws_secret_access_key, + aws_session_token: aws_session_token, + }, + name: secretName, + }, + relationships: { + provider: { + data: { + id: providerId, + type: "Provider", + }, + }, + }, + }, + }; + + try { + const response = await fetch(url.toString(), { + method: "POST", + headers: { + "Content-Type": "application/vnd.api+json", + Accept: "application/vnd.api+json", + Authorization: `Bearer ${session?.accessToken}`, + }, + body: JSON.stringify(bodyData), + }); + const data = await response.json(); + revalidatePath("/providers"); + return parseStringify(data); + } catch (error) { + console.error(error); + return { + error: getErrorMessage(error), + }; + } +}; export const checkConnectionProvider = async (formData: FormData) => { - // const session = await auth(); + const session = await auth(); const keyServer = process.env.API_BASE_URL; const providerId = formData.get("id"); @@ -162,9 +216,11 @@ export const checkConnectionProvider = async (formData: FormData) => { method: "POST", headers: { Accept: "application/vnd.api+json", + Authorization: `Bearer ${session?.accessToken}`, }, }); const data = await response.json(); + await wait(1000); revalidatePath("/providers"); return parseStringify(data); } catch (error) { diff --git a/app/(prowler)/providers/(set-up-provider)/add-credentials/page.tsx b/app/(prowler)/providers/(set-up-provider)/add-credentials/page.tsx index 5ccd9a1f25..c47c11e5b5 100644 --- a/app/(prowler)/providers/(set-up-provider)/add-credentials/page.tsx +++ b/app/(prowler)/providers/(set-up-provider)/add-credentials/page.tsx @@ -2,6 +2,10 @@ import React from "react"; import { AddCredentialsForm } from "@/components/providers/workflow/forms"; -export default function AddCredentialsPage() { - return ; +export default function AddCredentialsPage({ + searchParams, +}: { + searchParams: { provider: string; id: string }; +}) { + return ; } diff --git a/components/providers/workflow/forms/add-credentials-form.tsx b/components/providers/workflow/forms/add-credentials-form.tsx index 567a505310..e76c443215 100644 --- a/components/providers/workflow/forms/add-credentials-form.tsx +++ b/components/providers/workflow/forms/add-credentials-form.tsx @@ -3,26 +3,57 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { SaveIcon } from "lucide-react"; import { useRouter } from "next/navigation"; -import { useForm } from "react-hook-form"; +import { FieldErrors, useForm } from "react-hook-form"; import * as z from "zod"; +import { addCredentialsProvider } from "@/actions/providers/providers"; import { useToast } from "@/components/ui"; import { CustomButton, CustomInput } from "@/components/ui/custom"; import { Form } from "@/components/ui/form"; -import { addProvider } from "../../../../actions/providers/providers"; -import { addCredentialsFormSchema, ApiError } from "../../../../types"; +import { + addCredentialsFormSchema, + ApiError, + AWSCredentials, + CredentialsFormSchema, +} from "../../../../types"; export const AddCredentialsForm = ({ - providerType, + searchParams, }: { - providerType: string; + searchParams: { provider: string; id: string }; }) => { - const formSchema = addCredentialsFormSchema(providerType); - const { toast } = useToast(); + const providerType = searchParams.provider; + const providerId = searchParams.id; - const form = useForm>({ + const formSchema = addCredentialsFormSchema(providerType); + + const { toast } = useToast(); + const form = useForm({ resolver: zodResolver(formSchema), + defaultValues: { + secretName: "", + providerId, + ...(providerType === "aws" + ? { + aws_access_key_id: "", + aws_secret_access_key: "", + aws_session_token: "", + } + : providerType === "azure" + ? { + client_id: "", + client_secret: "", + tenant_id: "", + } + : providerType === "gcp" + ? { + client_id: "", + client_secret: "", + refresh_token: "", + } + : {}), + }, }); const isLoading = form.formState.isSubmitting; @@ -36,28 +67,32 @@ export const AddCredentialsForm = ({ ([key, value]) => value !== undefined && formData.append(key, value), ); - const data = await addProvider(formData); - console.log(data); + const data = await addCredentialsProvider(formData); if (data?.errors && data.errors.length > 0) { data.errors.forEach((error: ApiError) => { const errorMessage = error.detail; switch (error.source.pointer) { - case "/data/attributes/provider": - form.setError("providerType", { + case "/data/attributes/secret/aws_access_key_id": + form.setError("aws_access_key_id", { type: "server", message: errorMessage, }); break; - case "/data/attributes/uid": - case "/data/attributes/__all__": - form.setError("providerId", { + case "/data/attributes/secret/aws_secret_access_key": + form.setError("aws_secret_access_key", { type: "server", message: errorMessage, }); break; - case "/data/attributes/alias": - form.setError("providerAlias", { + case "/data/attributes/secret/aws_session_token": + form.setError("aws_session_token", { + type: "server", + message: errorMessage, + }); + break; + case "/data/attributes/name": + form.setError("secretName", { type: "server", message: errorMessage, }); @@ -81,43 +116,61 @@ export const AddCredentialsForm = ({ onSubmit={form.handleSubmit(onSubmitClient)} className="flex flex-col space-y-4" > + + {providerType === "aws" && ( <> - {/* AWS Access Key ID */} ) + .aws_access_key_id + } /> - {/* AWS Secret Access Key */} ) + .aws_secret_access_key + } /> - {/* AWS Session Token */} ) + .aws_session_token + } /> )} diff --git a/components/providers/workflow/forms/connect-account-form.tsx b/components/providers/workflow/forms/connect-account-form.tsx index 5af9b01c12..a2da297ae3 100644 --- a/components/providers/workflow/forms/connect-account-form.tsx +++ b/components/providers/workflow/forms/connect-account-form.tsx @@ -81,7 +81,11 @@ export const ConnectAccountForm = () => { }); setPrevStep(1); } else { - router.push("/providers/add-credentials"); + const { + id, + attributes: { provider }, + } = data.data; + router.push(`/providers/add-credentials?provider=${provider}&id=${id}`); } }; diff --git a/types/components.ts b/types/components.ts index 086e6e4a60..6d434f1264 100644 --- a/types/components.ts +++ b/types/components.ts @@ -26,6 +26,35 @@ export type NextUIColors = | "danger" | "default"; +export type AWSCredentials = { + aws_access_key_id: string; + aws_secret_access_key: string; + aws_session_token: string; + secretName: string; + providerId: string; +}; + +export type AzureCredentials = { + client_id: string; + client_secret: string; + tenant_id: string; + secretName: string; + providerId: string; +}; + +export type GCPCredentials = { + client_id: string; + client_secret: string; + refresh_token: string; + secretName: string; + providerId: string; +}; + +export type CredentialsFormSchema = + | AWSCredentials + | AzureCredentials + | GCPCredentials; + export interface SearchParamsProps { [key: string]: string | string[] | undefined; } diff --git a/types/formSchemas.ts b/types/formSchemas.ts index 64d6b94718..d9239c1633 100644 --- a/types/formSchemas.ts +++ b/types/formSchemas.ts @@ -39,8 +39,10 @@ export const addProviderFormSchema = z.object({ }); export const addCredentialsFormSchema = (providerType: string) => - z.object( - providerType === "aws" + z.object({ + secretName: z.string().optional(), + providerId: z.string(), + ...(providerType === "aws" ? { aws_access_key_id: z.string(), aws_secret_access_key: z.string(), @@ -58,8 +60,8 @@ export const addCredentialsFormSchema = (providerType: string) => client_secret: z.string(), refresh_token: z.string(), } - : {}, - ); + : {}), + }); export const editProviderFormSchema = (currentAlias: string) => z.object({