mirror of https://github.com/usbharu/Hideout.git
feat: /users/:idを追加
This commit is contained in:
parent
c48694ab0b
commit
992cc18c62
|
@ -0,0 +1,38 @@
|
||||||
|
package dev.usbharu.hideout.core.application.actor
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||||
|
import java.net.URI
|
||||||
|
|
||||||
|
data class ActorDetail(
|
||||||
|
val id: Long,
|
||||||
|
val name: String,
|
||||||
|
val screenName: String,
|
||||||
|
val host: String,
|
||||||
|
val remoteUrl: String?,
|
||||||
|
val locked: Boolean,
|
||||||
|
val description: String,
|
||||||
|
val postsCount: Int,
|
||||||
|
val iconUrl: URI?,
|
||||||
|
val bannerURL: URI?,
|
||||||
|
val followingCount: Int?,
|
||||||
|
val followersCount: Int?
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun of(actor: Actor, iconUrl: URI?, bannerURL: URI?): ActorDetail {
|
||||||
|
return ActorDetail(
|
||||||
|
id = actor.id.id,
|
||||||
|
name = actor.name.name,
|
||||||
|
screenName = actor.screenName.screenName,
|
||||||
|
host = actor.url.host,
|
||||||
|
remoteUrl = actor.url.toString(),
|
||||||
|
locked = actor.locked,
|
||||||
|
description = actor.description.description,
|
||||||
|
postsCount = actor.postsCount.postsCount,
|
||||||
|
iconUrl = iconUrl,
|
||||||
|
bannerURL = bannerURL,
|
||||||
|
followingCount = actor.followingCount?.relationshipCount,
|
||||||
|
followersCount = actor.followersCount?.relationshipCount
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package dev.usbharu.hideout.core.application.actor
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.support.acct.Acct
|
||||||
|
|
||||||
|
data class GetActorDetail(
|
||||||
|
val actorName: Acct? = null,
|
||||||
|
val id: Long? = null
|
||||||
|
)
|
|
@ -0,0 +1,49 @@
|
||||||
|
package dev.usbharu.hideout.core.application.actor
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||||
|
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||||
|
import dev.usbharu.hideout.core.config.ApplicationConfig
|
||||||
|
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||||
|
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||||
|
import dev.usbharu.hideout.core.domain.model.media.MediaRepository
|
||||||
|
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class GetActorDetailApplicationService(
|
||||||
|
private val actorRepository: ActorRepository,
|
||||||
|
private val mediaRepository: MediaRepository,
|
||||||
|
private val applicationConfig: ApplicationConfig,
|
||||||
|
transaction: Transaction
|
||||||
|
) :
|
||||||
|
AbstractApplicationService<GetActorDetail, ActorDetail>(
|
||||||
|
transaction, logger
|
||||||
|
) {
|
||||||
|
override suspend fun internalExecute(command: GetActorDetail, principal: Principal): ActorDetail {
|
||||||
|
val actor = if (command.id != null) {
|
||||||
|
actorRepository.findById(ActorId(command.id))
|
||||||
|
?: throw IllegalArgumentException("Actor ${command.id} not found.")
|
||||||
|
} else if (command.actorName != null) {
|
||||||
|
|
||||||
|
val host = if (command.actorName.host.isEmpty()) {
|
||||||
|
applicationConfig.url.host
|
||||||
|
} else {
|
||||||
|
command.actorName.host
|
||||||
|
}
|
||||||
|
actorRepository.findByNameAndDomain(command.actorName.userpart, host)
|
||||||
|
?: throw IllegalArgumentException("Actor ${command.actorName} not found.")
|
||||||
|
} else {
|
||||||
|
throw IllegalArgumentException("id and actorName are null.")
|
||||||
|
}
|
||||||
|
|
||||||
|
val iconUrl = actor.icon?.let { mediaRepository.findById(it)?.url }
|
||||||
|
val bannerUrl = actor.banner?.let { mediaRepository.findById(it)?.url }
|
||||||
|
|
||||||
|
return ActorDetail.of(actor, iconUrl, bannerUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val logger = LoggerFactory.getLogger(GetActorDetailApplicationService::class.java)
|
||||||
|
}
|
||||||
|
}
|
|
@ -87,6 +87,7 @@ class SecurityConfig {
|
||||||
authorize(GET, "/auth/sign_up", hasRole("ANONYMOUS"))
|
authorize(GET, "/auth/sign_up", hasRole("ANONYMOUS"))
|
||||||
authorize(POST, "/auth/sign_up", permitAll)
|
authorize(POST, "/auth/sign_up", permitAll)
|
||||||
authorize(GET, "/users/{username}/posts/{postId}", permitAll)
|
authorize(GET, "/users/{username}/posts/{postId}", permitAll)
|
||||||
|
authorize(GET, "/users/{userid}", permitAll)
|
||||||
authorize(GET, "/files/*", permitAll)
|
authorize(GET, "/files/*", permitAll)
|
||||||
authorize(POST, "/publish", authenticated)
|
authorize(POST, "/publish", authenticated)
|
||||||
authorize(GET, "/publish", authenticated)
|
authorize(GET, "/publish", authenticated)
|
||||||
|
|
|
@ -5,4 +5,14 @@ data class Acct(
|
||||||
val host: String
|
val host: String
|
||||||
) {
|
) {
|
||||||
override fun toString(): String = "acct:$userpart@$host"
|
override fun toString(): String = "acct:$userpart@$host"
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun of(acct: String): Acct {
|
||||||
|
return Acct(
|
||||||
|
acct.substringBeforeLast('@'),
|
||||||
|
acct.substringAfterLast('@', "")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package dev.usbharu.hideout.core.interfaces.web.user
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.application.actor.GetActorDetail
|
||||||
|
import dev.usbharu.hideout.core.application.actor.GetActorDetailApplicationService
|
||||||
|
import dev.usbharu.hideout.core.application.instance.GetLocalInstanceApplicationService
|
||||||
|
import dev.usbharu.hideout.core.domain.model.support.acct.Acct
|
||||||
|
import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous
|
||||||
|
import dev.usbharu.hideout.core.infrastructure.springframework.SpringSecurityFormLoginPrincipalContextHolder
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.ui.Model
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
class UserController(
|
||||||
|
private val getLocalInstanceApplicationService: GetLocalInstanceApplicationService,
|
||||||
|
private val getUserDetailApplicationService: GetActorDetailApplicationService,
|
||||||
|
private val springSecurityFormLoginPrincipalContextHolder: SpringSecurityFormLoginPrincipalContextHolder,
|
||||||
|
) {
|
||||||
|
@GetMapping("/users/{name}")
|
||||||
|
suspend fun userById(@PathVariable name: String, model: Model): String {
|
||||||
|
val principal = springSecurityFormLoginPrincipalContextHolder.getPrincipal()
|
||||||
|
|
||||||
|
model.addAttribute("instance", getLocalInstanceApplicationService.execute(Unit, Anonymous))
|
||||||
|
model.addAttribute(
|
||||||
|
"user",
|
||||||
|
getUserDetailApplicationService.execute(GetActorDetail(Acct.of(name)), principal)
|
||||||
|
)
|
||||||
|
return "userById"
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,3 +22,4 @@ post-form.new-posts-form-label=\u4ECA\u306A\u306B\u3057\u3066\u308B?
|
||||||
post-form.new-posts-submit=\u6295\u7A3F\u3059\u308B
|
post-form.new-posts-submit=\u6295\u7A3F\u3059\u308B
|
||||||
post.repost=\u30EA\u30DD\u30B9\u30C8
|
post.repost=\u30EA\u30DD\u30B9\u30C8
|
||||||
post.repost-by={0}\u304C\u30EA\u30DD\u30B9\u30C8
|
post.repost-by={0}\u304C\u30EA\u30DD\u30B9\u30C8
|
||||||
|
user-by-id.title={0} \u3055\u3093 - {1}
|
|
@ -22,3 +22,4 @@ post-form.new-posts-form-label=\u4ECA\u306A\u306B\u3057\u3066\u308B?
|
||||||
post-form.new-posts-submit=\u6295\u7A3F\u3059\u308B
|
post-form.new-posts-submit=\u6295\u7A3F\u3059\u308B
|
||||||
post.repost=\u30EA\u30DD\u30B9\u30C8
|
post.repost=\u30EA\u30DD\u30B9\u30C8
|
||||||
post.repost-by={0}\u304C\u30EA\u30DD\u30B9\u30C8
|
post.repost-by={0}\u304C\u30EA\u30DD\u30B9\u30C8
|
||||||
|
user-by-id.title={0} \u3055\u3093 - {1}
|
|
@ -0,0 +1,14 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title th:text="#{user-by-id.title(${user.screenName},${instance.name})}">User - hideout</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<div>
|
||||||
|
<img th:src="user.icon">
|
||||||
|
</div>
|
||||||
|
</noscript>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue