diff options
Diffstat (limited to 'src/main/java/com/juick/ActivityPubManager.java')
-rw-r--r-- | src/main/java/com/juick/ActivityPubManager.java | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/main/java/com/juick/ActivityPubManager.java b/src/main/java/com/juick/ActivityPubManager.java index 566cc1fd..461f4731 100644 --- a/src/main/java/com/juick/ActivityPubManager.java +++ b/src/main/java/com/juick/ActivityPubManager.java @@ -19,6 +19,7 @@ package com.juick; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.juick.model.AnonymousUser; import com.juick.model.Message; import com.juick.model.Reaction; import com.juick.model.User; @@ -46,10 +47,14 @@ import io.pebbletemplates.pebble.template.PebbleTemplate; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.core.convert.ConversionService; import org.springframework.http.MediaType; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; +import org.tomitribe.auth.signatures.MissingRequiredHeaderException; +import org.tomitribe.auth.signatures.Signature; +import org.tomitribe.auth.signatures.Verifier; import javax.annotation.Nonnull; import javax.inject.Inject; @@ -57,7 +62,9 @@ import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.net.URI; +import java.security.Key; import java.security.NoSuchAlgorithmException; +import java.security.SignatureException; import java.time.Instant; import java.util.*; import java.util.stream.Collectors; @@ -80,6 +87,10 @@ public class ActivityPubManager implements ActivityListener, NotificationListene ConversionService conversionService; @Inject ObjectMapper jsonMapper; + @Inject + private ApplicationEventPublisher applicationEventPublisher; + @Inject + private KeystoreManager keystoreManager; @Override public void processFollowEvent(@Nonnull FollowEvent followEvent) { @@ -420,4 +431,51 @@ public class ActivityPubManager implements ActivityListener, NotificationListene throw new HttpNotFoundException(); } } + + public User verifyActor(String method, String path, Map<String, String> headers) { + String signatureString = headers.get("signature"); + if (StringUtils.isNotEmpty(signatureString)) { + Signature signature = Signature.fromString(signatureString); + var keyId = UriComponentsBuilder.fromUriString(signature.getKeyId()).fragment(null).build().toUri(); + var user = activityPubService.getUserByAccountUri(keyId.toASCIIString()); + Key key = null; + Actor actor = null; + if (!user.isAnonymous()) { + // local user + key = keystoreManager.getPublicKey(); + } else { + var context = activityPubService.get(keyId); + if (context.isPresent()) { + actor = (Actor) context.get(); + key = KeystoreManager.publicKeyOf(actor); + } + } + if (key != null) { + Verifier verifier = new Verifier(key, signature); + try { + boolean result = verifier.verify(method.toLowerCase(), path, headers); + if (result) { + if (!user.isAnonymous()) { + return user; + } else { + if (actor != null) { + User person = new User(); + person.setUri(URI.create(actor.getId())); + if (actor.isSuspended()) { + logger.info("{} is suspended, deleting", actor.getId()); + applicationEventPublisher + .publishEvent(new DeleteUserEvent(this, actor.getId())); + } + return person; + } + } + } + } catch (NoSuchAlgorithmException | SignatureException | MissingRequiredHeaderException + | IOException e) { + logger.warn("Verification error for {}: {}", signature.getKeyId(), e.getMessage()); + } + } + } + return AnonymousUser.INSTANCE; + } } |