package com.juick.service; import java.net.URI; import java.util.Collections; import javax.inject.Inject; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.stereotype.Component; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import com.juick.www.api.webfinger.model.Account; import com.juick.www.api.webfinger.model.Link; import rocks.xmpp.addr.Jid; @Component public class WebfingerService { private static final Logger logger = LoggerFactory.getLogger("ActivityPub"); private final RestTemplate restClient; @Inject public WebfingerService(final RestTemplate restClient) { this.restClient = restClient; } public URI discoverAccountURI(String acct, MediaType linkType) { Jid acctId = Jid.of(acct); URI resourceUri = UriComponentsBuilder.fromPath("/.well-known/webfinger").host(acctId.getDomain()) .scheme("https").queryParam("resource", "acct:" + acct).build().toUri(); HttpHeaders headers = new HttpHeaders(); headers.setAccept(Collections.singletonList(MediaType.valueOf("application/jrd+json"))); HttpEntity webfingerRequest = new HttpEntity<>(headers); try { ResponseEntity response = restClient.exchange(resourceUri, HttpMethod.GET, webfingerRequest, Account.class); if (response.getStatusCode().is2xxSuccessful()) { var account = response.getBody(); for (Link l : account.links()) { if (l.rel().equals("self") && l.type().equals(linkType.toString())) { return URI.create(l.href()); } } } } catch (RestClientException e) { logger.warn("Cannot discover person {}: {}", acct, e.getMessage()); } return URI.create(StringUtils.EMPTY); } }