From 0541dc6e943f4c53c3be57dbe83e1324dbd1e068 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Wed, 7 Nov 2018 17:59:40 +0300 Subject: /.well-known/x-nodeinfo2 --- .../java/com/juick/server/api/xnodeinfo2/Info.java | 48 +++++++++++++++++++ .../server/api/xnodeinfo2/model/NodeInfo.java | 54 ++++++++++++++++++++++ .../juick/server/api/xnodeinfo2/model/Server.java | 40 ++++++++++++++++ .../server/api/xnodeinfo2/model/ServiceInfo.java | 24 ++++++++++ .../juick/server/api/xnodeinfo2/model/Usage.java | 31 +++++++++++++ .../server/api/xnodeinfo2/model/UserStats.java | 31 +++++++++++++ .../juick/server/configuration/SecurityConfig.java | 2 +- .../java/com/juick/server/tests/ServerTests.java | 3 ++ juick-server/src/test/resources/xnodeinfo2.json | 24 ++++++++++ 9 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 juick-server/src/main/java/com/juick/server/api/xnodeinfo2/Info.java create mode 100644 juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/NodeInfo.java create mode 100644 juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/Server.java create mode 100644 juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/ServiceInfo.java create mode 100644 juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/Usage.java create mode 100644 juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/UserStats.java create mode 100644 juick-server/src/test/resources/xnodeinfo2.json diff --git a/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/Info.java b/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/Info.java new file mode 100644 index 00000000..0c6328c6 --- /dev/null +++ b/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/Info.java @@ -0,0 +1,48 @@ +package com.juick.server.api.xnodeinfo2; + +import com.juick.server.api.xnodeinfo2.model.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.inject.Inject; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Arrays; + +@RestController +public class Info { + @Value("${ap_base_uri:http://localhost:8080/}") + private String baseUri; + @Inject + private JdbcTemplate jdbcTemplate; + + @GetMapping("/.well-known/x-nodeinfo2") + public NodeInfo showNodeInfo() { + NodeInfo nodeInfo = new NodeInfo(); + Server server = new Server(); + server.setBaseUrl(baseUri); + server.setName("Juick"); + server.setSoftware("Juick"); + server.setVersion("2.x"); + nodeInfo.setServer(server); + nodeInfo.setProtocols(Arrays.asList("xmpp", "activitypub", "smtp")); + ServiceInfo serviceInfo = new ServiceInfo(); + serviceInfo.setInbound(Arrays.asList("jabber", "mastodon", "email", "telegram")); + serviceInfo.setOutbound(Arrays.asList("jabber", "mastodon", "telegram", "twitter", "email", "rss")); + nodeInfo.setServices(serviceInfo); + UserStats userStats = new UserStats(); + userStats.setTotal(jdbcTemplate.queryForObject("SELECT COUNT(*) FROM users WHERE banned=0", Integer.class)); + userStats.setActiveMonth(jdbcTemplate.queryForObject("SELECT COUNT(*) FROM users WHERE banned=0 AND last_seen > ?", Integer.class, Instant.now().minus(1, ChronoUnit.MONTHS))); + userStats.setActiveHalfyear(jdbcTemplate.queryForObject("SELECT COUNT(*) FROM users WHERE banned=0 AND last_seen > ?", Integer.class, Instant.now().minus(6, ChronoUnit.MONTHS))); + Usage usage = new Usage(); + usage.setUsers(userStats); + usage.setLocalPosts(jdbcTemplate.queryForObject("SELECT COUNT(*) FROM messages", + Integer.class)); + usage.setLocalComments(jdbcTemplate.queryForObject("SELECT COUNT(*) FROM replies", + Integer.class)); + nodeInfo.setUsage(usage); + return nodeInfo; + } +} diff --git a/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/NodeInfo.java b/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/NodeInfo.java new file mode 100644 index 00000000..06fe354f --- /dev/null +++ b/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/NodeInfo.java @@ -0,0 +1,54 @@ +package com.juick.server.api.xnodeinfo2.model; + +import java.util.List; + +public class NodeInfo { + + private Server server; + + private List protocols; + + private ServiceInfo services; + + public String getVersion() { + return "1.0"; + } + + public Server getServer() { + return server; + } + + public void setServer(Server server) { + this.server = server; + } + + public List getProtocols() { + return protocols; + } + + public void setProtocols(List protocols) { + this.protocols = protocols; + } + + public ServiceInfo getServices() { + return services; + } + + public void setServices(ServiceInfo services) { + this.services = services; + } + + public boolean getOpenRegistrations() { + return true; + } + + private Usage usage; + + public Usage getUsage() { + return usage; + } + + public void setUsage(Usage usage) { + this.usage = usage; + } +} diff --git a/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/Server.java b/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/Server.java new file mode 100644 index 00000000..a772d268 --- /dev/null +++ b/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/Server.java @@ -0,0 +1,40 @@ +package com.juick.server.api.xnodeinfo2.model; + +public class Server { + private String baseUrl; + private String name; + private String software; + private String version; + + public String getBaseUrl() { + return baseUrl; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSoftware() { + return software; + } + + public void setSoftware(String software) { + this.software = software; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} diff --git a/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/ServiceInfo.java b/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/ServiceInfo.java new file mode 100644 index 00000000..5b6d2baa --- /dev/null +++ b/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/ServiceInfo.java @@ -0,0 +1,24 @@ +package com.juick.server.api.xnodeinfo2.model; + +import java.util.List; + +public class ServiceInfo { + private List inbound; + private List outbound; + + public List getInbound() { + return inbound; + } + + public void setInbound(List inbound) { + this.inbound = inbound; + } + + public List getOutbound() { + return outbound; + } + + public void setOutbound(List outbound) { + this.outbound = outbound; + } +} diff --git a/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/Usage.java b/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/Usage.java new file mode 100644 index 00000000..e04ea48b --- /dev/null +++ b/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/Usage.java @@ -0,0 +1,31 @@ +package com.juick.server.api.xnodeinfo2.model; + +public class Usage { + private UserStats users; + private int localPosts; + private int localComments; + + public UserStats getUsers() { + return users; + } + + public void setUsers(UserStats users) { + this.users = users; + } + + public int getLocalPosts() { + return localPosts; + } + + public void setLocalPosts(int localPosts) { + this.localPosts = localPosts; + } + + public int getLocalComments() { + return localComments; + } + + public void setLocalComments(int localComments) { + this.localComments = localComments; + } +} diff --git a/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/UserStats.java b/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/UserStats.java new file mode 100644 index 00000000..515661e3 --- /dev/null +++ b/juick-server/src/main/java/com/juick/server/api/xnodeinfo2/model/UserStats.java @@ -0,0 +1,31 @@ +package com.juick.server.api.xnodeinfo2.model; + +public class UserStats { + private int total; + private int activeHalfyear; + private int activeMonth; + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public int getActiveHalfyear() { + return activeHalfyear; + } + + public void setActiveHalfyear(int activeHalfyear) { + this.activeHalfyear = activeHalfyear; + } + + public int getActiveMonth() { + return activeMonth; + } + + public void setActiveMonth(int activeMonth) { + this.activeMonth = activeMonth; + } +} diff --git a/juick-server/src/main/java/com/juick/server/configuration/SecurityConfig.java b/juick-server/src/main/java/com/juick/server/configuration/SecurityConfig.java index 5aa575ac..f02083d5 100644 --- a/juick-server/src/main/java/com/juick/server/configuration/SecurityConfig.java +++ b/juick-server/src/main/java/com/juick/server/configuration/SecurityConfig.java @@ -97,7 +97,7 @@ public class SecurityConfig { .authorizeRequests() .antMatchers(HttpMethod.OPTIONS).permitAll() .antMatchers("/api/", "/api/messages", "/api/messages/discussions", "/api/users", "/api/thread", "/api/tags", "/api/tlgmbtwbhk", "/api/fbwbhk", - "/api/skypebotendpoint", "/api/_fblogin", "/api/_vklogin", "/api/_tglogin", "/api/inbox", "/api/u/**", "/.well-known/webfinger", "/rss/**", "/api/events").permitAll() + "/api/skypebotendpoint", "/api/_fblogin", "/api/_vklogin", "/api/_tglogin", "/api/inbox", "/api/u/**", "/.well-known/webfinger", "/.well-known/x-nodeinfo2", "/rss/**", "/api/events").permitAll() .anyRequest().hasRole("USER") .and() .anonymous().principal(JuickUser.ANONYMOUS_USER).authorities(JuickUser.ANONYMOUS_AUTHORITY) 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 4161583a..5383536a 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 @@ -40,6 +40,7 @@ import com.juick.server.api.activity.model.activities.Undo; import com.juick.server.api.activity.model.objects.Note; import com.juick.server.api.activity.model.objects.Person; import com.juick.server.api.webfinger.model.Account; +import com.juick.server.api.xnodeinfo2.model.NodeInfo; import com.juick.server.util.HttpUtils; import com.juick.server.util.ImageUtils; import com.juick.server.xmpp.helpers.XMPPStatus; @@ -1728,6 +1729,8 @@ public class ServerTests { String noteStr = IOUtils.toString(new ClassPathResource("mention.json").getURI(), StandardCharsets.UTF_8); Note create2 = jsonMapper.readValue(noteStr, Note.class); jsonMapper.readValue(IOUtils.toString(new ClassPathResource("webfinger.json").getURI(), StandardCharsets.UTF_8), Account.class); + NodeInfo info = jsonMapper.readValue(IOUtils.toString(new ClassPathResource("xnodeinfo2.json").getURI(), StandardCharsets.UTF_8), NodeInfo.class); + assertThat(info.getUsage().getUsers().getActiveHalfyear(), is(42)); } @Test public void activitySerialization() throws Exception { diff --git a/juick-server/src/test/resources/xnodeinfo2.json b/juick-server/src/test/resources/xnodeinfo2.json new file mode 100644 index 00000000..14be6394 --- /dev/null +++ b/juick-server/src/test/resources/xnodeinfo2.json @@ -0,0 +1,24 @@ +{ + "version": "1.0", + "server": { + "baseUrl": "https://example.com", + "name": "Example diaspora* server", + "software": "diaspora", + "version": "0.5.0" + }, + "protocols": ["diaspora", "zot"], + "services": { + "inbound": ["gnusocial"], + "outbound": ["facebook", "twitter"] + }, + "openRegistrations": true, + "usage": { + "users": { + "total": 123, + "activeHalfyear": 42, + "activeMonth": 23 + }, + "localPosts": 500, + "localComments": 1000 + } +} \ No newline at end of file -- cgit v1.2.3