mirror of https://github.com/usbharu/Hideout.git
feat: 新規ユーザー作成時にInstanceを取得するように
This commit is contained in:
parent
bb87cab45f
commit
4837192139
|
@ -1,17 +1,64 @@
|
||||||
package dev.usbharu.hideout.core.service.instance
|
package dev.usbharu.hideout.core.service.instance
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
|
import dev.usbharu.hideout.activitypub.domain.model.nodeinfo.Nodeinfo
|
||||||
|
import dev.usbharu.hideout.activitypub.domain.model.nodeinfo.Nodeinfo2_0
|
||||||
import dev.usbharu.hideout.core.domain.model.instance.Instance
|
import dev.usbharu.hideout.core.domain.model.instance.Instance
|
||||||
import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository
|
import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository
|
||||||
|
import dev.usbharu.hideout.core.service.resource.ResourceResolveService
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
|
import java.net.URL
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
interface InstanceService {
|
interface InstanceService {
|
||||||
|
suspend fun fetchInstance(url: String): Instance
|
||||||
suspend fun createNewInstance(instanceCreateDto: InstanceCreateDto): Instance
|
suspend fun createNewInstance(instanceCreateDto: InstanceCreateDto): Instance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class InstanceServiceImpl(private val instanceRepository: InstanceRepository) : InstanceService {
|
class InstanceServiceImpl(
|
||||||
|
private val instanceRepository: InstanceRepository,
|
||||||
|
private val resourceResolveService: ResourceResolveService,
|
||||||
|
private val objectMapper: ObjectMapper
|
||||||
|
) : InstanceService {
|
||||||
|
override suspend fun fetchInstance(url: String): Instance {
|
||||||
|
val u = URL(url)
|
||||||
|
val resolveInstanceUrl = u.protocol + "://" + u.host
|
||||||
|
val nodeinfoJson = resourceResolveService.resolve("$resolveInstanceUrl/.well-known/nodeinfo").bodyAsText()
|
||||||
|
val nodeinfo = objectMapper.readValue(nodeinfoJson, Nodeinfo::class.java)
|
||||||
|
val nodeinfoPathMap = nodeinfo.links.map { it.rel to it.href }.toMap()
|
||||||
|
|
||||||
|
|
||||||
|
for ((key, value) in nodeinfoPathMap) {
|
||||||
|
when (key) {
|
||||||
|
"http://nodeinfo.diaspora.software/ns/schema/2.0" -> {
|
||||||
|
val nodeinfo20 = objectMapper.readValue(
|
||||||
|
resourceResolveService.resolve(value).bodyAsText(),
|
||||||
|
Nodeinfo2_0::class.java
|
||||||
|
)
|
||||||
|
|
||||||
|
val instanceCreateDto = InstanceCreateDto(
|
||||||
|
nodeinfo20.metadata.nodeName,
|
||||||
|
nodeinfo20.metadata.nodeDescription,
|
||||||
|
resolveInstanceUrl,
|
||||||
|
resolveInstanceUrl + "/favicon.ico",
|
||||||
|
null,
|
||||||
|
nodeinfo20.software.name,
|
||||||
|
nodeinfo20.software.version
|
||||||
|
)
|
||||||
|
return createNewInstance(instanceCreateDto)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw IllegalStateException("Nodeinfo aren't found.")
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun createNewInstance(instanceCreateDto: InstanceCreateDto): Instance {
|
override suspend fun createNewInstance(instanceCreateDto: InstanceCreateDto): Instance {
|
||||||
val instance = Instance(
|
val instance = Instance(
|
||||||
instanceRepository.generateId(),
|
instanceRepository.generateId(),
|
||||||
|
|
|
@ -7,7 +7,24 @@ import java.io.InputStream
|
||||||
|
|
||||||
class KtorResolveResponse(val ktorHttpResponse: HttpResponse) : ResolveResponse {
|
class KtorResolveResponse(val ktorHttpResponse: HttpResponse) : ResolveResponse {
|
||||||
|
|
||||||
|
private lateinit var _bodyAsText: String
|
||||||
|
private lateinit var _bodyAsBytes: ByteArray
|
||||||
|
|
||||||
override suspend fun body(): InputStream = ktorHttpResponse.bodyAsChannel().toInputStream()
|
override suspend fun body(): InputStream = ktorHttpResponse.bodyAsChannel().toInputStream()
|
||||||
|
override suspend fun bodyAsText(): String {
|
||||||
|
if (!this::_bodyAsText.isInitialized) {
|
||||||
|
_bodyAsText = ktorHttpResponse.bodyAsText()
|
||||||
|
}
|
||||||
|
return _bodyAsText
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun bodyAsBytes(): ByteArray {
|
||||||
|
if (!this::_bodyAsBytes.isInitialized) {
|
||||||
|
_bodyAsBytes = ktorHttpResponse.readBytes()
|
||||||
|
}
|
||||||
|
return _bodyAsBytes
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun header(): Map<String, List<String>> = ktorHttpResponse.headers.toMap()
|
override suspend fun header(): Map<String, List<String>> = ktorHttpResponse.headers.toMap()
|
||||||
override suspend fun status(): Int = ktorHttpResponse.status.value
|
override suspend fun status(): Int = ktorHttpResponse.status.value
|
||||||
override suspend fun statusMessage(): String = ktorHttpResponse.status.description
|
override suspend fun statusMessage(): String = ktorHttpResponse.status.description
|
||||||
|
|
|
@ -4,6 +4,8 @@ import java.io.InputStream
|
||||||
|
|
||||||
interface ResolveResponse {
|
interface ResolveResponse {
|
||||||
suspend fun body(): InputStream
|
suspend fun body(): InputStream
|
||||||
|
suspend fun bodyAsText(): String
|
||||||
|
suspend fun bodyAsBytes(): ByteArray
|
||||||
suspend fun header(): Map<String, List<String>>
|
suspend fun header(): Map<String, List<String>>
|
||||||
suspend fun status(): Int
|
suspend fun status(): Int
|
||||||
suspend fun statusMessage(): String
|
suspend fun statusMessage(): String
|
||||||
|
|
|
@ -8,6 +8,7 @@ import dev.usbharu.hideout.core.domain.model.user.UserRepository
|
||||||
import dev.usbharu.hideout.core.query.FollowerQueryService
|
import dev.usbharu.hideout.core.query.FollowerQueryService
|
||||||
import dev.usbharu.hideout.core.query.UserQueryService
|
import dev.usbharu.hideout.core.query.UserQueryService
|
||||||
import dev.usbharu.hideout.core.service.follow.SendFollowDto
|
import dev.usbharu.hideout.core.service.follow.SendFollowDto
|
||||||
|
import dev.usbharu.hideout.core.service.instance.InstanceService
|
||||||
import org.jetbrains.exposed.exceptions.ExposedSQLException
|
import org.jetbrains.exposed.exceptions.ExposedSQLException
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
@ -20,7 +21,8 @@ class UserServiceImpl(
|
||||||
private val userQueryService: UserQueryService,
|
private val userQueryService: UserQueryService,
|
||||||
private val followerQueryService: FollowerQueryService,
|
private val followerQueryService: FollowerQueryService,
|
||||||
private val userBuilder: User.UserBuilder,
|
private val userBuilder: User.UserBuilder,
|
||||||
private val applicationConfig: ApplicationConfig
|
private val applicationConfig: ApplicationConfig,
|
||||||
|
private val instanceService: InstanceService
|
||||||
) :
|
) :
|
||||||
UserService {
|
UserService {
|
||||||
|
|
||||||
|
@ -55,6 +57,8 @@ class UserServiceImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun createRemoteUser(user: RemoteUserCreateDto): User {
|
override suspend fun createRemoteUser(user: RemoteUserCreateDto): User {
|
||||||
|
instanceService.fetchInstance(user.url)
|
||||||
|
|
||||||
val nextId = userRepository.nextId()
|
val nextId = userRepository.nextId()
|
||||||
val userEntity = userBuilder.of(
|
val userEntity = userBuilder.of(
|
||||||
id = nextId,
|
id = nextId,
|
||||||
|
|
Loading…
Reference in New Issue