mirror of https://github.com/usbharu/Hideout.git
feat: APIから投稿できるように
This commit is contained in:
parent
8ccf2546b4
commit
42dc455873
|
@ -7,13 +7,13 @@ import dev.usbharu.hideout.config.Config
|
||||||
import dev.usbharu.hideout.config.ConfigData
|
import dev.usbharu.hideout.config.ConfigData
|
||||||
import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob
|
import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob
|
||||||
import dev.usbharu.hideout.plugins.*
|
import dev.usbharu.hideout.plugins.*
|
||||||
import dev.usbharu.hideout.repository.IUserAuthRepository
|
import dev.usbharu.hideout.repository.*
|
||||||
import dev.usbharu.hideout.repository.IUserRepository
|
|
||||||
import dev.usbharu.hideout.repository.UserAuthRepository
|
|
||||||
import dev.usbharu.hideout.repository.UserRepository
|
|
||||||
import dev.usbharu.hideout.routing.register
|
import dev.usbharu.hideout.routing.register
|
||||||
|
import dev.usbharu.hideout.service.IPostService
|
||||||
import dev.usbharu.hideout.service.IUserAuthService
|
import dev.usbharu.hideout.service.IUserAuthService
|
||||||
|
import dev.usbharu.hideout.service.TwitterSnowflakeIdGenerateService
|
||||||
import dev.usbharu.hideout.service.activitypub.*
|
import dev.usbharu.hideout.service.activitypub.*
|
||||||
|
import dev.usbharu.hideout.service.impl.PostService
|
||||||
import dev.usbharu.hideout.service.impl.UserAuthService
|
import dev.usbharu.hideout.service.impl.UserAuthService
|
||||||
import dev.usbharu.hideout.service.impl.UserService
|
import dev.usbharu.hideout.service.impl.UserService
|
||||||
import dev.usbharu.hideout.service.job.JobQueueParentService
|
import dev.usbharu.hideout.service.job.JobQueueParentService
|
||||||
|
@ -81,6 +81,8 @@ fun Application.parent() {
|
||||||
single<UserService> { UserService(get()) }
|
single<UserService> { UserService(get()) }
|
||||||
single<ActivityPubUserService> { ActivityPubUserServiceImpl(get(), get(), get()) }
|
single<ActivityPubUserService> { ActivityPubUserServiceImpl(get(), get(), get()) }
|
||||||
single<ActivityPubNoteService> { ActivityPubNoteServiceImpl(get(), get(), get()) }
|
single<ActivityPubNoteService> { ActivityPubNoteServiceImpl(get(), get(), get()) }
|
||||||
|
single<IPostService> { PostService(get(), get()) }
|
||||||
|
single<IPostRepository> { PostRepositoryImpl(get(), TwitterSnowflakeIdGenerateService) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,7 +96,8 @@ fun Application.parent() {
|
||||||
inject<HttpSignatureVerifyService>().value,
|
inject<HttpSignatureVerifyService>().value,
|
||||||
inject<ActivityPubService>().value,
|
inject<ActivityPubService>().value,
|
||||||
inject<UserService>().value,
|
inject<UserService>().value,
|
||||||
inject<ActivityPubUserService>().value
|
inject<ActivityPubUserService>().value,
|
||||||
|
inject<IPostService>().value
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ object Posts : Table() {
|
||||||
val url = varchar("url", 500)
|
val url = varchar("url", 500)
|
||||||
val repostId = long("repostId").references(id).nullable()
|
val repostId = long("repostId").references(id).nullable()
|
||||||
val replyId = long("replyId").references(id).nullable()
|
val replyId = long("replyId").references(id).nullable()
|
||||||
|
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Post(
|
data class Post(
|
||||||
|
@ -21,7 +22,6 @@ data class Post(
|
||||||
val text: String,
|
val text: String,
|
||||||
val createdAt: Long,
|
val createdAt: Long,
|
||||||
val visibility: Int,
|
val visibility: Int,
|
||||||
val url: String,
|
|
||||||
val repostId: Long? = null,
|
val repostId: Long? = null,
|
||||||
val replyId: Long? = null
|
val replyId: Long? = null
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package dev.usbharu.hideout.domain.model
|
package dev.usbharu.hideout.domain.model
|
||||||
|
|
||||||
import org.jetbrains.exposed.dao.id.LongIdTable
|
import org.jetbrains.exposed.dao.id.LongIdTable
|
||||||
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
|
|
||||||
data class User(
|
data class User(
|
||||||
val name: String,
|
val name: String,
|
||||||
|
@ -47,3 +48,16 @@ object Users : LongIdTable("users") {
|
||||||
uniqueIndex(name, domain)
|
uniqueIndex(name, domain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun ResultRow.toUser(): User {
|
||||||
|
return User(
|
||||||
|
this[Users.name],
|
||||||
|
this[Users.domain],
|
||||||
|
this[Users.screenName],
|
||||||
|
this[Users.description],
|
||||||
|
this[Users.inbox],
|
||||||
|
this[Users.outbox],
|
||||||
|
this[Users.url]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package dev.usbharu.hideout.domain.model.api
|
||||||
|
|
||||||
|
data class StatusForPost(
|
||||||
|
val status:String,
|
||||||
|
val userId:Long
|
||||||
|
)
|
|
@ -3,7 +3,9 @@ package dev.usbharu.hideout.plugins
|
||||||
import dev.usbharu.hideout.routing.activitypub.inbox
|
import dev.usbharu.hideout.routing.activitypub.inbox
|
||||||
import dev.usbharu.hideout.routing.activitypub.outbox
|
import dev.usbharu.hideout.routing.activitypub.outbox
|
||||||
import dev.usbharu.hideout.routing.activitypub.usersAP
|
import dev.usbharu.hideout.routing.activitypub.usersAP
|
||||||
|
import dev.usbharu.hideout.routing.api.v1.statuses
|
||||||
import dev.usbharu.hideout.routing.wellknown.webfinger
|
import dev.usbharu.hideout.routing.wellknown.webfinger
|
||||||
|
import dev.usbharu.hideout.service.IPostService
|
||||||
import dev.usbharu.hideout.service.activitypub.ActivityPubService
|
import dev.usbharu.hideout.service.activitypub.ActivityPubService
|
||||||
import dev.usbharu.hideout.service.activitypub.ActivityPubUserService
|
import dev.usbharu.hideout.service.activitypub.ActivityPubUserService
|
||||||
import dev.usbharu.hideout.service.impl.UserService
|
import dev.usbharu.hideout.service.impl.UserService
|
||||||
|
@ -15,8 +17,9 @@ import io.ktor.server.routing.*
|
||||||
fun Application.configureRouting(
|
fun Application.configureRouting(
|
||||||
httpSignatureVerifyService: HttpSignatureVerifyService,
|
httpSignatureVerifyService: HttpSignatureVerifyService,
|
||||||
activityPubService: ActivityPubService,
|
activityPubService: ActivityPubService,
|
||||||
userService:UserService,
|
userService: UserService,
|
||||||
activityPubUserService: ActivityPubUserService
|
activityPubUserService: ActivityPubUserService,
|
||||||
|
postService: IPostService
|
||||||
) {
|
) {
|
||||||
install(AutoHeadResponse)
|
install(AutoHeadResponse)
|
||||||
routing {
|
routing {
|
||||||
|
@ -24,5 +27,10 @@ fun Application.configureRouting(
|
||||||
outbox()
|
outbox()
|
||||||
usersAP(activityPubUserService)
|
usersAP(activityPubUserService)
|
||||||
webfinger(userService)
|
webfinger(userService)
|
||||||
|
|
||||||
|
route("api/v1") {
|
||||||
|
statuses(postService)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package dev.usbharu.hideout.repository
|
package dev.usbharu.hideout.repository
|
||||||
|
|
||||||
import dev.usbharu.hideout.domain.model.Post
|
import dev.usbharu.hideout.config.Config
|
||||||
import dev.usbharu.hideout.domain.model.PostEntity
|
import dev.usbharu.hideout.domain.model.*
|
||||||
import dev.usbharu.hideout.domain.model.Posts
|
|
||||||
import dev.usbharu.hideout.domain.model.toPost
|
|
||||||
import dev.usbharu.hideout.service.IdGenerateService
|
import dev.usbharu.hideout.service.IdGenerateService
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
|
@ -26,6 +24,8 @@ class PostRepositoryImpl(database: Database, private val idGenerateService: IdGe
|
||||||
return query {
|
return query {
|
||||||
|
|
||||||
val generateId = idGenerateService.generateId()
|
val generateId = idGenerateService.generateId()
|
||||||
|
val name = Users.select { Users.id eq post.userId }.single().toUser().name
|
||||||
|
val postUrl = Config.configData.url + "/users/$name/posts/$generateId"
|
||||||
Posts.insert {
|
Posts.insert {
|
||||||
it[id] = generateId
|
it[id] = generateId
|
||||||
it[userId] = post.userId
|
it[userId] = post.userId
|
||||||
|
@ -33,7 +33,7 @@ class PostRepositoryImpl(database: Database, private val idGenerateService: IdGe
|
||||||
it[text] = post.text
|
it[text] = post.text
|
||||||
it[createdAt] = post.createdAt
|
it[createdAt] = post.createdAt
|
||||||
it[visibility] = post.visibility
|
it[visibility] = post.visibility
|
||||||
it[url] = post.url
|
it[url] = postUrl
|
||||||
it[repostId] = post.repostId
|
it[repostId] = post.repostId
|
||||||
it[replyId] = post.replyId
|
it[replyId] = post.replyId
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ class PostRepositoryImpl(database: Database, private val idGenerateService: IdGe
|
||||||
post.text,
|
post.text,
|
||||||
post.createdAt,
|
post.createdAt,
|
||||||
post.visibility,
|
post.visibility,
|
||||||
post.url,
|
postUrl,
|
||||||
post.repostId,
|
post.repostId,
|
||||||
post.replyId
|
post.replyId
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package dev.usbharu.hideout.routing.api.v1
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.Post
|
||||||
|
import dev.usbharu.hideout.domain.model.api.StatusForPost
|
||||||
|
import dev.usbharu.hideout.service.IPostService
|
||||||
|
import dev.usbharu.hideout.service.impl.PostService
|
||||||
|
import io.ktor.server.application.*
|
||||||
|
import io.ktor.server.request.*
|
||||||
|
import io.ktor.server.response.*
|
||||||
|
import io.ktor.server.routing.*
|
||||||
|
|
||||||
|
fun Route.statuses(postService: IPostService) {
|
||||||
|
route("statuses") {
|
||||||
|
post {
|
||||||
|
val status: StatusForPost = call.receive()
|
||||||
|
val post = Post(
|
||||||
|
userId = status.userId,
|
||||||
|
createdAt = System.currentTimeMillis(),
|
||||||
|
text = status.status,
|
||||||
|
visibility = 1
|
||||||
|
)
|
||||||
|
postService.create(post)
|
||||||
|
call.respond(status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,11 +3,12 @@ package dev.usbharu.hideout.service.impl
|
||||||
import dev.usbharu.hideout.domain.model.Post
|
import dev.usbharu.hideout.domain.model.Post
|
||||||
import dev.usbharu.hideout.repository.IPostRepository
|
import dev.usbharu.hideout.repository.IPostRepository
|
||||||
import dev.usbharu.hideout.service.IPostService
|
import dev.usbharu.hideout.service.IPostService
|
||||||
|
import dev.usbharu.hideout.service.activitypub.ActivityPubNoteService
|
||||||
import dev.usbharu.hideout.service.job.JobQueueParentService
|
import dev.usbharu.hideout.service.job.JobQueueParentService
|
||||||
|
|
||||||
class PostService(private val postRepository:IPostRepository,private val jobQueueParentService: JobQueueParentService) : IPostService {
|
class PostService(private val postRepository:IPostRepository,private val activityPubNoteService: ActivityPubNoteService) : IPostService {
|
||||||
override suspend fun create(post: Post) {
|
override suspend fun create(post: Post) {
|
||||||
postRepository.insert(post)
|
val postEntity = postRepository.insert(post)
|
||||||
|
activityPubNoteService.createNote(postEntity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ class InboxRoutingKtTest {
|
||||||
}
|
}
|
||||||
application {
|
application {
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
configureRouting(mock(), mock(), mock(), mock())
|
configureRouting(mock(), mock(), mock(), mock(),mock())
|
||||||
}
|
}
|
||||||
client.get("/inbox").let {
|
client.get("/inbox").let {
|
||||||
Assertions.assertEquals(HttpStatusCode.MethodNotAllowed, it.status)
|
Assertions.assertEquals(HttpStatusCode.MethodNotAllowed, it.status)
|
||||||
|
@ -50,7 +50,7 @@ class InboxRoutingKtTest {
|
||||||
application {
|
application {
|
||||||
configureStatusPages()
|
configureStatusPages()
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
configureRouting(httpSignatureVerifyService, activityPubService, userService, activityPubUserService)
|
configureRouting(httpSignatureVerifyService, activityPubService, userService, activityPubUserService,mock())
|
||||||
}
|
}
|
||||||
client.post("/inbox").let {
|
client.post("/inbox").let {
|
||||||
Assertions.assertEquals(HttpStatusCode.BadRequest, it.status)
|
Assertions.assertEquals(HttpStatusCode.BadRequest, it.status)
|
||||||
|
@ -64,7 +64,7 @@ class InboxRoutingKtTest {
|
||||||
}
|
}
|
||||||
application {
|
application {
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
configureRouting(mock(), mock(), mock(), mock())
|
configureRouting(mock(), mock(), mock(), mock(),mock())
|
||||||
}
|
}
|
||||||
client.get("/users/test/inbox").let {
|
client.get("/users/test/inbox").let {
|
||||||
Assertions.assertEquals(HttpStatusCode.MethodNotAllowed, it.status)
|
Assertions.assertEquals(HttpStatusCode.MethodNotAllowed, it.status)
|
||||||
|
@ -87,7 +87,7 @@ class InboxRoutingKtTest {
|
||||||
application {
|
application {
|
||||||
configureStatusPages()
|
configureStatusPages()
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
configureRouting(httpSignatureVerifyService, activityPubService, userService, activityPubUserService)
|
configureRouting(httpSignatureVerifyService, activityPubService, userService, activityPubUserService,mock())
|
||||||
}
|
}
|
||||||
client.post("/users/test/inbox").let {
|
client.post("/users/test/inbox").let {
|
||||||
Assertions.assertEquals(HttpStatusCode.BadRequest, it.status)
|
Assertions.assertEquals(HttpStatusCode.BadRequest, it.status)
|
||||||
|
|
|
@ -70,7 +70,7 @@ class UsersAPTest {
|
||||||
|
|
||||||
application {
|
application {
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
configureRouting(httpSignatureVerifyService, activityPubService, userService, activityPubUserService)
|
configureRouting(httpSignatureVerifyService, activityPubService, userService, activityPubUserService,mock())
|
||||||
}
|
}
|
||||||
client.get("/users/test") {
|
client.get("/users/test") {
|
||||||
accept(ContentType.Application.Activity)
|
accept(ContentType.Application.Activity)
|
||||||
|
|
Loading…
Reference in New Issue