More fixes

This commit is contained in:
Tim Zöller 2025-11-29 22:00:35 +01:00
parent 3fa67c43d6
commit 96cf1fe5ad
3 changed files with 39 additions and 12 deletions

View file

@ -197,6 +197,23 @@ public class HttpSignatureValidator {
return Base64.getEncoder().encodeToString(signature); return Base64.getEncoder().encodeToString(signature);
} }
/**
* Container for HTTP signature headers.
*/
public static class SignatureHeaders {
public final String host;
public final String date;
public final String digest;
public final String signature;
public SignatureHeaders(String host, String date, String digest, String signature) {
this.host = host;
this.date = date;
this.digest = digest;
this.signature = signature;
}
}
/** /**
* Signs an outbound HTTP request for ActivityPub federation. * Signs an outbound HTTP request for ActivityPub federation.
* *
@ -205,9 +222,9 @@ public class HttpSignatureValidator {
* @param body the request body * @param body the request body
* @param privateKeyPem the sender's private key * @param privateKeyPem the sender's private key
* @param keyId the public key ID * @param keyId the public key ID
* @return the Signature header value * @return SignatureHeaders containing all headers needed for the signed request
*/ */
public String signRequest(String method, String targetUrl, String body, String privateKeyPem, String keyId) { public SignatureHeaders signRequest(String method, String targetUrl, String body, String privateKeyPem, String keyId) {
try { try {
java.net.URI uri = new java.net.URI(targetUrl); java.net.URI uri = new java.net.URI(targetUrl);
String host = uri.getHost(); String host = uri.getHost();
@ -239,11 +256,13 @@ public class HttpSignatureValidator {
String signatureBase64 = sign(signingString, privateKeyPem); String signatureBase64 = sign(signingString, privateKeyPem);
// Build signature header // Build signature header
return String.format( String signatureHeader = String.format(
"keyId=\"%s\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest\",signature=\"%s\"", "keyId=\"%s\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest\",signature=\"%s\"",
keyId, signatureBase64 keyId, signatureBase64
); );
return new SignatureHeaders(host, date, digestValue, signatureHeader);
} catch (Exception e) { } catch (Exception e) {
log.error("Failed to sign request", e); log.error("Failed to sign request", e);
throw new RuntimeException("Failed to sign request", e); throw new RuntimeException("Failed to sign request", e);

View file

@ -166,19 +166,24 @@ public class FederationService {
try { try {
String activityJson = objectMapper.writeValueAsString(activity); String activityJson = objectMapper.writeValueAsString(activity);
HttpHeaders headers = new HttpHeaders(); // Generate HTTP signature with all required headers
headers.set("Content-Type", "application/activity+json"); HttpSignatureValidator.SignatureHeaders signatureHeaders = signatureValidator.signRequest(
headers.set("Accept", "application/activity+json");
// Add HTTP signature
String signature = signatureValidator.signRequest(
HttpMethod.POST.name(), HttpMethod.POST.name(),
inboxUrl, inboxUrl,
activityJson, activityJson,
sender.getPrivateKey(), sender.getPrivateKey(),
baseUrl + "/users/" + sender.getUsername() + "#main-key" baseUrl + "/users/" + sender.getUsername() + "#main-key"
); );
headers.set("Signature", signature);
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/activity+json");
headers.set("Accept", "application/activity+json");
// Add all signature-related headers
headers.set("Host", signatureHeaders.host);
headers.set("Date", signatureHeaders.date);
headers.set("Digest", signatureHeaders.digest);
headers.set("Signature", signatureHeaders.signature);
HttpEntity<String> entity = new HttpEntity<>(activityJson, headers); HttpEntity<String> entity = new HttpEntity<>(activityJson, headers);

View file

@ -2,8 +2,11 @@
# Activated with: mvn spring-boot:run -Dspring-boot.run.profiles=dev # Activated with: mvn spring-boot:run -Dspring-boot.run.profiles=dev
spring: spring:
# Development datasource is handled by Testcontainers (see TestcontainersConfiguration) datasource:
# No need to configure datasource here - it's automatically configured url: jdbc:postgresql://localhost:5432/fitpub
username: fitpub
password: change_me_in_production
driver-class-name: org.postgresql.Driver
jpa: jpa:
hibernate: hibernate: