logging
This commit is contained in:
parent
bb058306f0
commit
1b31712ac7
7 changed files with 260 additions and 250 deletions
|
|
@ -398,20 +398,23 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- KSeF 2.0 Client -->
|
<!-- KSeF 2.0 Client
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>pl.akmf.ksef-sdk</groupId>
|
<groupId>pl.akmf.ksef-sdk</groupId>
|
||||||
<artifactId>ksef-client</artifactId>
|
<artifactId>ksef-client</artifactId>
|
||||||
<version>3.0.4</version>
|
<version>3.0.4</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
-->
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<!--
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>github-cirfmf</id>
|
<id>github-cirfmf</id>
|
||||||
<url>https://maven.pkg.github.com/CIRFMF/ksef-client-java</url>
|
<url>https://maven.pkg.github.com/CIRFMF/ksef-client-java</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
-->
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -80,12 +80,12 @@ public class KSeFAPIService {
|
||||||
public String uploadInvoice(ItemCollection workitem, String fileName)
|
public String uploadInvoice(ItemCollection workitem, String fileName)
|
||||||
throws PluginException {
|
throws PluginException {
|
||||||
String referenceNumber = null;
|
String referenceNumber = null;
|
||||||
logger.info("├── Upload Invoice...");
|
logger.info("├── 📤 Upload Invoice...");
|
||||||
|
|
||||||
// First open an interactive Session. The KSeFAuthManager automatically reuses
|
// First open an interactive Session. The KSeFAuthManager automatically reuses
|
||||||
// an existing session
|
// an existing session
|
||||||
|
|
||||||
kseFAuthManager.openSession();
|
// kseFAuthManager.openSession();
|
||||||
|
|
||||||
if (kseFAuthManager.getAccessToken() == null) {
|
if (kseFAuthManager.getAccessToken() == null) {
|
||||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||||
|
|
@ -167,7 +167,7 @@ public class KSeFAPIService {
|
||||||
String uri = kseFAuthManager.getBaseURI() + "/sessions/online/"
|
String uri = kseFAuthManager.getBaseURI() + "/sessions/online/"
|
||||||
+ kseFAuthManager.getSessionRefNumber()
|
+ kseFAuthManager.getSessionRefNumber()
|
||||||
+ "/invoices";
|
+ "/invoices";
|
||||||
logger.info("│ ├── Endpoint: " + uri);
|
logger.info("│ ├── Endpoint: " + uri);
|
||||||
|
|
||||||
if (kseFAuthManager.isDebug()) {
|
if (kseFAuthManager.isDebug()) {
|
||||||
logger.info("Request: " + jsonBody);
|
logger.info("Request: " + jsonBody);
|
||||||
|
|
|
||||||
|
|
@ -78,18 +78,23 @@ public class KSeFAuthManager {
|
||||||
|
|
||||||
private HttpClient httpClient;
|
private HttpClient httpClient;
|
||||||
private String baseURI = "";
|
private String baseURI = "";
|
||||||
private String challenge = "";
|
|
||||||
private String refNumber = null;
|
// public keys
|
||||||
private String authToken = null;
|
|
||||||
private String accessToken = null;
|
|
||||||
private String challengeTimestamp = null;
|
|
||||||
private String symmetricCertBase64;
|
private String symmetricCertBase64;
|
||||||
private String ksefTokenCertBase64;
|
private String ksefTokenCertBase64;
|
||||||
private PublicKey symmetricPublicKey;
|
private PublicKey symmetricPublicKey;
|
||||||
private PublicKey ksefTokenPublicKey;
|
private PublicKey ksefTokenPublicKey;
|
||||||
|
|
||||||
|
// Auth information
|
||||||
|
private String challenge = "";
|
||||||
|
private String authRefNumber = null;
|
||||||
|
private String authToken = null;
|
||||||
|
private String challengeTimestamp = null;
|
||||||
|
|
||||||
|
// Session information
|
||||||
|
private String accessToken = null;
|
||||||
private String sessionRefNumber;
|
private String sessionRefNumber;
|
||||||
private String sessionValidUntil;
|
private String sessionValidUntil;
|
||||||
|
|
||||||
private byte[] sessionAesKey;
|
private byte[] sessionAesKey;
|
||||||
private byte[] sessionIv;
|
private byte[] sessionIv;
|
||||||
|
|
||||||
|
|
@ -154,8 +159,8 @@ public class KSeFAuthManager {
|
||||||
return baseURI;
|
return baseURI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRefNumber() {
|
public String getAuthRefNumber() {
|
||||||
return refNumber;
|
return authRefNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAuthToken() {
|
public String getAuthToken() {
|
||||||
|
|
@ -193,6 +198,9 @@ public class KSeFAuthManager {
|
||||||
|
|
||||||
this.authChallenge();
|
this.authChallenge();
|
||||||
this.authKSeFToken();
|
this.authKSeFToken();
|
||||||
|
|
||||||
|
this.checkTokenStatus();
|
||||||
|
|
||||||
this.redeemToken();
|
this.redeemToken();
|
||||||
this.openInteractiveSession();
|
this.openInteractiveSession();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -246,6 +254,85 @@ public class KSeFAuthManager {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper Method to read the certificates
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Lock(LockType.WRITE)
|
||||||
|
public void loadPublicKeyCertificates() throws PluginException {
|
||||||
|
|
||||||
|
logger.info("├── ♻️ KSeF API load public-key-certificates...");
|
||||||
|
String uri = baseURI + "/security/public-key-certificates";
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
logger.info("│ ├── Endpoint: " + uri);
|
||||||
|
}
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(URI.create(uri))
|
||||||
|
.header("Accept", "application/json")
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = null;
|
||||||
|
try {
|
||||||
|
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||||
|
"Unable to send request for KSeF certificates endpoint: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
logger.info("│ ├── Response Code = " + response.statusCode());
|
||||||
|
logger.info("Response: " + response.body());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.statusCode() != 200) {
|
||||||
|
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||||
|
"Unexpected response from KSeF certificates endpoint: " + response.statusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON parsen
|
||||||
|
try (Jsonb jsonb = JsonbBuilder.create()) {
|
||||||
|
|
||||||
|
var certArray = jsonb.fromJson(response.body(), JsonObject[].class);
|
||||||
|
for (JsonObject entry : certArray) {
|
||||||
|
// usage = ["KsefTokenEncryption"] oder ["SymmetricKeyEncryption"]
|
||||||
|
var usages = entry.getJsonArray("usage");
|
||||||
|
|
||||||
|
if (usages.stream().anyMatch(v -> v.toString().contains("KsefTokenEncryption"))) {
|
||||||
|
ksefTokenCertBase64 = entry.getString("certificate");
|
||||||
|
if (debug) {
|
||||||
|
logger.info("│ ├── ✓ KsefTokenEncryption certificate found.");
|
||||||
|
} // Public Key extrahieren
|
||||||
|
ksefTokenPublicKey = extractPublicKeyFromCertificate(ksefTokenCertBase64);
|
||||||
|
logger.info("│ ├── ✓ RSA PublicKey successfully extracted.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usages.stream().anyMatch(v -> v.toString().contains("SymmetricKeyEncryption"))) {
|
||||||
|
symmetricCertBase64 = entry.getString("certificate");
|
||||||
|
if (debug) {
|
||||||
|
logger.info("│ ├── ✓ SymmetricKeyEncryption certificate found.");
|
||||||
|
}
|
||||||
|
// Public Key extrahieren
|
||||||
|
symmetricPublicKey = extractPublicKeyFromCertificate(symmetricCertBase64);
|
||||||
|
logger.info("│ ├── ✓ Symetric PublicKey successfully extracted.");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ksefTokenPublicKey == null) {
|
||||||
|
logger.warning("│ ├── ⚠️ No certificate with usage 'ksefTokenPublicKey' found!");
|
||||||
|
}
|
||||||
|
if (symmetricPublicKey == null) {
|
||||||
|
logger.warning("│ ├── ⚠️ No certificate with usage 'symmetricPublicKey' found!");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||||
|
"Error parsing certificates JSON: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diese method führt den challenge Request durch
|
* Diese method führt den challenge Request durch
|
||||||
*
|
*
|
||||||
|
|
@ -254,9 +341,12 @@ public class KSeFAuthManager {
|
||||||
// @Lock(LockType.READ)
|
// @Lock(LockType.READ)
|
||||||
@Lock(LockType.WRITE)
|
@Lock(LockType.WRITE)
|
||||||
public void authChallenge() throws PluginException {
|
public void authChallenge() throws PluginException {
|
||||||
logger.info("├── KSeF API Challenge...");
|
logger.info("├── 🛅 KSeF API Challenge...");
|
||||||
String uri = baseURI + "/auth/challenge";
|
String uri = baseURI + "/auth/challenge";
|
||||||
logger.info("│ ├── Endpoint: " + uri);
|
|
||||||
|
if (debug) {
|
||||||
|
logger.info("│ ├── Endpoint: " + uri);
|
||||||
|
}
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
.uri(URI.create(uri)) // nur Endpoint checken
|
.uri(URI.create(uri)) // nur Endpoint checken
|
||||||
.header("Accept", "application/json")
|
.header("Accept", "application/json")
|
||||||
|
|
@ -266,8 +356,8 @@ public class KSeFAuthManager {
|
||||||
HttpResponse<String> response;
|
HttpResponse<String> response;
|
||||||
try {
|
try {
|
||||||
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
logger.info("│ ├── Response Code = " + response.statusCode());
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
|
logger.info("│ ├── Response Code = " + response.statusCode());
|
||||||
logger.info("Response: " + response.body());
|
logger.info("Response: " + response.body());
|
||||||
}
|
}
|
||||||
// Prüfen, dass wir eine API-Antwort bekommen, kein HTML
|
// Prüfen, dass wir eine API-Antwort bekommen, kein HTML
|
||||||
|
|
@ -283,10 +373,9 @@ public class KSeFAuthManager {
|
||||||
JsonObject jsonObject = jsonb.fromJson(response.body(), JsonObject.class);
|
JsonObject jsonObject = jsonb.fromJson(response.body(), JsonObject.class);
|
||||||
challenge = jsonObject.getString("challenge");
|
challenge = jsonObject.getString("challenge");
|
||||||
challengeTimestamp = jsonObject.getString("timestamp");
|
challengeTimestamp = jsonObject.getString("timestamp");
|
||||||
if (debug) {
|
|
||||||
logger.info("│ ├── challenge: " + challenge);
|
logger.info("│ ├── ✓ challenge: " + challenge);
|
||||||
logger.info("│ ├── timestamp: " + challengeTimestamp);
|
logger.info("│ ├── ✓ timestamp: " + challengeTimestamp);
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.severe("├── ⚠️ Error parsing JSON response" + e.getMessage());
|
logger.severe("├── ⚠️ Error parsing JSON response" + e.getMessage());
|
||||||
|
|
@ -310,10 +399,12 @@ public class KSeFAuthManager {
|
||||||
*/
|
*/
|
||||||
@Lock(LockType.WRITE)
|
@Lock(LockType.WRITE)
|
||||||
public void authKSeFToken() throws PluginException {
|
public void authKSeFToken() throws PluginException {
|
||||||
logger.info("├── KSeF API auth ksef-token...");
|
logger.info("├── 🛃 KSeF API auth ksef-token...");
|
||||||
String uri = baseURI + "/auth/ksef-token";
|
String uri = baseURI + "/auth/ksef-token";
|
||||||
logger.info("│ ├── Endpoint: " + uri);
|
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
logger.info("│ ├── Endpoint: " + uri);
|
||||||
|
}
|
||||||
HttpResponse<String> response = null;
|
HttpResponse<String> response = null;
|
||||||
try {
|
try {
|
||||||
String jsonPayload = String.format(
|
String jsonPayload = String.format(
|
||||||
|
|
@ -339,8 +430,9 @@ public class KSeFAuthManager {
|
||||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||||
"API Error: Unable to request ksef-token");
|
"API Error: Unable to request ksef-token");
|
||||||
}
|
}
|
||||||
logger.info("│ ├── Response Code = " + response.statusCode());
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
|
logger.info("│ ├── Response Code = " + response.statusCode());
|
||||||
logger.info("Response: " + response.body());
|
logger.info("Response: " + response.body());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -356,14 +448,15 @@ public class KSeFAuthManager {
|
||||||
JsonObject jsonObject = jsonb.fromJson(response.body(), JsonObject.class);
|
JsonObject jsonObject = jsonb.fromJson(response.body(), JsonObject.class);
|
||||||
|
|
||||||
// Reference Number speichern
|
// Reference Number speichern
|
||||||
refNumber = jsonObject.getString("referenceNumber");
|
authRefNumber = jsonObject.getString("referenceNumber");
|
||||||
logger.info("Extracted referenceNumber: " + refNumber);
|
logger.info("│ ├── ✓ referenceNumber: " + authRefNumber);
|
||||||
|
|
||||||
// Authentication Token speichern
|
// Authentication Token speichern
|
||||||
JsonObject authTokenObject = jsonObject.getJsonObject("authenticationToken");
|
JsonObject authTokenObject = jsonObject.getJsonObject("authenticationToken");
|
||||||
authToken = authTokenObject.getString("token");
|
authToken = authTokenObject.getString("token");
|
||||||
logger.info("Extracted authenticationToken: " + authToken);
|
if (debug) {
|
||||||
|
logger.info("│ ├── ✓ authenticationToken: " + authToken);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.severe("├── ⚠️ Error parsing JSON response" + e.getMessage());
|
logger.severe("├── ⚠️ Error parsing JSON response" + e.getMessage());
|
||||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||||
|
|
@ -386,9 +479,11 @@ public class KSeFAuthManager {
|
||||||
"Error - missing access token!");
|
"Error - missing access token!");
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("├── KSeF API open interactive session...");
|
logger.info("├── 🔐 KSeF API open interactive session...");
|
||||||
String uri = baseURI + "/sessions/online";
|
String uri = baseURI + "/sessions/online";
|
||||||
logger.info("│ ├── Endpoint: " + uri);
|
if (debug) {
|
||||||
|
logger.info("│ ├── Endpoint: " + uri);
|
||||||
|
}
|
||||||
HttpResponse<String> response = null;
|
HttpResponse<String> response = null;
|
||||||
try {
|
try {
|
||||||
// --- AES Schlüssel erzeugen ---
|
// --- AES Schlüssel erzeugen ---
|
||||||
|
|
@ -436,8 +531,8 @@ public class KSeFAuthManager {
|
||||||
|
|
||||||
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
|
||||||
logger.info("│ ├── Response Code = " + response.statusCode());
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
|
logger.info("│ ├── Response Code = " + response.statusCode());
|
||||||
logger.info("Response: " + response.body());
|
logger.info("Response: " + response.body());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -553,9 +648,12 @@ public class KSeFAuthManager {
|
||||||
@Lock(LockType.WRITE)
|
@Lock(LockType.WRITE)
|
||||||
public JsonObject redeemToken() throws PluginException {
|
public JsonObject redeemToken() throws PluginException {
|
||||||
|
|
||||||
logger.info("├── KSeF API redeem token...");
|
logger.info("├── 🛂 KSeF API redeem token...");
|
||||||
String uri = baseURI + "/auth/token/redeem";
|
String uri = baseURI + "/auth/token/redeem";
|
||||||
logger.info("│ ├── Endpoint: " + uri);
|
|
||||||
|
if (debug) {
|
||||||
|
logger.info("│ ├── Endpoint: " + uri);
|
||||||
|
}
|
||||||
HttpResponse<String> response = null;
|
HttpResponse<String> response = null;
|
||||||
try {
|
try {
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
|
@ -571,10 +669,10 @@ public class KSeFAuthManager {
|
||||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||||
"API Error - unable to redeemToken: " + e.getMessage());
|
"API Error - unable to redeemToken: " + e.getMessage());
|
||||||
}
|
}
|
||||||
logger.info("│ ├── Response Code = " + response.statusCode());
|
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
logger.info("│ └── Response: " + response.body());
|
logger.info("│ ├── Response Code = " + response.statusCode());
|
||||||
|
logger.info("│ ├── Response: " + response.body());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.statusCode() >= 400) {
|
if (response.statusCode() >= 400) {
|
||||||
|
|
@ -591,7 +689,7 @@ public class KSeFAuthManager {
|
||||||
JsonObject accessTokenObj = jsonObject.getJsonObject("accessToken");
|
JsonObject accessTokenObj = jsonObject.getJsonObject("accessToken");
|
||||||
this.accessToken = accessTokenObj.getString("token");
|
this.accessToken = accessTokenObj.getString("token");
|
||||||
|
|
||||||
logger.info("│ └── Access Token received");
|
logger.info("│ └── ☑️ Access Token received");
|
||||||
|
|
||||||
return jsonObject;
|
return jsonObject;
|
||||||
|
|
||||||
|
|
@ -603,80 +701,6 @@ public class KSeFAuthManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper Method to read the certificates
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
@Lock(LockType.WRITE)
|
|
||||||
public void loadPublicKeyCertificates() throws PluginException {
|
|
||||||
|
|
||||||
logger.info("├── KSeF API load public-key-certificates...");
|
|
||||||
String uri = baseURI + "/security/public-key-certificates";
|
|
||||||
logger.info("│ ├── Endpoint: " + uri);
|
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create(uri))
|
|
||||||
.header("Accept", "application/json")
|
|
||||||
.GET()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
HttpResponse<String> response = null;
|
|
||||||
try {
|
|
||||||
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
} catch (IOException | InterruptedException e) {
|
|
||||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
|
||||||
"Unable to send request for KSeF certificates endpoint: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("│ ├── Response Code = " + response.statusCode());
|
|
||||||
if (debug) {
|
|
||||||
logger.info("Response: " + response.body());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.statusCode() != 200) {
|
|
||||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
|
||||||
"Unexpected response from KSeF certificates endpoint: " + response.statusCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
// JSON parsen
|
|
||||||
try (Jsonb jsonb = JsonbBuilder.create()) {
|
|
||||||
|
|
||||||
var certArray = jsonb.fromJson(response.body(), JsonObject[].class);
|
|
||||||
for (JsonObject entry : certArray) {
|
|
||||||
// usage = ["KsefTokenEncryption"] oder ["SymmetricKeyEncryption"]
|
|
||||||
var usages = entry.getJsonArray("usage");
|
|
||||||
|
|
||||||
if (usages.stream().anyMatch(v -> v.toString().contains("KsefTokenEncryption"))) {
|
|
||||||
ksefTokenCertBase64 = entry.getString("certificate");
|
|
||||||
logger.info("│ ├── KsefTokenEncryption certificate found.");
|
|
||||||
// Public Key extrahieren
|
|
||||||
ksefTokenPublicKey = extractPublicKeyFromCertificate(ksefTokenCertBase64);
|
|
||||||
logger.info("│ ├── ✓ RSA PublicKey successfully extracted.");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (usages.stream().anyMatch(v -> v.toString().contains("SymmetricKeyEncryption"))) {
|
|
||||||
symmetricCertBase64 = entry.getString("certificate");
|
|
||||||
logger.info("│ ├── SymmetricKeyEncryption certificate found.");
|
|
||||||
// Public Key extrahieren
|
|
||||||
symmetricPublicKey = extractPublicKeyFromCertificate(symmetricCertBase64);
|
|
||||||
logger.info("│ ├── ✓ RSA PublicKey successfully extracted.");
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ksefTokenPublicKey == null) {
|
|
||||||
logger.warning("│ ├── ⚠️ No certificate with usage 'ksefTokenPublicKey' found!");
|
|
||||||
}
|
|
||||||
if (symmetricPublicKey == null) {
|
|
||||||
logger.warning("│ ├── ⚠️ No certificate with usage 'symmetricPublicKey' found!");
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
|
||||||
"Error parsing certificates JSON: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private PublicKey extractPublicKeyFromCertificate(String base64Cert) throws Exception {
|
private PublicKey extractPublicKeyFromCertificate(String base64Cert) throws Exception {
|
||||||
byte[] der = java.util.Base64.getDecoder().decode(base64Cert);
|
byte[] der = java.util.Base64.getDecoder().decode(base64Cert);
|
||||||
java.security.cert.CertificateFactory factory = java.security.cert.CertificateFactory.getInstance("X.509");
|
java.security.cert.CertificateFactory factory = java.security.cert.CertificateFactory.getInstance("X.509");
|
||||||
|
|
@ -686,45 +710,60 @@ public class KSeFAuthManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper Method to analyze the auth status
|
* This method verifies the actual status of the authentication process for the
|
||||||
|
* current auth token (this is the token received from the start of the auth
|
||||||
|
* procedure)
|
||||||
*
|
*
|
||||||
* @return
|
* https://ksef-test.mf.gov.pl/docs/v2/index.html#tag/Uzyskiwanie-dostepu/paths/~1api~1v2~1auth~1%7BreferenceNumber%7D/get
|
||||||
* @throws Exception
|
*
|
||||||
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
public JsonObject getAuthStatus() throws Exception {
|
public void checkTokenStatus() throws PluginException {
|
||||||
if (refNumber == null) {
|
logger.info("├── 🌡️ KSeF API check auth status...");
|
||||||
throw new IllegalStateException("Reference number is missing. Call generateAuthToken() first.");
|
String uri = baseURI + "/auth/" + authRefNumber;
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("├── KSeF API check authentication status...");
|
|
||||||
|
|
||||||
String uri = baseURI + "/auth/" + refNumber;
|
|
||||||
logger.info("│ ├── Endpoint: " + uri);
|
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create(uri))
|
|
||||||
.header("Accept", "application/json")
|
|
||||||
.header("Authorization", "Bearer " + authToken)
|
|
||||||
.GET()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
logger.info("│ ├── Response Code = " + response.statusCode());
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
logger.info("Response: " + response.body());
|
logger.info("│ ├── Endpoint: " + uri);
|
||||||
}
|
}
|
||||||
|
HttpResponse<String> response = null;
|
||||||
if (response.statusCode() >= 500) {
|
try {
|
||||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_CONFIG,
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
"Unable to access KSeF API: response=" + response.statusCode());
|
.uri(URI.create(uri))
|
||||||
|
.header("Accept", "application/json")
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.header("Authorization", "Bearer " + authToken)
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||||
|
"API Error: Unable to request auth status: " + e.getMessage());
|
||||||
|
}
|
||||||
|
if (true) {
|
||||||
|
logger.info("│ ├── Response Code = " + response.statusCode());
|
||||||
|
logger.info("Response: " + response.body());
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Jsonb jsonb = JsonbBuilder.create()) {
|
try (Jsonb jsonb = JsonbBuilder.create()) {
|
||||||
JsonObject jsonObject = jsonb.fromJson(response.body(), JsonObject.class);
|
JsonObject jsonObject = jsonb.fromJson(response.body(), JsonObject.class);
|
||||||
Boolean isRedeemed = jsonObject.containsKey("isTokenRedeemed") ? jsonObject.getBoolean("isTokenRedeemed")
|
Boolean isRedeemed = jsonObject.containsKey("isTokenRedeemed") ? jsonObject.getBoolean("isTokenRedeemed")
|
||||||
: null;
|
: null;
|
||||||
logger.info("│ ├── isTokenRedeemed: " + isRedeemed);
|
|
||||||
return jsonObject;
|
String lastTokenRefreshDate = jsonObject.containsKey("lastTokenRefreshDate")
|
||||||
|
? jsonObject.getString("lastTokenRefreshDate")
|
||||||
|
: null;
|
||||||
|
String refreshTokenValidUntil = jsonObject.containsKey("refreshTokenValidUntil")
|
||||||
|
? jsonObject.getString("refreshTokenValidUntil")
|
||||||
|
: null;
|
||||||
|
|
||||||
|
logger.info("│ ├── › lastTokenRefreshDate: " + lastTokenRefreshDate);
|
||||||
|
if (isRedeemed) {
|
||||||
|
logger.info("│ ├── ✓ isTokenRedeemed: " + isRedeemed);
|
||||||
|
logger.info("│ ├── ✓ refreshTokenValidUntil: " + refreshTokenValidUntil);
|
||||||
|
} else {
|
||||||
|
logger.info("│ ├── 𐄂 isTokenRedeemed: " + isRedeemed);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.severe("├── ⚠️ Error parsing JSON response: " + e.getMessage());
|
logger.severe("├── ⚠️ Error parsing JSON response: " + e.getMessage());
|
||||||
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
throw new PluginException(KSeFAuthManager.class.getSimpleName(), ERROR_API,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.alexanderlogistics;
|
||||||
|
|
||||||
|
import java.util.logging.ConsoleHandler;
|
||||||
|
import java.util.logging.Handler;
|
||||||
|
import java.util.logging.LogRecord;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.logging.SimpleFormatter;
|
||||||
|
|
||||||
|
public class TestLoggerConfig {
|
||||||
|
public static void setupTestLogger() {
|
||||||
|
Logger logger = Logger.getLogger("");
|
||||||
|
Handler[] handlers = logger.getHandlers();
|
||||||
|
|
||||||
|
for (Handler handler : handlers) {
|
||||||
|
if (handler instanceof ConsoleHandler) {
|
||||||
|
handler.setFormatter(new SimpleFormatter() {
|
||||||
|
@Override
|
||||||
|
public String format(LogRecord record) {
|
||||||
|
return String.format("%s%n",
|
||||||
|
record.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,74 +21,80 @@ import org.junit.jupiter.api.TestMethodOrder;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import com.alexanderlogistics.TestLoggerConfig;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
public class KSeFAPIServiceTest {
|
public class KSeFAPIServiceTest {
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(KSeFAPIServiceTest.class.getName());
|
private static Logger logger = Logger.getLogger(KSeFAPIServiceTest.class.getName());
|
||||||
|
|
||||||
private KSeFAuthManager manager;
|
private KSeFAuthManager manager;
|
||||||
private KSeFAPIService apiService;
|
private KSeFAPIService apiService;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setup() throws Exception {
|
void setup() throws Exception {
|
||||||
manager = new KSeFAuthManager();
|
|
||||||
|
|
||||||
// Test config
|
TestLoggerConfig.setupTestLogger();
|
||||||
manager.setKsefToken(Params.TOKEN);
|
|
||||||
manager.setKsefNip(Params.NIP);
|
|
||||||
manager.setKsefEndpoint("https://ksef-test.mf.gov.pl/api/v2");
|
|
||||||
manager.setDebug(true);
|
|
||||||
|
|
||||||
// init() ausführen
|
manager = new KSeFAuthManager();
|
||||||
manager.init();
|
|
||||||
|
|
||||||
// Open Session
|
// Test config
|
||||||
manager.openSession();
|
manager.setKsefToken(Params.TOKEN);
|
||||||
|
manager.setKsefNip(Params.NIP);
|
||||||
|
manager.setKsefEndpoint("https://ksef-test.mf.gov.pl/api/v2");
|
||||||
|
manager.setDebug(false);
|
||||||
|
|
||||||
// manager.loadPublicKeyCertificates();
|
// init() ausführen
|
||||||
// manager.authChallenge();
|
manager.init();
|
||||||
// manager.authKSeFToken();
|
|
||||||
// manager.redeemToken();
|
|
||||||
// manager.openInteractiveSession();
|
|
||||||
|
|
||||||
// Create API Service and inject manager
|
// Open Session
|
||||||
apiService = new KSeFAPIService();
|
manager.openSession();
|
||||||
apiService.kseFAuthManager = manager;
|
|
||||||
|
|
||||||
}
|
manager.checkTokenStatus();
|
||||||
|
// manager.loadPublicKeyCertificates();
|
||||||
|
// manager.authChallenge();
|
||||||
|
// manager.authKSeFToken();
|
||||||
|
// manager.redeemToken();
|
||||||
|
// manager.openInteractiveSession();
|
||||||
|
|
||||||
@Test
|
// Create API Service and inject manager
|
||||||
@Order(4)
|
apiService = new KSeFAPIService();
|
||||||
@DisplayName("Upload Invoice XML (AES-256 + RSA)")
|
apiService.kseFAuthManager = manager;
|
||||||
public void testUploadInvoice() throws Exception {
|
|
||||||
logger.info("==> Test: Upload Invoice XML");
|
|
||||||
|
|
||||||
ItemCollection workitem = createWorkitem();
|
}
|
||||||
|
|
||||||
// Execute upload
|
@Test
|
||||||
String referenceNumber = apiService.uploadInvoice(workitem, "example-invoice-01.xml");
|
@Order(4)
|
||||||
|
@DisplayName("Upload Invoice XML (AES-256 + RSA)")
|
||||||
|
public void testUploadInvoice() throws Exception {
|
||||||
|
logger.info("==> Test: Upload Invoice XML");
|
||||||
|
|
||||||
// Verify result
|
ItemCollection workitem = createWorkitem();
|
||||||
assertNotNull(referenceNumber, "Reference number should not be null");
|
|
||||||
assertFalse(referenceNumber.isEmpty(), "Reference number should not be empty");
|
|
||||||
|
|
||||||
logger.info("✅ Upload successful - Reference Number: " + referenceNumber);
|
// Execute upload
|
||||||
|
String referenceNumber = apiService.uploadInvoice(workitem, "example-invoice-01.xml");
|
||||||
|
|
||||||
FileData file = workitem.getFileData("example-invoice-01.xml");
|
// Verify result
|
||||||
ItemCollection fileAttributes = new ItemCollection(file.getAttributes());
|
assertNotNull(referenceNumber, "Reference number should not be null");
|
||||||
assertEquals(referenceNumber, fileAttributes.getItemValueString("ksef.referenceNumber"));
|
assertFalse(referenceNumber.isEmpty(), "Reference number should not be empty");
|
||||||
}
|
|
||||||
|
|
||||||
private ItemCollection createWorkitem() throws IOException {
|
logger.info("✅ Upload successful - Reference Number: " + referenceNumber);
|
||||||
ItemCollection workitem = new ItemCollection();
|
|
||||||
// ---------- 2) XML laden ----------
|
|
||||||
Path xmlPath = Paths.get("src/test/resources/ksef/example-invoice-01.xml");
|
|
||||||
byte[] invoiceXml = Files.readAllBytes(xmlPath);
|
|
||||||
|
|
||||||
FileData fileData = new FileData("example-invoice-01.xml", invoiceXml, null, null);
|
FileData file = workitem.getFileData("example-invoice-01.xml");
|
||||||
workitem.addFileData(fileData);
|
ItemCollection fileAttributes = new ItemCollection(file.getAttributes());
|
||||||
|
assertEquals(referenceNumber, fileAttributes.getItemValueString("ksef.referenceNumber"));
|
||||||
|
}
|
||||||
|
|
||||||
return workitem;
|
private ItemCollection createWorkitem() throws IOException {
|
||||||
}
|
ItemCollection workitem = new ItemCollection();
|
||||||
|
// ---------- 2) XML laden ----------
|
||||||
|
Path xmlPath = Paths.get("src/test/resources/ksef/example-invoice-01.xml");
|
||||||
|
byte[] invoiceXml = Files.readAllBytes(xmlPath);
|
||||||
|
|
||||||
|
FileData fileData = new FileData("example-invoice-01.xml", invoiceXml, null, null);
|
||||||
|
workitem.addFileData(fileData);
|
||||||
|
|
||||||
|
return workitem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ public class KSeFAuthManagerTest {
|
||||||
manager.redeemToken();
|
manager.redeemToken();
|
||||||
|
|
||||||
assertNotNull(
|
assertNotNull(
|
||||||
manager.getRefNumber(),
|
manager.getAuthRefNumber(),
|
||||||
"RefNumber darf nicht NULL sein");
|
"RefNumber darf nicht NULL sein");
|
||||||
|
|
||||||
assertNotNull(
|
assertNotNull(
|
||||||
|
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
package com.alexanderlogistics.ksef;
|
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
|
||||||
import org.junit.jupiter.api.TestMethodOrder;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
|
|
||||||
import pl.akmf.ksef.sdk.api.services.DefaultCryptographyService;
|
|
||||||
import pl.akmf.ksef.sdk.client.interfaces.KSeFClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dieser Test testet den offiziellen KSeF Client
|
|
||||||
*
|
|
||||||
* <dependency>
|
|
||||||
* <groupId>pl.akmf.ksef-sdk</groupId>
|
|
||||||
* <artifactId>ksef-client</artifactId>
|
|
||||||
* <version>3.0.4</version>
|
|
||||||
* <scope>test</scope>
|
|
||||||
* </dependency>
|
|
||||||
*/
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
|
||||||
public class KSeFClientTest {
|
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(KSeFClientTest.class.getName());
|
|
||||||
|
|
||||||
private DefaultCryptographyService cryptographyService;
|
|
||||||
private KSeFClient ksefClient;
|
|
||||||
private String accessToken;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setup() throws Exception {
|
|
||||||
// Simply instantiate as POJOs
|
|
||||||
// cryptographyService = new DefaultCryptographyService();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
|
||||||
// 1) Challenge abholen
|
|
||||||
// ------------------------------------------------------------
|
|
||||||
// @Test
|
|
||||||
// @Order(1)
|
|
||||||
// @DisplayName("POST /api/v2/auth/token/redeem")
|
|
||||||
// void testRedeemToken() throws Exception {
|
|
||||||
|
|
||||||
// EncryptionData encryptionData = cryptographyService.getEncryptionData();
|
|
||||||
|
|
||||||
// OpenOnlineSessionRequest request = new OpenOnlineSessionRequestBuilder()
|
|
||||||
// .withFormCode(new FormCode(SystemCode.FA_3, SchemaVersion.VERSION_1_0E,
|
|
||||||
// SessionValue.FA))
|
|
||||||
// .withEncryptionInfo(encryptionData.encryptionInfo())
|
|
||||||
// .build();
|
|
||||||
|
|
||||||
// OpenOnlineSessionResponse openOnlineSessionResponse =
|
|
||||||
// ksefClient.openOnlineSession(request,
|
|
||||||
// accessToken);
|
|
||||||
// logger.info("OK");
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue