From 6704afa3cae97fcbae320c10ef0e903913164d3e Mon Sep 17 00:00:00 2001
From: Felix Reichenbach <felix.reichenbach@mgm-tp.com>
Date: Fri, 3 Jan 2025 15:00:23 +0100
Subject: [PATCH] OZG-7136 add validation to PostfachAddress

---
 .../nachrichten/postfach/PostfachAddress.java |  5 ++
 .../postfach/PostfachNachricht.java           |  2 +
 .../postfach/PostfachRemoteService.java       |  7 +-
 .../BayernIdPostfachRemoteService.java        |  4 +-
 .../BayernIdPostfachRemoteServiceITCase.java  | 77 +++++++++++++++++
 .../osi/OsiPostfachRemoteServiceITCase.java   | 84 +++++++++++++++++++
 6 files changed, 176 insertions(+), 3 deletions(-)
 create mode 100644 nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteServiceITCase.java
 create mode 100644 nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteServiceITCase.java

diff --git a/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachAddress.java b/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachAddress.java
index 1329a83..86ee9d4 100644
--- a/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachAddress.java
+++ b/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachAddress.java
@@ -23,6 +23,9 @@
  */
 package de.ozgcloud.nachrichten.postfach;
 
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+
 import lombok.Builder;
 import lombok.Getter;
 import lombok.ToString;
@@ -40,6 +43,8 @@ public class PostfachAddress {
 
 	private String version;
 	private int type;
+	@NotNull
 	private PostfachAddressIdentifier identifier;
+	@NotBlank
 	private String serviceKontoType;
 }
\ No newline at end of file
diff --git a/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachricht.java b/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachricht.java
index d896f46..5064269 100644
--- a/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachricht.java
+++ b/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachNachricht.java
@@ -27,6 +27,7 @@ import java.time.ZonedDateTime;
 import java.util.Collections;
 import java.util.List;
 
+import jakarta.validation.Valid;
 import jakarta.validation.constraints.NotNull;
 
 import lombok.Builder;
