feat: usersのAPIを追加

This commit is contained in:
usbharu 2023-05-18 15:11:07 +09:00
parent 9de04f944f
commit cd8e8d530b
Signed by: usbharu
GPG Key ID: 6556747BF94EEBC8
5 changed files with 153 additions and 2 deletions

View File

@ -0,0 +1,3 @@
package dev.usbharu.hideout.domain.model.hideout.form
data class UserCreate(val username: String, val password: String)

View File

@ -0,0 +1,89 @@
package dev.usbharu.hideout.routing.api.internal.v1
import dev.usbharu.hideout.config.Config
import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto
import dev.usbharu.hideout.domain.model.hideout.form.UserCreate
import dev.usbharu.hideout.exception.ParameterNotExistException
import dev.usbharu.hideout.plugins.TOKEN_AUTH
import dev.usbharu.hideout.service.impl.IUserService
import dev.usbharu.hideout.util.AcctUtil
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.auth.jwt.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
fun Route.users(userService: IUserService) {
route("/users") {
get {
call.respond(userService.findAll())
}
post {
val userCreate = call.receive<UserCreate>()
if (userService.usernameAlreadyUse(userCreate.username)) {
return@post call.respond(HttpStatusCode.BadRequest)
}
val user = userService.createLocalUser(
UserCreateDto(
userCreate.username,
userCreate.username,
"",
userCreate.password
)
)
call.response.header("Location", "${Config.configData.url}/api/internal/v1/users/${user.name}")
call.respond(HttpStatusCode.OK)
}
route("/{name}") {
route("/followers") {
get {
val userParameter = call.parameters["name"]
?: throw ParameterNotExistException("Parameter(name='userName@domain') does not exist.")
if (userParameter.toLongOrNull() != null) {
return@get call.respond(userService.findFollowersById(userParameter.toLong()))
}
val acct = AcctUtil.parse(userParameter)
return@get call.respond(userService.findFollowersByNameAndDomain(acct.username, acct.domain))
}
authenticate(TOKEN_AUTH) {
post {
val userId = call.principal<JWTPrincipal>()?.payload?.getClaim("uid")?.asLong()
?: throw IllegalStateException("no principal")
val userParameter = call.parameters["name"]
?: throw ParameterNotExistException("Parameter(name='userName@domain') does not exist.")
if (userParameter.toLongOrNull() != null) {
if (userService.addFollowers(userParameter.toLong(), userId)) {
return@post call.respond(HttpStatusCode.OK)
} else {
return@post call.respond(HttpStatusCode.Accepted)
}
}
val acct = AcctUtil.parse(userParameter)
val targetUser = userService.findByNameAndDomain(acct.username, acct.domain)
if (userService.addFollowers(targetUser.id, userId)) {
return@post call.respond(HttpStatusCode.OK)
} else {
return@post call.respond(HttpStatusCode.Accepted)
}
}
}
}
route("/following") {
get {
val userParameter = (call.parameters["name"]
?: throw ParameterNotExistException("Parameter(name='userName@domain') does not exist."))
if (userParameter.toLongOrNull() != null) {
return@get call.respond(userService.findFollowingById(userParameter.toLong()))
}
val acct = AcctUtil.parse(userParameter)
return@get call.respond(userService.findFollowingByNameAndDomain(acct.username, acct.domain))
}
}
}
}
}

View File

@ -16,6 +16,8 @@ interface IUserService {
suspend fun findByNameLocalUser(name: String): User
suspend fun findByNameAndDomain(name: String, domain: String? = null): User
suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User>
suspend fun findByUrl(url: String): User
@ -30,5 +32,18 @@ interface IUserService {
suspend fun findFollowersById(id: Long): List<User>
suspend fun addFollowers(id: Long, follower: Long)
suspend fun findFollowersByNameAndDomain(name: String, domain: String?): List<User>
suspend fun findFollowingById(id: Long): List<User>
suspend fun findFollowingByNameAndDomain(name: String, domain: String?): List<User>
/**
* フォロワーを追加する
*
* @param id
* @param follower
* @return リクエストが成功したか
*/
suspend fun addFollowers(id: Long, follower: Long): Boolean
}

View File

@ -92,6 +92,31 @@ class PostService(
}
}
override suspend fun findByUserIdForUser(
userId: Long,
since: Instant?,
until: Instant?,
minId: Long?,
maxId: Long?,
limit: Int?,
forUserId: Long?
): List<Post> {
TODO("Not yet implemented")
}
override suspend fun findByUserNameAndDomainForUser(
userName: String,
domain: String,
since: Instant?,
until: Instant?,
minId: Long?,
maxId: Long?,
limit: Int?,
forUserId: Long?
): List<Post> {
TODO("Not yet implemented")
}
override suspend fun delete(id: String) {
TODO("Not yet implemented")
}

View File

@ -35,6 +35,10 @@ class UserService(private val userRepository: IUserRepository, private val userA
?: throw UserNotFoundException("$name was not found.")
}
override suspend fun findByNameAndDomain(name: String, domain: String?): User {
TODO("Not yet implemented")
}
override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> =
userRepository.findByNameAndDomains(names)
@ -87,6 +91,21 @@ class UserService(private val userRepository: IUserRepository, private val userA
}
override suspend fun findFollowersById(id: Long): List<User> = userRepository.findFollowersById(id)
override suspend fun findFollowersByNameAndDomain(name: String, domain: String?): List<User> {
TODO("Not yet implemented")
}
override suspend fun addFollowers(id: Long, follower: Long) = userRepository.createFollower(id, follower)
override suspend fun findFollowingById(id: Long): List<User> {
TODO("Not yet implemented")
}
override suspend fun findFollowingByNameAndDomain(name: String, domain: String?): List<User> {
TODO("Not yet implemented")
}
//TODO APのフォロー処理を作る
override suspend fun addFollowers(id: Long, follower: Long): Boolean {
userRepository.createFollower(id, follower)
return false
}
}