mirror of https://github.com/usbharu/Hideout.git
refactor: 一部の命名を変更。ユーザーを作成できるように
This commit is contained in:
parent
d369c68d94
commit
e0aee75930
|
@ -79,7 +79,7 @@ fun Application.parent() {
|
||||||
}
|
}
|
||||||
single<ActivityPubFollowService> { ActivityPubFollowServiceImpl(get(), get(), get(), get()) }
|
single<ActivityPubFollowService> { ActivityPubFollowServiceImpl(get(), get(), get(), get()) }
|
||||||
single<ActivityPubService> { ActivityPubServiceImpl(get(), get()) }
|
single<ActivityPubService> { ActivityPubServiceImpl(get(), get()) }
|
||||||
single<UserService> { UserService(get()) }
|
single<UserService> { UserService(get(),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<IPostService> { PostService(get(), get()) }
|
||||||
|
@ -93,7 +93,7 @@ fun Application.parent() {
|
||||||
configureStaticRouting()
|
configureStaticRouting()
|
||||||
configureMonitoring()
|
configureMonitoring()
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
register(inject<IUserAuthService>().value)
|
register(inject<UserService>().value)
|
||||||
configureRouting(
|
configureRouting(
|
||||||
inject<HttpSignatureVerifyService>().value,
|
inject<HttpSignatureVerifyService>().value,
|
||||||
inject<ActivityPubService>().value,
|
inject<ActivityPubService>().value,
|
||||||
|
|
|
@ -2,7 +2,6 @@ package dev.usbharu.hideout.domain.model.hideout.dto
|
||||||
|
|
||||||
data class UserCreateDto(
|
data class UserCreateDto(
|
||||||
val name:String,
|
val name:String,
|
||||||
val domain:String,
|
|
||||||
val screenName:String,
|
val screenName:String,
|
||||||
val description:String,
|
val description:String,
|
||||||
val password:String
|
val password:String
|
||||||
|
|
|
@ -149,8 +149,8 @@ class KtorKeyMap(private val userAuthRepository: IUserRepository) : KeyMap {
|
||||||
val username = (keyId ?: throw IllegalArgumentException("keyId is null")).substringBeforeLast("#pubkey")
|
val username = (keyId ?: throw IllegalArgumentException("keyId is null")).substringBeforeLast("#pubkey")
|
||||||
.substringAfterLast("/")
|
.substringAfterLast("/")
|
||||||
val publicBytes = Base64.getDecoder().decode(
|
val publicBytes = Base64.getDecoder().decode(
|
||||||
userAuthRepository.findByName(
|
userAuthRepository.findByNameAndDomain(
|
||||||
username
|
username,Config.configData.domain
|
||||||
)?.publicKey?.replace("-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----")?.replace("", "")
|
)?.publicKey?.replace("-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----")?.replace("", "")
|
||||||
?.replace("\n", "")
|
?.replace("\n", "")
|
||||||
)
|
)
|
||||||
|
@ -162,8 +162,8 @@ class KtorKeyMap(private val userAuthRepository: IUserRepository) : KeyMap {
|
||||||
val username = (keyId ?: throw IllegalArgumentException("keyId is null")).substringBeforeLast("#pubkey")
|
val username = (keyId ?: throw IllegalArgumentException("keyId is null")).substringBeforeLast("#pubkey")
|
||||||
.substringAfterLast("/")
|
.substringAfterLast("/")
|
||||||
val publicBytes = Base64.getDecoder().decode(
|
val publicBytes = Base64.getDecoder().decode(
|
||||||
userAuthRepository.findByName(
|
userAuthRepository.findByNameAndDomain(
|
||||||
username
|
username,Config.configData.domain
|
||||||
)?.privateKey?.replace("-----BEGIN PRIVATE KEY-----", "")?.replace("-----END PRIVATE KEY-----", "")
|
)?.privateKey?.replace("-----BEGIN PRIVATE KEY-----", "")?.replace("-----END PRIVATE KEY-----", "")
|
||||||
?.replace("\n", "")
|
?.replace("\n", "")
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,7 +9,11 @@ interface IUserRepository {
|
||||||
|
|
||||||
suspend fun findByIds(ids: List<Long>): List<User>
|
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>
|
suspend fun findByNameAndDomains(names: List<Pair<String,String>>): List<User>
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,8 @@ import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransacti
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import java.time.Instant
|
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 {
|
init {
|
||||||
transaction(database) {
|
transaction(database) {
|
||||||
SchemaUtils.create(Users)
|
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 {
|
return query {
|
||||||
Users.select { Users.name eq name }.map {
|
Users.select { Users.name eq name }.map {
|
||||||
it.toUser()
|
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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
package dev.usbharu.hideout.routing
|
package dev.usbharu.hideout.routing
|
||||||
|
|
||||||
import dev.usbharu.hideout.plugins.UserSession
|
import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto
|
||||||
import dev.usbharu.hideout.service.IUserAuthService
|
import dev.usbharu.hideout.service.impl.UserService
|
||||||
import io.ktor.http.*
|
import io.ktor.http.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
import io.ktor.server.auth.*
|
import io.ktor.server.auth.*
|
||||||
import io.ktor.server.request.*
|
import io.ktor.server.request.*
|
||||||
import io.ktor.server.response.*
|
import io.ktor.server.response.*
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
import io.ktor.server.sessions.*
|
|
||||||
|
|
||||||
fun Application.register(userAuthService: IUserAuthService) {
|
fun Application.register(userService: UserService) {
|
||||||
|
|
||||||
routing {
|
routing {
|
||||||
get("/register") {
|
get("/register") {
|
||||||
|
@ -39,13 +38,10 @@ fun Application.register(userAuthService: IUserAuthService) {
|
||||||
val parameters = call.receiveParameters()
|
val parameters = call.receiveParameters()
|
||||||
val password = parameters["password"] ?: return@post call.respondRedirect("/register")
|
val password = parameters["password"] ?: return@post call.respondRedirect("/register")
|
||||||
val username = parameters["username"] ?: 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")
|
return@post call.respondRedirect("/register")
|
||||||
}
|
}
|
||||||
|
userService.createLocalUser(UserCreateDto(username, username, "", password))
|
||||||
val hash = userAuthService.hash(password)
|
|
||||||
userAuthService.registerAccount(username,hash)
|
|
||||||
// call.respondRedirect("/login")
|
|
||||||
call.respondRedirect("/users/$username")
|
call.respondRedirect("/users/$username")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package dev.usbharu.hideout.routing.activitypub
|
package dev.usbharu.hideout.routing.activitypub
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.config.Config
|
||||||
import dev.usbharu.hideout.exception.ParameterNotExistException
|
import dev.usbharu.hideout.exception.ParameterNotExistException
|
||||||
import dev.usbharu.hideout.plugins.respondAp
|
import dev.usbharu.hideout.plugins.respondAp
|
||||||
import dev.usbharu.hideout.service.activitypub.ActivityPubUserService
|
import dev.usbharu.hideout.service.activitypub.ActivityPubUserService
|
||||||
|
@ -24,7 +25,7 @@ fun Routing.usersAP(activityPubUserService: ActivityPubUserService, userService:
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
get {
|
get {
|
||||||
val userEntity = userService.findByName(call.parameters["name"]!!)
|
val userEntity = userService.findByNameLocalUser(call.parameters["name"]!!)
|
||||||
call.respondText(userEntity.toString() + "\n" + userService.findFollowersById(userEntity.id))
|
call.respondText(userEntity.toString() + "\n" + userService.findFollowersById(userEntity.id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ fun Routing.webfinger(userService:UserService){
|
||||||
.substringAfter("acct:")
|
.substringAfter("acct:")
|
||||||
.trimStart('@')
|
.trimStart('@')
|
||||||
|
|
||||||
val userEntity = userService.findByName(accountName)
|
val userEntity = userService.findByNameLocalUser(accountName)
|
||||||
|
|
||||||
val webFinger = WebFinger(
|
val webFinger = WebFinger(
|
||||||
subject = acct,
|
subject = acct,
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package dev.usbharu.hideout.service
|
package dev.usbharu.hideout.service
|
||||||
|
|
||||||
|
import java.security.KeyPair
|
||||||
|
|
||||||
interface IUserAuthService {
|
interface IUserAuthService {
|
||||||
fun hash(password: String): String
|
fun hash(password: String): String
|
||||||
|
|
||||||
suspend fun usernameAlreadyUse(username: String): Boolean
|
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
|
suspend fun verifyAccount(username: String, password: String): Boolean
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ class ActivityPubUserServiceImpl(
|
||||||
private val logger = LoggerFactory.getLogger(this::class.java)
|
private val logger = LoggerFactory.getLogger(this::class.java)
|
||||||
override suspend fun getPersonByName(name: String): Person {
|
override suspend fun getPersonByName(name: String): Person {
|
||||||
// TODO: JOINで書き直し
|
// TODO: JOINで書き直し
|
||||||
val userEntity = userService.findByName(name)
|
val userEntity = userService.findByNameLocalUser(name)
|
||||||
val userUrl = "${Config.configData.url}/users/$name"
|
val userUrl = "${Config.configData.url}/users/$name"
|
||||||
return Person(
|
return Person(
|
||||||
type = emptyList(),
|
type = emptyList(),
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
package dev.usbharu.hideout.service.impl
|
package dev.usbharu.hideout.service.impl
|
||||||
|
|
||||||
import dev.usbharu.hideout.config.Config
|
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.exception.UserNotFoundException
|
||||||
import dev.usbharu.hideout.repository.IUserRepository
|
import dev.usbharu.hideout.repository.IUserRepository
|
||||||
import dev.usbharu.hideout.service.IUserAuthService
|
import dev.usbharu.hideout.service.IUserAuthService
|
||||||
import io.ktor.util.*
|
import io.ktor.util.*
|
||||||
import java.security.*
|
import java.security.*
|
||||||
import java.security.interfaces.RSAPrivateKey
|
|
||||||
import java.security.interfaces.RSAPublicKey
|
|
||||||
import java.time.Instant
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class UserAuthService(
|
class UserAuthService(
|
||||||
|
@ -27,37 +23,13 @@ class UserAuthService(
|
||||||
return true
|
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 {
|
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")
|
?: throw UserNotFoundException("$username was not found")
|
||||||
return userEntity.password == hash(password)
|
return userEntity.password == hash(password)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateKeyPair(): KeyPair {
|
override suspend fun generateKeyPair(): KeyPair {
|
||||||
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
|
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
|
||||||
keyPairGenerator.initialize(1024)
|
keyPairGenerator.initialize(1024)
|
||||||
return keyPairGenerator.generateKeyPair()
|
return keyPairGenerator.generateKeyPair()
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
package dev.usbharu.hideout.service.impl
|
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.domain.model.hideout.entity.User
|
||||||
import dev.usbharu.hideout.exception.UserNotFoundException
|
import dev.usbharu.hideout.exception.UserNotFoundException
|
||||||
import dev.usbharu.hideout.repository.IUserRepository
|
import dev.usbharu.hideout.repository.IUserRepository
|
||||||
|
import dev.usbharu.hideout.service.IUserAuthService
|
||||||
import java.lang.Integer.min
|
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
|
private val maxLimit = 100
|
||||||
suspend fun findAll(limit: Int? = maxLimit, offset: Long? = 0): List<User> {
|
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)
|
return userRepository.findByIds(ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun findByName(name: String): User {
|
suspend fun findByName(name: String): List<User> {
|
||||||
return userRepository.findByName(name)
|
return userRepository.findByName(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun findByNameLocalUser(name: String): User {
|
||||||
|
return userRepository.findByNameAndDomain(name, Config.configData.domain)
|
||||||
?: throw UserNotFoundException("$name was not found.")
|
?: 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)
|
return userRepository.findByNameAndDomains(names)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,10 +49,37 @@ class UserService(private val userRepository: IUserRepository) {
|
||||||
return userRepository.findByUrls(urls)
|
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 {
|
suspend fun create(user: User): User {
|
||||||
return userRepository.save(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> {
|
suspend fun findFollowersById(id: Long): List<User> {
|
||||||
return userRepository.findFollowersById(id)
|
return userRepository.findFollowersById(id)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue