feat(vorlagen): Platzhalter, Pruefung und Service fuer Vorlagen (#019)
Vorlagen werden beim Speichern so geprueft, wie sie spaeter benutzt werden: mit probeweise aufgeloesten Platzhaltern. Ein unbekannter Platzhalter ist ein Fehler, kein leerer Text - sonst stuende from="" in authorized_keys. Werte mit Anfuehrungszeichen, Kommas oder Leerraum koennen keine weiteren Optionen einschleusen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { EINGEBAUTE_VORLAGEN } from "../prisma/vorlagen";
|
||||
import {
|
||||
VorlagenFehler,
|
||||
istIpAdresse,
|
||||
platzhalterErsetzen,
|
||||
vorlageAufloesen,
|
||||
vorlagePruefen,
|
||||
type VorlageEingabe,
|
||||
} from "@/lib/vorlagen";
|
||||
|
||||
/** Vorlagen und Platzhalter (#019). */
|
||||
|
||||
const BASIS: VorlageEingabe = {
|
||||
name: "Test",
|
||||
schluesselTyp: "ED25519",
|
||||
kategorie: "DIENST",
|
||||
zielbenutzer: "deploy",
|
||||
zielbenutzerAnlegen: true,
|
||||
sudoModus: "KEINER",
|
||||
sudoBefehle: [],
|
||||
knownHostsEintragen: true,
|
||||
privatNachAusrollenLoeschen: false,
|
||||
};
|
||||
|
||||
describe("Platzhalter", () => {
|
||||
it("ersetzt bekannte Platzhalter", () => {
|
||||
expect(platzhalterErsetzen('from="{{quellHostIp}}"', { quellHostIp: "10.0.0.5" })).toBe(
|
||||
'from="10.0.0.5"',
|
||||
);
|
||||
expect(platzhalterErsetzen("deploy-{{ zielHost }}", { zielHost: "srv-app01" })).toBe("deploy-srv-app01");
|
||||
});
|
||||
|
||||
it("verweigert unbekannte, fehlende und gefaehrliche Werte", () => {
|
||||
expect(() => platzhalterErsetzen("{{irgendwas}}", {})).toThrow(VorlagenFehler);
|
||||
expect(() => platzhalterErsetzen("{{quellHostIp}}", {})).toThrow(/fehlt ein Wert/);
|
||||
expect(() =>
|
||||
platzhalterErsetzen('from="{{quellHostIp}}"', { quellHostIp: '1.2.3.4",command="id' }),
|
||||
).toThrow(VorlagenFehler);
|
||||
});
|
||||
|
||||
it("erkennt IP-Adressen", () => {
|
||||
expect(istIpAdresse("10.0.0.5")).toBe(true);
|
||||
expect(istIpAdresse("10.0.0.0/24")).toBe(true);
|
||||
expect(istIpAdresse("fe80::1")).toBe(true);
|
||||
expect(istIpAdresse("srv-app01")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Vorlage pruefen", () => {
|
||||
it("nimmt alle eingebauten Vorlagen an", () => {
|
||||
for (const vorlage of EINGEBAUTE_VORLAGEN) {
|
||||
expect(() =>
|
||||
vorlagePruefen({
|
||||
...BASIS,
|
||||
...vorlage,
|
||||
beschreibung: vorlage.beschreibung ?? null,
|
||||
kategorie: vorlage.kategorie as "PERSON" | "DIENST",
|
||||
schluesselTyp: (vorlage.schluesselTyp ?? "ED25519") as "ED25519",
|
||||
sudoBefehle: [],
|
||||
zielbenutzerAnlegen: vorlage.zielbenutzerAnlegen ?? false,
|
||||
sudoModus: (vorlage.sudoModus ?? "KEINER") as "KEINER",
|
||||
knownHostsEintragen: vorlage.knownHostsEintragen ?? true,
|
||||
privatNachAusrollenLoeschen: false,
|
||||
}),
|
||||
).not.toThrow();
|
||||
}
|
||||
});
|
||||
|
||||
it.each([
|
||||
[{ zielbenutzer: "Root" }, "zielbenutzer"],
|
||||
[{ authorizedKeysOptionen: 'from="{{unbekannt}}"' }, "authorizedKeysOptionen"],
|
||||
[{ authorizedKeysOptionen: "restriktiv" }, "authorizedKeysOptionen"],
|
||||
[{ sudoModus: "BEFEHLE" as const, sudoBefehle: [] }, "sudoBefehle"],
|
||||
[{ sudoModus: "BEFEHLE" as const, sudoBefehle: ["systemctl restart x"] }, "sudoBefehle"],
|
||||
[{ zielbenutzerAnlegen: false, sudoModus: "VOLL" as const }, "sudoModus"],
|
||||
[{ sshConfigAlias: "a b {{zielHost}}" }, "sshConfigAlias"],
|
||||
[{ kategorie: "PERSON" as const }, "kategorie"],
|
||||
])("weist ab: %o", (fehler, feld) => {
|
||||
try {
|
||||
vorlagePruefen({ ...BASIS, ...fehler });
|
||||
throw new Error("kein Fehler");
|
||||
} catch (fehlerObjekt) {
|
||||
expect(fehlerObjekt).toBeInstanceOf(VorlagenFehler);
|
||||
expect((fehlerObjekt as VorlagenFehler).feld).toBe(feld);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("Vorlage aufloesen", () => {
|
||||
it("liefert Optionen, Alias und Ablaufdatum", () => {
|
||||
const jetzt = new Date("2026-10-12T10:00:00Z");
|
||||
expect(
|
||||
vorlageAufloesen(
|
||||
{
|
||||
zielbenutzer: "deploy",
|
||||
authorizedKeysOptionen: 'from="{{quellHostIp}}"',
|
||||
sshConfigAlias: "deploy-{{zielHost}}",
|
||||
standardLaufzeitTage: 90,
|
||||
},
|
||||
{ quellHostIp: "10.0.0.5", zielHost: "srv-app01" },
|
||||
jetzt,
|
||||
),
|
||||
).toEqual({
|
||||
zielbenutzer: "deploy",
|
||||
authorizedKeysOptionen: 'from="10.0.0.5"',
|
||||
sshConfigAlias: "deploy-srv-app01",
|
||||
ablaufAm: new Date("2027-01-10T10:00:00Z"),
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user