@@ -67,6 +68,7 @@ public class PostfachNachricht {
 	private String id;
 
 	private String vorgangId;
+	@Valid
 	private PostfachAddress postfachAddress;
 	private String messageId;
 	private String referencedNachricht;
diff --git a/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachRemoteService.java b/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachRemoteService.java
index c4e2d19..170bd4d 100644
--- a/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachRemoteService.java
+++ b/nachrichten-manager-postfach-interface/src/main/java/de/ozgcloud/nachrichten/postfach/PostfachRemoteService.java
@@ -25,9 +25,14 @@ package de.ozgcloud.nachrichten.postfach;
 
 import java.util.stream.Stream;
 
+import jakarta.validation.Valid;
+
+import org.springframework.validation.annotation.Validated;
+
+@Validated
 public interface PostfachRemoteService {
 
-	void sendMessage(PostfachNachricht nachricht);
+	void sendMessage(@Valid PostfachNachricht nachricht);
 
 	Stream<PostfachNachricht> getAllMessages();
 
diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteService.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteService.java
index 7a89c7d..c961f31 100644
--- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteService.java
+++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteService.java
@@ -101,8 +101,8 @@ class BayernIdPostfachRemoteService implements PostfachRemoteService {
 	}
 
 	Function<StreamObserver<GrpcSendBayernIdMessageResponse>, CallStreamObserver<GrpcSendBayernIdMessageRequest>> buildCallStreamObserverBuilder() {
-		return responseObserver ->
-				(CallStreamObserver<GrpcSendBayernIdMessageRequest>) bayernIdProxyServiceStub.sendMessageAsStream(responseObserver);
+		return responseObserver -> (CallStreamObserver<GrpcSendBayernIdMessageRequest>) bayernIdProxyServiceStub
+				.sendMessageAsStream(responseObserver);
 	}
 
 	Function<String, BayernIdAttachment> buildAttachmentBuilder() {
diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteServiceITCase.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteServiceITCase.java
new file mode 100644
index 0000000..86f9e13
--- /dev/null
+++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/bayernid/BayernIdPostfachRemoteServiceITCase.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
+ * Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei
+ * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.ozgcloud.nachrichten.postfach.bayernid;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import jakarta.validation.ConstraintViolationException;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.NullAndEmptySource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+
+import de.ozgcloud.common.test.ITCase;
+import de.ozgcloud.nachrichten.email.EmailGrpcService;
+import de.ozgcloud.nachrichten.postfach.PostfachAddressTestFactory;
+import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory;
+
+@ITCase
+@SpringBootTest(properties = { "ozgcloud.bayernid.enabled = true" })
+class BayernIdPostfachRemoteServiceITCase {
+
+	@Autowired
+	private BayernIdPostfachRemoteService service;
+
+	@MockBean
+	private EmailGrpcService emailGrpcService;
+	@MockBean
+	private BayernIdProperties bayernIdProperties;
+
+	@Nested
+	class TestSendMessage {
+
+		@ParameterizedTest
+		@NullAndEmptySource
+		void shouldThrowConstraintViolationExceptionOnMissingKontoType(String serviceKontoType) {
+			var nachricht = PostfachNachrichtTestFactory.createBuilder()
+					.postfachAddress(PostfachAddressTestFactory.createBuilder().serviceKontoType(serviceKontoType).build())
+					.build();
+
+			assertThrows(ConstraintViolationException.class, () -> service.sendMessage(nachricht));
+		}
+
+		@Test
+		void shouldThrowConstraintViolationExceptionOnMissingIdentifier() {
+			var nachricht = PostfachNachrichtTestFactory.createBuilder()
+					.postfachAddress(PostfachAddressTestFactory.createBuilder().identifier(null).build())
+					.build();
+
+			assertThrows(ConstraintViolationException.class, () -> service.sendMessage(nachricht));
+		}
+	}
+}
\ No newline at end of file
diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteServiceITCase.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteServiceITCase.java
new file mode 100644
index 0000000..ee9c037
--- /dev/null
+++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/postfach/osi/OsiPostfachRemoteServiceITCase.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
+ * Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei
+ * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.ozgcloud.nachrichten.postfach.osi;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import jakarta.validation.ConstraintViolationException;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.NullAndEmptySource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.web.client.RestTemplate;
+
+import de.ozgcloud.common.test.ITCase;
+import de.ozgcloud.nachrichten.email.EmailGrpcService;
+import de.ozgcloud.nachrichten.postfach.PostfachAddressTestFactory;
+import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory;
+
+@ITCase
+@SpringBootTest(properties = {
+		"ozgcloud.osi.postfach.proxyapi.url = foo",
+		"ozgcloud.osi.postfach.proxyapi.key = bar",
+		"ozgcloud.osi.postfach.proxyapi.realm = foobar"
+})
+class OsiPostfachRemoteServiceITCase {
+
+	@Autowired
+	private OsiPostfachRemoteService service;
+
+	@MockBean
+	private EmailGrpcService emailGrpcService;
+	@MockBean
+	private OsiPostfachProperties properties;
+	@MockBean
+	private RestTemplate restTemplate;
+
+	@Nested
+	class TestSendMessage {
+
+		@ParameterizedTest
+		@NullAndEmptySource
+		void shouldThrowConstraintViolationExceptionOnMissingKontoType(String serviceKontoType) {
+			var nachricht = PostfachNachrichtTestFactory.createBuilder()
+					.postfachAddress(PostfachAddressTestFactory.createBuilder().serviceKontoType(serviceKontoType).build())
+					.build();
+
+			assertThrows(ConstraintViolationException.class, () -> service.sendMessage(nachricht));
+		}
+
+		@Test
+		void shouldThrowConstraintViolationExceptionOnMissingIdentifier() {
+			var nachricht = PostfachNachrichtTestFactory.createBuilder()
+					.postfachAddress(PostfachAddressTestFactory.createBuilder().identifier(null).build())
+					.build();
+
+			assertThrows(ConstraintViolationException.class, () -> service.sendMessage(nachricht));
+		}
+	}
+}
\ No newline at end of file
-- 
GitLab