From b3d633cf0e8a6c35be9755702dedbea29ff3d897 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Tue, 4 Sep 2018 11:22:57 +0300 Subject: WebFinger support --- .../com/juick/server/api/webfinger/Resource.java | 56 ++++++++++++++++++++++ .../juick/server/api/webfinger/model/Account.java | 24 ++++++++++ .../com/juick/server/api/webfinger/model/Link.java | 31 ++++++++++++ .../server/configuration/ApiSecurityConfig.java | 2 +- .../java/com/juick/server/tests/ServerTests.java | 10 ++++ 5 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 juick-server/src/main/java/com/juick/server/api/webfinger/Resource.java create mode 100644 juick-server/src/main/java/com/juick/server/api/webfinger/model/Account.java create mode 100644 juick-server/src/main/java/com/juick/server/api/webfinger/model/Link.java (limited to 'juick-server') diff --git a/juick-server/src/main/java/com/juick/server/api/webfinger/Resource.java b/juick-server/src/main/java/com/juick/server/api/webfinger/Resource.java new file mode 100644 index 00000000..e43e02d1 --- /dev/null +++ b/juick-server/src/main/java/com/juick/server/api/webfinger/Resource.java @@ -0,0 +1,56 @@ +package com.juick.server.api.webfinger; + +import com.juick.User; +import com.juick.server.api.webfinger.model.Account; +import com.juick.server.api.webfinger.model.Link; +import com.juick.server.util.HttpNotFoundException; +import com.juick.service.UserService; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.util.UriComponentsBuilder; +import rocks.xmpp.addr.Jid; + +import javax.inject.Inject; +import java.util.Arrays; +import java.util.Collections; + +@RestController +public class Resource { + @Inject + private UserService userService; + @Value("${web_domain:localhost}") + private String domain; + @Value("${ap_base_uri:http://localhost:8080/}") + private String baseUri; + + @GetMapping("/.well-known/webfinger") + public Account getWebResource(@RequestParam String resource) { + if (resource.startsWith("acct:")) { + Jid account = Jid.of(resource.substring(5)); + if (account.getDomain().equals(domain)) { + User user = userService.getUserByName(account.getLocal()); + if (!user.isAnonymous()) { + UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(baseUri); + builder.path(String.format("/u/%s", user.getName())); + Link blog = new Link(); + blog.setRel("self"); + blog.setType("application/activity+json"); + blog.setHref(builder.toUriString()); + UriComponentsBuilder rssBuilder = UriComponentsBuilder.fromHttpUrl(baseUri); + rssBuilder.path(String.format("/rss/%s/blog", user.getName())); + Link rss = new Link(); + rss.setRel("self"); + rss.setType("application/rss+xml"); + rss.setHref(rssBuilder.toUriString()); + Account result = new Account(); + result.setSubject(resource); + result.setLinks(Arrays.asList(blog, rss)); + return result; + } + } + } + throw new HttpNotFoundException(); + } +} diff --git a/juick-server/src/main/java/com/juick/server/api/webfinger/model/Account.java b/juick-server/src/main/java/com/juick/server/api/webfinger/model/Account.java new file mode 100644 index 00000000..892fa303 --- /dev/null +++ b/juick-server/src/main/java/com/juick/server/api/webfinger/model/Account.java @@ -0,0 +1,24 @@ +package com.juick.server.api.webfinger.model; + +import java.util.List; + +public class Account { + private String subject; + private List links; + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public List getLinks() { + return links; + } + + public void setLinks(List links) { + this.links = links; + } +} diff --git a/juick-server/src/main/java/com/juick/server/api/webfinger/model/Link.java b/juick-server/src/main/java/com/juick/server/api/webfinger/model/Link.java new file mode 100644 index 00000000..48e7ab67 --- /dev/null +++ b/juick-server/src/main/java/com/juick/server/api/webfinger/model/Link.java @@ -0,0 +1,31 @@ +package com.juick.server.api.webfinger.model; + +public class Link { + private String rel; + private String type; + private String href; + + public String getRel() { + return rel; + } + + public void setRel(String rel) { + this.rel = rel; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getHref() { + return href; + } + + public void setHref(String href) { + this.href = href; + } +} diff --git a/juick-server/src/main/java/com/juick/server/configuration/ApiSecurityConfig.java b/juick-server/src/main/java/com/juick/server/configuration/ApiSecurityConfig.java index 8b37ef17..2f263a78 100644 --- a/juick-server/src/main/java/com/juick/server/configuration/ApiSecurityConfig.java +++ b/juick-server/src/main/java/com/juick/server/configuration/ApiSecurityConfig.java @@ -65,7 +65,7 @@ public class ApiSecurityConfig extends WebSecurityConfigurerAdapter { http.authorizeRequests() .antMatchers(HttpMethod.OPTIONS).permitAll() .antMatchers("/", "/messages", "/users", "/thread", "/tags", "/tlgmbtwbhk", "/fbwbhk", - "/skypebotendpoint", "/_fblogin", "/_vklogin", "_tglogin").permitAll() + "/skypebotendpoint", "/_fblogin", "/_vklogin", "_tglogin", "/u/**", "/.well-known/webfinger").permitAll() .anyRequest().hasRole("USER") .and().httpBasic().authenticationEntryPoint(juickAuthenticationEntryPoint()) .and().anonymous() diff --git a/juick-server/src/test/java/com/juick/server/tests/ServerTests.java b/juick-server/src/test/java/com/juick/server/tests/ServerTests.java index b5f5143b..9a4fb93a 100644 --- a/juick-server/src/test/java/com/juick/server/tests/ServerTests.java +++ b/juick-server/src/test/java/com/juick/server/tests/ServerTests.java @@ -1320,6 +1320,16 @@ public class ServerTests { assertThat(messagesService.getMessages(AnonymousUser.INSTANCE, Collections.singletonList(mid)).get(0).getReplies(), is(1)); assertThat(messagesService.getReplies(banned, mid).size(), is(2)); assertThat(messagesService.getMessages(banned, Collections.singletonList(mid)).get(0).getReplies(), is(2)); + } + @Test + public void accountUrlsShouldBeExposedOverWebfinger() throws Exception { + mockMvc.perform(get("/.well-known/webfinger?resource=acct:ugnich@localhost")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.subject", is("acct:ugnich@localhost"))) + .andExpect(jsonPath("$.links", hasSize(2))) + .andExpect(jsonPath("$.links[0].href", is("http://localhost:8080/u/ugnich"))); + mockMvc.perform(get("/.well-known/webfinger?resource=acct:durov@localhost")) + .andExpect(status().isNotFound()); } } -- cgit v1.2.3