update
This commit is contained in:
parent
278880a6b0
commit
e76a8dc668
2 changed files with 117 additions and 1 deletions
|
|
@ -2,7 +2,6 @@ package com.alexanderlogistics.ksef;
|
|||
|
||||
public class Params {
|
||||
public static final String TOKEN = "20251113-EC-2751AC3000-5C5466924B-62|nip-9552521552|fc0c95d020dc45d4af491fb0aa755f3f3f674b33ecbf4250a88ea6e36fa8340b";
|
||||
public static final String TOKENx = "20251113-EC-2751AC3000-5C5466924B-62.nip-9552521552.fc0c95d020dc45d4af491fb0aa755f3f3f674b33ecbf4250a88ea6e36fa8340b";
|
||||
public static final String NIP = "9552521552";
|
||||
|
||||
public static String getEncodedToken() {
|
||||
|
|
@ -10,4 +9,5 @@ public class Params {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,27 @@
|
|||
package com.alexanderlogistics.ksef;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
import org.imixs.workflow.exceptions.ModelException;
|
||||
import org.imixs.workflow.exceptions.PluginException;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
|
@ -44,6 +57,9 @@ public class TestKSeF {
|
|||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private String refNumber = null;
|
||||
private String authToken = null;
|
||||
|
||||
@BeforeAll
|
||||
public static void setupClass() {
|
||||
logger.info("=== KSeF 2.0 Client Test ===");
|
||||
|
|
@ -119,6 +135,106 @@ public class TestKSeF {
|
|||
// Prüfen, dass wir eine API-Antwort bekommen
|
||||
assertTrue(response.statusCode() < 500, "API sollte antworten, Status < 500");
|
||||
assertFalse(response.body().contains("<html>"), "Response sollte keine HTML-Seite sein");
|
||||
|
||||
// JSON parsen und Werte speichern
|
||||
if (response.statusCode() == 200 || response.statusCode() == 202) {
|
||||
JsonNode jsonNode = objectMapper.readTree(response.body());
|
||||
|
||||
// Reference Number speichern
|
||||
refNumber = jsonNode.get("referenceNumber").asText();
|
||||
logger.info("Extracted referenceNumber: " + refNumber);
|
||||
|
||||
// Authentication Token speichern
|
||||
authToken = jsonNode.get("authenticationToken").get("token").asText();
|
||||
logger.info("Extracted authenticationToken: " + authToken);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(3)
|
||||
@DisplayName("KSeF Public Key Zertifikate abrufen")
|
||||
public void testFetchKsefPublicKeys() throws Exception {
|
||||
assertNotNull(Params.TOKEN, "KSEF_TOKEN environment variable nicht gesetzt");
|
||||
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create(KSEF_TEST_URL + "/security/public-key-certificates"))
|
||||
.header("Accept", "application/json")
|
||||
.header("Authorization", "Bearer " + Params.TOKEN) // Access Token nutzen
|
||||
.GET()
|
||||
.build();
|
||||
|
||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
|
||||
System.out.println("Status: " + response.statusCode());
|
||||
System.out.println("Response: " + response.body());
|
||||
|
||||
// Assertions
|
||||
assertEquals(200, response.statusCode(), "Request sollte 200 OK zurückgeben");
|
||||
assertTrue(response.body().contains("certificate"), "Response sollte ein Feld 'certificate' enthalten");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(4)
|
||||
@DisplayName("Rechnung übermitteln an KSeF 2.0 API")
|
||||
public void testSendInvoice() throws Exception {
|
||||
assertNotNull(refNumber, "ReferenceNumber nicht gesetzt");
|
||||
|
||||
// 1. Rechnung laden
|
||||
Path invoicePath = Paths.get("test/resources/test-invoice.xml");
|
||||
byte[] invoiceBytes = Files.readAllBytes(invoicePath);
|
||||
int invoiceSize = invoiceBytes.length;
|
||||
|
||||
// 2. SHA-256 Hash der Originalrechnung
|
||||
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
||||
byte[] invoiceHashBytes = sha256.digest(invoiceBytes);
|
||||
String invoiceHash = Base64.getEncoder().encodeToString(invoiceHashBytes);
|
||||
|
||||
// 3. AES-256 Schlüssel + IV generieren
|
||||
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
|
||||
keyGen.init(256);
|
||||
SecretKey aesKey = keyGen.generateKey();
|
||||
byte[] ivBytes = new byte[16];
|
||||
new SecureRandom().nextBytes(ivBytes);
|
||||
IvParameterSpec iv = new IvParameterSpec(ivBytes);
|
||||
|
||||
// 4. Rechnung verschlüsseln (AES-256-CBC + PKCS7Padding)
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, aesKey, iv);
|
||||
byte[] encryptedInvoiceBytes = cipher.doFinal(invoiceBytes);
|
||||
|
||||
int encryptedInvoiceSize = encryptedInvoiceBytes.length;
|
||||
byte[] encryptedInvoiceHashBytes = sha256.digest(encryptedInvoiceBytes);
|
||||
String encryptedInvoiceHash = Base64.getEncoder().encodeToString(encryptedInvoiceHashBytes);
|
||||
|
||||
// 5. Verschlüsselten Inhalt Base64 codieren
|
||||
String encryptedInvoiceContent = Base64.getEncoder().encodeToString(encryptedInvoiceBytes);
|
||||
|
||||
// 6. JSON-Payload erstellen
|
||||
String jsonPayload = "{"
|
||||
+ "\"invoiceHash\":\"" + invoiceHash + "\","
|
||||
+ "\"invoiceSize\":" + invoiceSize + ","
|
||||
+ "\"encryptedInvoiceHash\":\"" + encryptedInvoiceHash + "\","
|
||||
+ "\"encryptedInvoiceSize\":" + encryptedInvoiceSize + ","
|
||||
+ "\"encryptedInvoiceContent\":\"" + encryptedInvoiceContent + "\","
|
||||
+ "\"offlineMode\":false"
|
||||
+ "}";
|
||||
|
||||
// 7. HTTP POST Request an die API
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create(KSEF_TEST_URL + "/sessions/online/" + refNumber + "/invoices"))
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Accept", "application/json")
|
||||
.header("Authorization", "Bearer " + authToken) // Token aus Authentifizierung
|
||||
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
|
||||
.build();
|
||||
|
||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
|
||||
System.out.println("Status: " + response.statusCode());
|
||||
System.out.println("Response: " + response.body());
|
||||
|
||||
assertEquals(200, response.statusCode(), "Invoice Upload sollte Status 200 zurückgeben");
|
||||
assertTrue(response.body().contains("invoiceId"), "Antwort sollte field invoiceId enthalten");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue