mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-04 02:04:06 +00:00
Co-authored-by: alejandrobailo <alejandrobailo94@gmail.com>
137 lines
3.8 KiB
TypeScript
137 lines
3.8 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import templateSchema from "./fixtures/template-credential-schema.json";
|
|
import { parseRegistryCredentialSchema } from "./provider-credential-schema";
|
|
import {
|
|
getCredentialDefaults,
|
|
validateCredentialValues,
|
|
} from "./provider-credential-values";
|
|
|
|
const schema = parseRegistryCredentialSchema({
|
|
type: "object",
|
|
properties: {
|
|
token: { type: "string", format: "password", writeOnly: true },
|
|
region: { type: "string", enum: ["eu", "us"], default: "eu" },
|
|
notes: { type: "string", "x-prowler-widget": "textarea" },
|
|
},
|
|
required: ["token"],
|
|
})!;
|
|
|
|
describe("dynamic credential validation", () => {
|
|
const template = () => parseRegistryCredentialSchema(templateSchema)!;
|
|
const templateValues = {
|
|
api_url: "https://api.example.test",
|
|
api_key: "fixture-key-not-a-secret",
|
|
verify_tls: false,
|
|
timeout_seconds: "60",
|
|
};
|
|
|
|
it("preserves typed Template defaults and submits booleans and integers", () => {
|
|
// Given / When / Then
|
|
expect(getCredentialDefaults(template())).toEqual({
|
|
ca_bundle: "",
|
|
verify_tls: true,
|
|
timeout_seconds: 30,
|
|
auth_scheme: "bearer",
|
|
});
|
|
expect(validateCredentialValues(template(), templateValues)).toEqual({
|
|
valid: true,
|
|
secret: { ...templateValues, timeout_seconds: 60 },
|
|
errors: {},
|
|
});
|
|
});
|
|
|
|
it.each([1, 300, "1", "300"])("accepts timeout boundary %j", (timeout) => {
|
|
expect(
|
|
validateCredentialValues(template(), {
|
|
...templateValues,
|
|
timeout_seconds: timeout,
|
|
}),
|
|
).toMatchObject({
|
|
valid: true,
|
|
secret: { timeout_seconds: Number(timeout) },
|
|
});
|
|
});
|
|
|
|
it.each([
|
|
0,
|
|
301,
|
|
1.5,
|
|
"1.5",
|
|
" ",
|
|
"1second",
|
|
"0x10",
|
|
true,
|
|
null,
|
|
Infinity,
|
|
NaN,
|
|
])("rejects invalid Template timeouts: %j", (timeout) => {
|
|
expect(
|
|
validateCredentialValues(template(), {
|
|
...templateValues,
|
|
timeout_seconds: timeout,
|
|
}),
|
|
).toMatchObject({
|
|
valid: false,
|
|
errors: { timeout_seconds: expect.any(String) },
|
|
});
|
|
});
|
|
|
|
it.each(["true", "false", 0, 1, null])(
|
|
"rejects non-boolean TLS values: %j",
|
|
(verifyTls) => {
|
|
expect(
|
|
validateCredentialValues(template(), {
|
|
...templateValues,
|
|
verify_tls: verifyTls,
|
|
}),
|
|
).toMatchObject({
|
|
valid: false,
|
|
errors: { verify_tls: expect.any(String) },
|
|
});
|
|
},
|
|
);
|
|
|
|
it("accepts false and zero for required fields without treating them as missing", () => {
|
|
const requiredSchema = parseRegistryCredentialSchema({
|
|
type: "object",
|
|
properties: {
|
|
enabled: { type: "boolean" },
|
|
retries: { type: "integer" },
|
|
},
|
|
required: ["enabled", "retries"],
|
|
})!;
|
|
expect(getCredentialDefaults(requiredSchema)).toEqual({ enabled: false });
|
|
expect(
|
|
validateCredentialValues(requiredSchema, { enabled: false, retries: 0 }),
|
|
).toEqual({
|
|
valid: true,
|
|
secret: { enabled: false, retries: 0 },
|
|
errors: {},
|
|
});
|
|
expect(validateCredentialValues(requiredSchema, {})).toMatchObject({
|
|
valid: false,
|
|
errors: { enabled: expect.any(String), retries: expect.any(String) },
|
|
});
|
|
});
|
|
it("uses declared defaults and preserves credential bytes", () => {
|
|
expect(getCredentialDefaults(schema)).toEqual({ region: "eu" });
|
|
expect(
|
|
validateCredentialValues(schema, { token: " secret ", region: "eu" }),
|
|
).toEqual({
|
|
valid: true,
|
|
secret: { token: " secret ", region: "eu" },
|
|
errors: {},
|
|
});
|
|
});
|
|
it.each([
|
|
{},
|
|
{ token: "" },
|
|
{ token: "secret", region: "invalid" },
|
|
{ token: 12 },
|
|
{ token: "secret", extra: "hidden" },
|
|
])("rejects invalid or undeclared values: %j", (values) => {
|
|
expect(validateCredentialValues(schema, values).valid).toBe(false);
|
|
});
|
|
});
|