diff --git a/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt index aaa2746e..563c628c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt @@ -69,8 +69,10 @@ class SecurityConfig { builder.pattern("/api/v1/apps"), builder.pattern("/api/v1/instance/**"), builder.pattern("/.well-known/**"), - builder.pattern("/error") + builder.pattern("/error"), + builder.pattern("/nodeinfo/2.0") ).permitAll() + it.requestMatchers(builder.pattern("/change-password")).authenticated() it.requestMatchers(builder.pattern("/api/v1/accounts/verify_credentials")) .hasAnyAuthority("SCOPE_read", "SCOPE_read:accounts") it.anyRequest().denyAll() @@ -79,6 +81,7 @@ class SecurityConfig { .oauth2ResourceServer { it.jwt(Customizer.withDefaults()) } + .passwordManagement { } .formLogin(Customizer.withDefaults()) .csrf { it.ignoringRequestMatchers(builder.pattern("/api/**")) diff --git a/src/main/kotlin/dev/usbharu/hideout/controller/wellknown/NodeinfoController.kt b/src/main/kotlin/dev/usbharu/hideout/controller/wellknown/NodeinfoController.kt new file mode 100644 index 00000000..a6630fe7 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/controller/wellknown/NodeinfoController.kt @@ -0,0 +1,64 @@ +package dev.usbharu.hideout.controller.wellknown + +import dev.usbharu.hideout.config.ApplicationConfig +import dev.usbharu.hideout.domain.model.wellknown.Nodeinfo +import dev.usbharu.hideout.domain.model.wellknown.Nodeinfo2_0 +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +class NodeinfoController(private val applicationConfig: ApplicationConfig) { + @GetMapping("/.well-known/nodeinfo") + fun nodeinfo(): ResponseEntity { + return ResponseEntity( + Nodeinfo( + listOf( + Nodeinfo.Links( + "http://nodeinfo.diaspora.software/ns/schema/2.0", + "${applicationConfig.url}/nodeinfo/2.0" + ) + ) + ), HttpStatus.OK + ) + } + + @GetMapping("/nodeinfo/2.0") + fun nodeinfo2_0(): ResponseEntity { + return ResponseEntity( + Nodeinfo2_0( + version = "2.0", + software = Nodeinfo2_0.Software( + name = "hideout", + version = "0.0.1" + ), + protocols = listOf("activitypub"), + services = Nodeinfo2_0.Services( + inbound = emptyList(), + outbound = emptyList() + ), + openRegistrations = false, + usage = Nodeinfo2_0.Usage( + users = Nodeinfo2_0.Usage.Users( + total = 1, + activeHalfYear = 1, + activeMonth = 1 + ), + localPosts = 1, + localComments = 0 + ), + metadata = Nodeinfo2_0.Metadata( + nodeName = "hideout", + nodeDescription = "hideout test server", + maintainer = Nodeinfo2_0.Metadata.Maintainer("usbharu", "i@usbharu.dev"), + langs = emptyList(), + tosUrl = "", + repositoryUrl = "https://github.com/usbharu/Hideout", + feedbackUrl = "https://github.com/usbharu/Hideout/issues/new/choose", + ) + ), + HttpStatus.OK + ) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/wellknown/Nodeinfo.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/wellknown/Nodeinfo.kt new file mode 100644 index 00000000..46adc8b8 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/wellknown/Nodeinfo.kt @@ -0,0 +1,11 @@ +package dev.usbharu.hideout.domain.model.wellknown + + +data class Nodeinfo( + val links: List +) { + data class Links( + val rel: String, + val href: String + ) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/wellknown/Nodeinfo2_0.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/wellknown/Nodeinfo2_0.kt new file mode 100644 index 00000000..fbce0298 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/wellknown/Nodeinfo2_0.kt @@ -0,0 +1,48 @@ +package dev.usbharu.hideout.domain.model.wellknown + +data class Nodeinfo2_0( + val version: String, + val software: Software, + val protocols: List, + val services: Services, + val openRegistrations: Boolean, + val usage: Usage, + val metadata: Metadata +) { + data class Software( + val name: String, + val version: String + ) + + data class Services( + val inbound: List, + val outbound: List + ) + + data class Usage( + val users: Users, + val localPosts: Int, + val localComments: Int + ) { + data class Users( + val total: Int, + val activeHalfYear: Int, + val activeMonth: Int + ) + } + + data class Metadata( + val nodeName: String, + val nodeDescription: String, + val maintainer: Maintainer, + val langs: List, + val tosUrl: String, + val repositoryUrl: String, + val feedbackUrl: String, + ) { + data class Maintainer( + val name: String, + val email: String + ) + } +}