From 72a8501d378f938fb1384c6e03fae6853ac14eef Mon Sep 17 00:00:00 2001 From: Aboubacar TRAORE Date: Wed, 24 Dec 2025 13:51:09 +0000 Subject: [PATCH] updating webhook controller --- .../infisical/InfisicalWebhookController.java | 77 ++++++++++++++++--- 1 file changed, 67 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/abnov/infisicalbridge/infisical/InfisicalWebhookController.java b/src/main/java/com/abnov/infisicalbridge/infisical/InfisicalWebhookController.java index a530a9f..a810ca3 100644 --- a/src/main/java/com/abnov/infisicalbridge/infisical/InfisicalWebhookController.java +++ b/src/main/java/com/abnov/infisicalbridge/infisical/InfisicalWebhookController.java @@ -1,11 +1,27 @@ package com.abnov.infisicalbridge.infisical; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.abnov.infisicalbridge.dokploy.DokployClient; +import com.abnov.infisicalbridge.dto.DokployComposeUpdateRequest; +import com.abnov.infisicalbridge.dto.DokployComposeUpdateResponse; +import com.abnov.infisicalbridge.dto.InfisicalWebhookEventResponse; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.infisical.sdk.InfisicalSdk; +import com.infisical.sdk.models.Secret; +import com.infisical.sdk.util.InfisicalException; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -15,23 +31,64 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class InfisicalWebhookController { private final InfisicalSignatureVerifier signatureVerifier; + private final InfisicalService service; + private final InfisicalProperties infisicalProperties; + private final ObjectMapper objectMapper; + private final DokployClient dokployClient; @PostMapping - public void handleWebhook( + public ResponseEntity handleWebhook( @RequestBody String payload, - @RequestHeader(value = "X-Infisical-Signature", required = false) String signature) { - // Check if signature header is present + @RequestParam String dokployComposeId, + @RequestHeader(value = "X-Infisical-Signature", required = false) String signature) + throws InfisicalException { + if (signature == null || signature.isEmpty()) { - log.error("Missing signature header"); - return; + log.warn("Missing X-Infisical-Signature header"); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } - // Verify the signature - if (!signatureVerifier.verifySignature(payload, signature, "demoa")) { - log.error("Invalid signature"); - return; + if (!signatureVerifier.verifySignature(payload, signature, infisicalProperties.getWebhookSecret())) { + log.warn("Invalid webhook signature"); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } - log.info("Webhook received and verified: {}", payload); + InfisicalWebhookEventResponse webhookEvent; + try { + webhookEvent = objectMapper.readValue(payload, InfisicalWebhookEventResponse.class); + } catch (JsonProcessingException e) { + log.error("Invalid webhook payload", e); + return ResponseEntity.badRequest().build(); + } + + InfisicalSdk sdk = service.getSdk(); + List secrets = sdk.Secrets().ListSecrets( + webhookEvent.project().projectId(), + webhookEvent.project().environment(), + webhookEvent.project().secretPath(), + false, + false, + false); + + if (secrets.isEmpty()) { + log.warn("No secrets found for project={} env={}", + webhookEvent.project().projectName(), + webhookEvent.project().environment()); + return ResponseEntity.noContent().build(); + } + + String envContent = secrets.stream() + .map(s -> s.getSecretKey() + "=" + s.getSecretValue()) + .collect(Collectors.joining("\n")); + + try { + dokployClient.updateCompose( + new DokployComposeUpdateRequest(dokployComposeId, envContent)); + } catch (Exception e) { + log.error("Failed to update Dokploy compose {}", dokployComposeId, e); + return ResponseEntity.status(HttpStatus.BAD_GATEWAY).build(); + } + + return ResponseEntity.ok().build(); } }