aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/juick
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/juick')
-rw-r--r--src/main/java/com/juick/ActivityPubManager.java27
-rw-r--r--src/main/java/com/juick/SignatureManager.java46
-rw-r--r--src/main/java/com/juick/config/ActivityPubClientErrorHandler.java12
-rw-r--r--src/main/java/com/juick/config/ActivityPubConfig.java5
-rw-r--r--src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java6
5 files changed, 45 insertions, 51 deletions
diff --git a/src/main/java/com/juick/ActivityPubManager.java b/src/main/java/com/juick/ActivityPubManager.java
index 63417626..1dd3b784 100644
--- a/src/main/java/com/juick/ActivityPubManager.java
+++ b/src/main/java/com/juick/ActivityPubManager.java
@@ -106,7 +106,7 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
@Override
public void deleteUserEvent(DeleteUserEvent event) {
String acct = event.getUserUri();
- logger.info("Deleting {} from followers", acct);
+ logger.debug("Deleting {} from followers", acct);
socialService.removeAccount(acct);
}
@@ -201,14 +201,18 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
Actor me = conversionService.convert(user, Actor.class);
socialService.getFollowers(user).forEach(acct -> {
try {
- Actor follower = (Actor) signatureManager.getContext(URI.create(acct)).orElseThrow();
- Update update = new Update();
- update.setId(userUri + "#update");
- update.setActor(me.getId());
- update.setObject(me);
- update.setPublished(Instant.now());
- logger.info("Update to follower {}", follower.getId());
- signatureManager.post(me, follower, update);
+ var context = signatureManager.getContext(URI.create(acct));
+ if (context.isPresent() && context.get() instanceof Actor follower) {
+ Update update = new Update();
+ update.setId(userUri + "#update");
+ update.setActor(me.getId());
+ update.setObject(me);
+ update.setPublished(Instant.now());
+ logger.info("Update to follower {}", follower.getId());
+ signatureManager.post(me, follower, update);
+ } else {
+ logger.warn("Unhandled context: {}", acct);
+ }
} catch (Exception e) {
logger.warn("activitypub exception", e);
}
@@ -233,9 +237,8 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
subscribers.addAll(note.getCc());
subscribers.forEach(acct -> {
if (!acct.equals(profileUriBuilder.followersUri(user))) {
- Optional<Context> context = signatureManager.getContext(URI.create(acct));
- if (context.isPresent() && context.get() instanceof Actor) {
- Actor follower = (Actor) context.get();
+ var context = signatureManager.getContext(URI.create(acct));
+ if (context.isPresent() && context.get() instanceof Actor follower) {
Create create = new Create();
create.setId(note.getId());
create.setActor(me.getId());
diff --git a/src/main/java/com/juick/SignatureManager.java b/src/main/java/com/juick/SignatureManager.java
index 9d6b68f7..92cb7fd9 100644
--- a/src/main/java/com/juick/SignatureManager.java
+++ b/src/main/java/com/juick/SignatureManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2020, Juick
+ * Copyright (C) 2008-2022, Juick
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -23,7 +23,6 @@ import com.juick.model.User;
import com.juick.service.UserService;
import com.juick.service.activities.DeleteUserEvent;
import com.juick.util.DateFormattersHolder;
-import com.juick.www.api.activity.model.Activity;
import com.juick.www.api.activity.model.Context;
import com.juick.www.api.activity.model.objects.Actor;
import com.juick.www.api.webfinger.model.Account;
@@ -33,19 +32,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
+import org.springframework.http.*;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import org.tomitribe.auth.signatures.Base64;
-import org.tomitribe.auth.signatures.MissingRequiredHeaderException;
-import org.tomitribe.auth.signatures.Signature;
-import org.tomitribe.auth.signatures.Signer;
-import org.tomitribe.auth.signatures.Verifier;
+import org.tomitribe.auth.signatures.*;
import rocks.xmpp.addr.Jid;
import javax.inject.Inject;
@@ -56,12 +48,7 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.time.Instant;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
import static com.juick.www.api.activity.model.Context.ACTIVITY_MEDIA_TYPE;
@@ -97,18 +84,18 @@ public class SignatureManager {
requestHeaders.add("Digest", digestHeader);
requestHeaders.add("Signature", signatureString);
HttpEntity<String> request = new HttpEntity<>(payload, requestHeaders);
- logger.info("Sending context to {}: {}", to.getId(), payload);
+ logger.debug("Sending context to {}: {}", to.getId(), payload);
ResponseEntity<Void> response = apClient.postForEntity(inbox, request, Void.class);
- logger.info("Remote response: {}", response.getStatusCodeValue());
+ logger.debug("Remote response: {}", response.getStatusCode());
}
public String addSignature(Actor from, String host, String method, String path, String dateString,
- String digestHeader) throws IOException {
+ String digestHeader) throws IOException {
return addSignature(from, host, method, path, dateString, digestHeader, keystoreManager);
}
public String addSignature(Actor from, String host, String method, String path, String dateString,
- String digestHeader, KeystoreManager keystoreManager) throws IOException {
+ String digestHeader, KeystoreManager keystoreManager) throws IOException {
List<String> requiredHeaders = StringUtils.isEmpty(digestHeader)
? Arrays.asList("(request-target)", "host", "date")
: Arrays.asList("(request-target)", "host", "date", "digest");
@@ -128,10 +115,9 @@ public class SignatureManager {
public User verifySignature(String method, String path, Map<String, String> headers) {
String signatureString = headers.get("signature");
Signature signature = Signature.fromString(signatureString);
- Optional<Context> context = getContext(
- UriComponentsBuilder.fromUriString(signature.getKeyId()).fragment(null).build().toUri());
- if (context.isPresent() && context.get() instanceof Actor) {
- Actor actor = (Actor) context.get();
+ var keyId = UriComponentsBuilder.fromUriString(signature.getKeyId()).fragment(null).build().toUri();
+ var context = getContext(keyId);
+ if (context.isPresent() && context.get() instanceof Actor actor) {
Key key = KeystoreManager.publicKeyOf(actor);
if (key != null) {
Verifier verifier = new Verifier(key, signature);
@@ -152,14 +138,14 @@ public class SignatureManager {
return AnonymousUser.INSTANCE;
}
} catch (NoSuchAlgorithmException | SignatureException | MissingRequiredHeaderException
- | IOException e) {
- logger.warn("Invalid signature {}: {}", signatureString, e.getMessage());
+ | IOException e) {
+ logger.warn("Verification error for {}: {}", signature.getKeyId(), e.getMessage());
}
} else {
- logger.warn("Unknown actor");
+ logger.warn("Public key missing for {}", actor.getId());
}
} else {
- logger.warn("Unknown keyId");
+ logger.warn("Public key error for {}", signature.getKeyId());
}
return AnonymousUser.INSTANCE;
}
@@ -177,7 +163,7 @@ public class SignatureManager {
}
return Optional.of(context);
} catch (Exception e) {
- logger.warn("REST Exception on {}: {}", contextUri, e.getMessage());
+ logger.warn("{}", e.getMessage());
}
return Optional.empty();
}
diff --git a/src/main/java/com/juick/config/ActivityPubClientErrorHandler.java b/src/main/java/com/juick/config/ActivityPubClientErrorHandler.java
index 69958bbd..23576ad5 100644
--- a/src/main/java/com/juick/config/ActivityPubClientErrorHandler.java
+++ b/src/main/java/com/juick/config/ActivityPubClientErrorHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2020, Juick
+ * Copyright (C) 2008-2022, Juick
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -28,6 +28,7 @@ import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.client.DefaultResponseErrorHandler;
+import javax.annotation.Nonnull;
import javax.inject.Inject;
import java.io.IOException;
import java.net.URI;
@@ -36,16 +37,17 @@ import java.nio.charset.StandardCharsets;
@Component
public class ActivityPubClientErrorHandler extends DefaultResponseErrorHandler {
private static final Logger logger = LoggerFactory.getLogger("ActivityPub");
-
@Inject
private ApplicationEventPublisher applicationEventPublisher;
@Override
- public void handleError(URI contextUri, HttpMethod method, ClientHttpResponse response) throws IOException {
- logger.warn("HTTP ERROR {} {} : {}", response.getStatusCode().value(),
- response.getStatusText(), IOUtils.toString(response.getBody(), StandardCharsets.UTF_8));
+ public void handleError(@Nonnull URI contextUri, @Nonnull HttpMethod method, ClientHttpResponse response)
+ throws IOException {
if (response.getStatusCode().equals(HttpStatus.GONE)) {
logger.warn("Server report {} is gone, deleting", contextUri.toASCIIString());
applicationEventPublisher.publishEvent(new DeleteUserEvent(this, contextUri.toASCIIString()));
+ } else {
+ logger.warn("HTTP ERROR {} {} : {}", response.getStatusCode().value(),
+ response.getStatusText(), IOUtils.toString(response.getBody(), StandardCharsets.UTF_8));
}
}
}
diff --git a/src/main/java/com/juick/config/ActivityPubConfig.java b/src/main/java/com/juick/config/ActivityPubConfig.java
index 3570b97d..9a626d12 100644
--- a/src/main/java/com/juick/config/ActivityPubConfig.java
+++ b/src/main/java/com/juick/config/ActivityPubConfig.java
@@ -29,6 +29,7 @@ import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
@@ -66,8 +67,8 @@ public class ActivityPubConfig {
CloseableHttpClient httpClient;
@Bean
- HttpComponentsClientHttpRequestFactory clientHttpRequestFactory() {
- HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
+ ClientHttpRequestFactory clientHttpRequestFactory() {
+ var clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setHttpClient(httpClient);
return clientHttpRequestFactory;
}
diff --git a/src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java b/src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java
index 723cf576..92e26406 100644
--- a/src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java
+++ b/src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java
@@ -32,6 +32,8 @@ import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
+
+import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
@@ -50,8 +52,8 @@ public class HTTPSignatureAuthenticationFilter extends OncePerRequestFilter {
}
@Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
- throws IOException, ServletException {
+ protected void doFilterInternal(@Nonnull HttpServletRequest request, @Nonnull HttpServletResponse response,
+ @Nonnull FilterChain filterChain) throws IOException, ServletException {
if (authenticationIsRequired()) {
Map<String, String> headers = Collections.list(request.getHeaderNames())
.stream()