refactor: 一部の命名を変更。ユーザーを作成できるように

This commit is contained in:
usbharu 2023-04-28 15:04:59 +09:00
parent f77d151234
commit 48411751de
Signed by: usbharu
GPG Key ID: 6556747BF94EEBC8
12 changed files with 82 additions and 57 deletions

View File

@ -79,7 +79,7 @@ fun Application.parent() {
}
single<ActivityPubFollowService> { ActivityPubFollowServiceImpl(get(), get(), get(), get()) }
single<ActivityPubService> { ActivityPubServiceImpl(get(), get()) }
single<UserService> { UserService(get()) }
single<UserService> { UserService(get(),get()) }
single<ActivityPubUserService> { ActivityPubUserServiceImpl(get(), get(), get()) }
single<ActivityPubNoteService> { ActivityPubNoteServiceImpl(get(), get(), get()) }
single<IPostService> { PostService(get(), get()) }
@ -93,7 +93,7 @@ fun Application.parent() {
configureStaticRouting()
configureMonitoring()
configureSerialization()
register(inject<IUserAuthService>().value)
register(inject<UserService>().value)
configureRouting(
inject<HttpSignatureVerifyService>().value,
inject<ActivityPubService>().value,

View File

@ -2,7 +2,6 @@ package dev.usbharu.hideout.domain.model.hideout.dto
data class UserCreateDto(
val name:String,
val domain:String,
val screenName:String,
val description:String,
val password:String

View File

@ -149,8 +149,8 @@ class KtorKeyMap(private val userAuthRepository: IUserRepository) : KeyMap {
val username = (keyId ?: throw IllegalArgumentException("keyId is null")).substringBeforeLast("#pubkey")
.substringAfterLast("/")
val publicBytes = Base64.getDecoder().decode(
userAuthRepository.findByName(
username
userAuthRepository.findByNameAndDomain(
username,Config.configData.domain
)?.publicKey?.replace("-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----")?.replace("", "")
?.replace("\n", "")
)
@ -162,8 +162,8 @@ class KtorKeyMap(private val userAuthRepository: IUserRepository) : KeyMap {
val username = (keyId ?: throw IllegalArgumentException("keyId is null")).substringBeforeLast("#pubkey")
.substringAfterLast("/")
val publicBytes = Base64.getDecoder().decode(
userAuthRepository.findByName(
username
userAuthRepository.findByNameAndDomain(
username,Config.configData.domain
)?.privateKey?.replace("-----BEGIN PRIVATE KEY-----", "")?.replace("-----END PRIVATE KEY-----", "")
?.replace("\n", "")
)

View File

@ -9,7 +9,11 @@ interface IUserRepository {
suspend fun findByIds(ids: List<Long>): List<User>
suspend fun findByName(name: String): User?
suspend fun findByName(name: String): List<User>
suspend fun findByNameAndDomain(name: String, domain: String): User?
suspend fun findByDomain(domain:String): List<User>
suspend fun findByNameAndDomains(names: List<Pair<String,String>>): List<User>

View File

@ -10,7 +10,8 @@ import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransacti
import org.jetbrains.exposed.sql.transactions.transaction
import java.time.Instant
class UserRepository(private val database: Database,private val idGenerateService: IdGenerateService) : IUserRepository {
class UserRepository(private val database: Database, private val idGenerateService: IdGenerateService) :
IUserRepository {
init {
transaction(database) {
SchemaUtils.create(Users)
@ -85,11 +86,25 @@ class UserRepository(private val database: Database,private val idGenerateServic
}
}
override suspend fun findByName(name: String): User? {
override suspend fun findByName(name: String): List<User> {
return query {
Users.select { Users.name eq name }.map {
it.toUser()
}.singleOrNull()
}
}
}
override suspend fun findByNameAndDomain(name: String, domain: String): User? {
return query {
Users.select { Users.name eq name and (Users.domain eq domain) }.singleOrNull()?.toUser()
}
}
override suspend fun findByDomain(domain: String): List<User> {
return query {
Users.select { Users.domain eq domain }.map {
it.toUser()
}
}
}

View File

@ -1,16 +1,15 @@
package dev.usbharu.hideout.routing
import dev.usbharu.hideout.plugins.UserSession
import dev.usbharu.hideout.service.IUserAuthService
import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto
import dev.usbharu.hideout.service.impl.UserService
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.sessions.*
fun Application.register(userAuthService: IUserAuthService) {
fun Application.register(userService: UserService) {
routing {
get("/register") {
@ -39,13 +38,10 @@ fun Application.register(userAuthService: IUserAuthService) {
val parameters = call.receiveParameters()
val password = parameters["password"] ?: return@post call.respondRedirect("/register")
val username = parameters["username"] ?: return@post call.respondRedirect("/register")
if (userAuthService.usernameAlreadyUse(username)) {
if (userService.usernameAlreadyUse(username)) {
return@post call.respondRedirect("/register")
}
val hash = userAuthService.hash(password)
userAuthService.registerAccount(username,hash)
// call.respondRedirect("/login")
userService.createLocalUser(UserCreateDto(username, username, "", password))
call.respondRedirect("/users/$username")
}
}

View File

@ -1,5 +1,6 @@
package dev.usbharu.hideout.routing.activitypub
import dev.usbharu.hideout.config.Config
import dev.usbharu.hideout.exception.ParameterNotExistException
import dev.usbharu.hideout.plugins.respondAp
import dev.usbharu.hideout.service.activitypub.ActivityPubUserService
@ -24,7 +25,7 @@ fun Routing.usersAP(activityPubUserService: ActivityPubUserService, userService:
)
}
get {
val userEntity = userService.findByName(call.parameters["name"]!!)
val userEntity = userService.findByNameLocalUser(call.parameters["name"]!!)
call.respondText(userEntity.toString() + "\n" + userService.findFollowersById(userEntity.id))
}
}

View File

@ -25,7 +25,7 @@ fun Routing.webfinger(userService:UserService){
.substringAfter("acct:")
.trimStart('@')
val userEntity = userService.findByName(accountName)
val userEntity = userService.findByNameLocalUser(accountName)
val webFinger = WebFinger(
subject = acct,

View File

@ -1,10 +1,13 @@
package dev.usbharu.hideout.service
import java.security.KeyPair
interface IUserAuthService {
fun hash(password: String): String
suspend fun usernameAlreadyUse(username: String): Boolean
suspend fun registerAccount(username: String, hash: String)
suspend fun generateKeyPair():KeyPair
suspend fun verifyAccount(username: String, password: String): Boolean

View File

@ -28,7 +28,7 @@ class ActivityPubUserServiceImpl(
private val logger = LoggerFactory.getLogger(this::class.java)
override suspend fun getPersonByName(name: String): Person {
// TODO: JOINで書き直し
val userEntity = userService.findByName(name)
val userEntity = userService.findByNameLocalUser(name)
val userUrl = "${Config.configData.url}/users/$name"
return Person(
type = emptyList(),

View File

@ -1,15 +1,11 @@
package dev.usbharu.hideout.service.impl
import dev.usbharu.hideout.config.Config
import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.exception.UserNotFoundException
import dev.usbharu.hideout.repository.IUserRepository
import dev.usbharu.hideout.service.IUserAuthService
import io.ktor.util.*
import java.security.*
import java.security.interfaces.RSAPrivateKey
import java.security.interfaces.RSAPublicKey
import java.time.Instant
import java.util.*
class UserAuthService(
@ -27,37 +23,13 @@ class UserAuthService(
return true
}
@Deprecated("")
override suspend fun registerAccount(username: String, hash: String) {
val url = "${Config.configData.url}/users/$username"
val registerUser = User(
id = 0L,
name = username,
domain = Config.configData.domain,
screenName = username,
description = "",
inbox = "$url/inbox",
outbox = "$url/outbox",
url = url,
publicKey = "",
createdAt = Instant.now(),
)
val createdUser = userRepository.save(registerUser)
val keyPair = generateKeyPair()
val privateKey = keyPair.private as RSAPrivateKey
val publicKey = keyPair.public as RSAPublicKey
TODO()
}
override suspend fun verifyAccount(username: String, password: String): Boolean {
val userEntity = userRepository.findByName(username)
val userEntity = userRepository.findByNameAndDomain(username, Config.configData.domain)
?: throw UserNotFoundException("$username was not found")
return userEntity.password == hash(password)
}
private fun generateKeyPair(): KeyPair {
override suspend fun generateKeyPair(): KeyPair {
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(1024)
return keyPairGenerator.generateKeyPair()

View File

@ -1,11 +1,15 @@
package dev.usbharu.hideout.service.impl
import dev.usbharu.hideout.config.Config
import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto
import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.exception.UserNotFoundException
import dev.usbharu.hideout.repository.IUserRepository
import dev.usbharu.hideout.service.IUserAuthService
import java.lang.Integer.min
import java.time.Instant
class UserService(private val userRepository: IUserRepository) {
class UserService(private val userRepository: IUserRepository, private val userAuthService: IUserAuthService) {
private val maxLimit = 100
suspend fun findAll(limit: Int? = maxLimit, offset: Long? = 0): List<User> {
@ -24,12 +28,16 @@ class UserService(private val userRepository: IUserRepository) {
return userRepository.findByIds(ids)
}
suspend fun findByName(name: String): User {
suspend fun findByName(name: String): List<User> {
return userRepository.findByName(name)
}
suspend fun findByNameLocalUser(name: String): User {
return userRepository.findByNameAndDomain(name, Config.configData.domain)
?: throw UserNotFoundException("$name was not found.")
}
suspend fun findByNameAndDomains(names: List<Pair<String,String>>): List<User> {
suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> {
return userRepository.findByNameAndDomains(names)
}
@ -41,10 +49,37 @@ class UserService(private val userRepository: IUserRepository) {
return userRepository.findByUrls(urls)
}
suspend fun usernameAlreadyUse(username: String): Boolean {
val findByNameAndDomain = userRepository.findByNameAndDomain(username, Config.configData.domain)
return findByNameAndDomain != null
}
@Deprecated("")
suspend fun create(user: User): User {
return userRepository.save(user)
}
suspend fun createLocalUser(user: UserCreateDto): User {
val nextId = userRepository.nextId()
val HashedPassword = userAuthService.hash(user.password)
val keyPair = userAuthService.generateKeyPair()
val userEntity = User(
id = nextId,
name = user.name,
domain = Config.configData.domain,
screenName = user.screenName,
description = user.description,
password = HashedPassword,
inbox = "${Config.configData.url}/users/$nextId/inbox",
outbox = "${Config.configData.url}/users/$nextId/outbox",
url = "${Config.configData.url}/users/$nextId",
publicKey = keyPair.public.toPem(),
privateKey = keyPair.private.toString(),
Instant.now()
)
return userRepository.save(userEntity)
}
suspend fun findFollowersById(id: Long): List<User> {
return userRepository.findFollowersById(id)
}