From 50b9e3178ca1bf689c39782ca66e783e7737662c Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:52:05 +0900 Subject: [PATCH 01/45] =?UTF-8?q?refactor:=20UserAuthentication=E3=82=92?= =?UTF-8?q?=E9=9D=9E=E6=8E=A8=E5=A5=A8=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/domain/model/User.kt | 27 ++++++++++++++++--- .../domain/model/UserAuthentication.kt | 5 ++-- .../hideout/repository/UserRepository.kt | 23 +++------------- .../activitypub/ActivityPubUserServiceImpl.kt | 6 ++++- .../hideout/service/impl/UserAuthService.kt | 6 ++++- 5 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt index 7239465e..62c8fa47 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt @@ -1,16 +1,26 @@ package dev.usbharu.hideout.domain.model +import org.h2.mvstore.type.LongDataType import org.jetbrains.exposed.dao.id.LongIdTable import org.jetbrains.exposed.sql.ResultRow +import org.jetbrains.exposed.sql.Table +import java.time.Instant +import java.time.LocalDateTime +import java.time.ZoneId data class User( + val id:Long, val name: String, val domain: String, val screenName: String, val description: String, + val password:String? = null, val inbox: String, val outbox: String, - val url: String + val url: String, + val publicKey:String, + val privateKey:String? = null, + val createdAt:LocalDateTime ) data class UserEntity( @@ -35,15 +45,21 @@ data class UserEntity( ) } -object Users : LongIdTable("users") { +object Users : Table("users") { + val id = long("id").uniqueIndex() val name = varchar("name", length = 64) val domain = varchar("domain", length = 255) val screenName = varchar("screen_name", length = 64) val description = varchar("description", length = 600) + val password = varchar("password", length = 255).nullable() val inbox = varchar("inbox", length = 255).uniqueIndex() val outbox = varchar("outbox", length = 255).uniqueIndex() val url = varchar("url", length = 255).uniqueIndex() + val publicKey = varchar("public_key", length = 10000) + val privateKey = varchar("private_key", length = 10000) + val createdAt = long("created_at") + override val primaryKey: PrimaryKey = PrimaryKey(id) init { uniqueIndex(name, domain) } @@ -52,12 +68,17 @@ object Users : LongIdTable("users") { fun ResultRow.toUser(): User { return User( + this[Users.id], this[Users.name], this[Users.domain], this[Users.screenName], this[Users.description], + this[Users.password], this[Users.inbox], this[Users.outbox], - this[Users.url] + this[Users.url], + this[Users.publicKey], + this[Users.privateKey], + LocalDateTime.ofInstant(Instant.ofEpochMilli((this[Users.createdAt])), ZoneId.systemDefault()) ) } diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt index d1cd3d82..c1f02961 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt @@ -3,13 +3,14 @@ package dev.usbharu.hideout.domain.model import org.jetbrains.exposed.dao.id.LongIdTable import org.jetbrains.exposed.sql.ReferenceOption +@Deprecated("") data class UserAuthentication( val userId: Long, val hash: String?, val publicKey: String, val privateKey: String? ) - +@Deprecated("") data class UserAuthenticationEntity( val id: Long, val userId: Long, @@ -25,7 +26,7 @@ data class UserAuthenticationEntity( userAuthentication.privateKey ) } - +@Deprecated("") object UsersAuthentication : LongIdTable("users_auth") { val userId = long("user_id").references(Users.id, onUpdate = ReferenceOption.CASCADE) val hash = varchar("hash", length = 64).nullable() diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt index dfaf32aa..c0382755 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt @@ -1,9 +1,6 @@ package dev.usbharu.hideout.repository -import dev.usbharu.hideout.domain.model.User -import dev.usbharu.hideout.domain.model.UserEntity -import dev.usbharu.hideout.domain.model.Users -import dev.usbharu.hideout.domain.model.UsersFollowers +import dev.usbharu.hideout.domain.model.* import kotlinx.coroutines.Dispatchers import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq @@ -20,21 +17,9 @@ class UserRepository(private val database: Database) : IUserRepository { } } - private 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] - ) - } - private fun ResultRow.toUserEntity(): UserEntity { return UserEntity( - this[Users.id].value, + this[Users.id], this[Users.name], this[Users.domain], this[Users.screenName], @@ -58,7 +43,7 @@ class UserRepository(private val database: Database) : IUserRepository { it[inbox] = user.inbox it[outbox] = user.outbox it[url] = user.url - }[Users.id].value, user) + }[Users.id], user) } } @@ -143,7 +128,7 @@ class UserRepository(private val database: Database) : IUserRepository { .select { Users.id eq id } .map { UserEntity( - id = it[followers[Users.id]].value, + id = it[followers[Users.id]], name = it[followers[Users.name]], domain = it[followers[Users.domain]], screenName = it[followers[Users.screenName]], diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt index 88272bdf..f4dd9fec 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt @@ -17,6 +17,7 @@ import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* import org.slf4j.LoggerFactory +import java.time.LocalDateTime class ActivityPubUserServiceImpl( private val userService: UserService, @@ -91,6 +92,7 @@ class ActivityPubUserServiceImpl( val person = Config.configData.objectMapper.readValue<Person>(httpResponse.bodyAsText()) val userEntity = userService.create( User( + id = 0L, name = person.preferredUsername ?: throw IllegalActivityPubObjectException("preferredUsername is null"), domain = url.substringAfter(":").substringBeforeLast("/"), @@ -98,7 +100,9 @@ class ActivityPubUserServiceImpl( description = person.summary ?: "", inbox = person.inbox ?: throw IllegalActivityPubObjectException("inbox is null"), outbox = person.outbox ?: throw IllegalActivityPubObjectException("outbox is null"), - url = url + url = url, + publicKey = "", + createdAt = LocalDateTime.now() ) ) userAuthService.createAccount( diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt index 5542d1ee..5166082a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt @@ -13,6 +13,7 @@ import io.ktor.util.* import java.security.* import java.security.interfaces.RSAPrivateKey import java.security.interfaces.RSAPublicKey +import java.time.LocalDateTime import java.util.* class UserAuthService( @@ -34,13 +35,16 @@ class UserAuthService( 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 + url = url, + publicKey = "", + createdAt = LocalDateTime.now(), ) val createdUser = userRepository.create(registerUser) From 07cf2c7c9d107f49dc8309d4285a7dbeb0756c8b Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 26 Apr 2023 17:08:27 +0900 Subject: [PATCH 02/45] =?UTF-8?q?refactor:=20UserEntity=E3=82=92=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/domain/model/Posts.kt | 1 + .../dev/usbharu/hideout/domain/model/User.kt | 66 --------------- .../domain/model/UserAuthentication.kt | 1 + .../hideout/domain/model/UsersFollowers.kt | 1 + .../hideout/repository/IUserRepository.kt | 21 +++-- .../hideout/repository/UserRepository.kt | 84 +++++++++++++------ .../hideout/service/impl/UserAuthService.kt | 1 - .../hideout/service/impl/UserService.kt | 19 ++--- .../hideout/plugins/ActivityPubKtTest.kt | 39 ++++++--- .../usbharu/hideout/plugins/KtorKeyMapTest.kt | 36 +++++--- .../hideout/repository/UserRepositoryTest.kt | 1 - .../ActivityPubFollowServiceImplTest.kt | 15 ++-- .../ActivityPubNoteServiceImplTest.kt | 26 ++++-- 13 files changed, 159 insertions(+), 152 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/Posts.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/Posts.kt index 3a6867db..d9e13915 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/Posts.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/Posts.kt @@ -1,5 +1,6 @@ package dev.usbharu.hideout.domain.model +import dev.usbharu.hideout.repository.Users import org.jetbrains.exposed.sql.ResultRow import org.jetbrains.exposed.sql.Table diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt index 62c8fa47..ee46667a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt @@ -1,12 +1,6 @@ package dev.usbharu.hideout.domain.model -import org.h2.mvstore.type.LongDataType -import org.jetbrains.exposed.dao.id.LongIdTable -import org.jetbrains.exposed.sql.ResultRow -import org.jetbrains.exposed.sql.Table -import java.time.Instant import java.time.LocalDateTime -import java.time.ZoneId data class User( val id:Long, @@ -22,63 +16,3 @@ data class User( val privateKey:String? = null, val createdAt:LocalDateTime ) - -data class UserEntity( - val id: Long, - val name: String, - val domain: String, - val screenName: String, - val description: String, - val inbox: String, - val outbox: String, - val url: String -) { - constructor(id: Long, user: User) : this( - id, - user.name, - user.domain, - user.screenName, - user.description, - user.inbox, - user.outbox, - user.url - ) -} - -object Users : Table("users") { - val id = long("id").uniqueIndex() - val name = varchar("name", length = 64) - val domain = varchar("domain", length = 255) - val screenName = varchar("screen_name", length = 64) - val description = varchar("description", length = 600) - val password = varchar("password", length = 255).nullable() - val inbox = varchar("inbox", length = 255).uniqueIndex() - val outbox = varchar("outbox", length = 255).uniqueIndex() - val url = varchar("url", length = 255).uniqueIndex() - val publicKey = varchar("public_key", length = 10000) - val privateKey = varchar("private_key", length = 10000) - val createdAt = long("created_at") - - override val primaryKey: PrimaryKey = PrimaryKey(id) - init { - uniqueIndex(name, domain) - } -} - - -fun ResultRow.toUser(): User { - return User( - this[Users.id], - this[Users.name], - this[Users.domain], - this[Users.screenName], - this[Users.description], - this[Users.password], - this[Users.inbox], - this[Users.outbox], - this[Users.url], - this[Users.publicKey], - this[Users.privateKey], - LocalDateTime.ofInstant(Instant.ofEpochMilli((this[Users.createdAt])), ZoneId.systemDefault()) - ) -} diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt index c1f02961..5754021a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt @@ -1,5 +1,6 @@ package dev.usbharu.hideout.domain.model +import dev.usbharu.hideout.repository.Users import org.jetbrains.exposed.dao.id.LongIdTable import org.jetbrains.exposed.sql.ReferenceOption diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/UsersFollowers.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/UsersFollowers.kt index 1f5de8ce..b5078c53 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/UsersFollowers.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/UsersFollowers.kt @@ -1,5 +1,6 @@ package dev.usbharu.hideout.domain.model +import dev.usbharu.hideout.repository.Users import org.jetbrains.exposed.dao.id.LongIdTable object UsersFollowers : LongIdTable("users_followers") { diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt index dd89dbd9..73ac26a4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt @@ -1,32 +1,31 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.User -import dev.usbharu.hideout.domain.model.UserEntity interface IUserRepository { - suspend fun create(user: User): UserEntity + suspend fun create(user: User): User - suspend fun findById(id: Long): UserEntity? + suspend fun findById(id: Long): User? - suspend fun findByIds(ids: List<Long>): List<UserEntity> + suspend fun findByIds(ids: List<Long>): List<User> - suspend fun findByName(name: String): UserEntity? + suspend fun findByName(name: String): User? - suspend fun findByNameAndDomains(names: List<Pair<String,String>>): List<UserEntity> + suspend fun findByNameAndDomains(names: List<Pair<String,String>>): List<User> - suspend fun findByUrl(url:String):UserEntity? + suspend fun findByUrl(url:String): User? - suspend fun findByUrls(urls: List<String>): List<UserEntity> + suspend fun findByUrls(urls: List<String>): List<User> - suspend fun update(userEntity: UserEntity) + suspend fun update(userEntity: User) suspend fun delete(id: Long) suspend fun findAll(): List<User> - suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long = 0): List<UserEntity> + suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long = 0): List<User> suspend fun createFollower(id: Long, follower: Long) suspend fun deleteFollower(id: Long, follower: Long) - suspend fun findFollowersById(id: Long): List<UserEntity> + suspend fun findFollowersById(id: Long): List<User> } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt index c0382755..051ceff0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt @@ -6,6 +6,9 @@ import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction import org.jetbrains.exposed.sql.transactions.transaction +import java.time.Instant +import java.time.LocalDateTime +import java.time.ZoneId class UserRepository(private val database: Database) : IUserRepository { init { @@ -17,25 +20,14 @@ class UserRepository(private val database: Database) : IUserRepository { } } - private fun ResultRow.toUserEntity(): UserEntity { - return UserEntity( - this[Users.id], - this[Users.name], - this[Users.domain], - this[Users.screenName], - this[Users.description], - this[Users.inbox], - this[Users.outbox], - this[Users.url], - ) - } + private fun ResultRow.toUserEntity(): User = toUser() suspend fun <T> query(block: suspend () -> T): T = newSuspendedTransaction(Dispatchers.IO) { block() } - override suspend fun create(user: User): UserEntity { + override suspend fun create(user: User): User { return query { - UserEntity(Users.insert { + Users.insert { it[name] = user.name it[domain] = user.domain it[screenName] = user.screenName @@ -43,7 +35,8 @@ class UserRepository(private val database: Database) : IUserRepository { it[inbox] = user.inbox it[outbox] = user.outbox it[url] = user.url - }[Users.id], user) + } + return@query user } } @@ -56,7 +49,7 @@ class UserRepository(private val database: Database) : IUserRepository { } } - override suspend fun findById(id: Long): UserEntity? { + override suspend fun findById(id: Long): User? { return query { Users.select { Users.id eq id }.map { it.toUserEntity() @@ -64,7 +57,7 @@ class UserRepository(private val database: Database) : IUserRepository { } } - override suspend fun findByIds(ids: List<Long>): List<UserEntity> { + override suspend fun findByIds(ids: List<Long>): List<User> { return query { Users.select { Users.id inList ids }.map { it.toUserEntity() @@ -72,7 +65,7 @@ class UserRepository(private val database: Database) : IUserRepository { } } - override suspend fun findByName(name: String): UserEntity? { + override suspend fun findByName(name: String): User? { return query { Users.select { Users.name eq name }.map { it.toUserEntity() @@ -80,7 +73,7 @@ class UserRepository(private val database: Database) : IUserRepository { } } - override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<UserEntity> { + override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> { return query { val selectAll = Users.selectAll() names.forEach { (name, domain) -> @@ -90,19 +83,19 @@ class UserRepository(private val database: Database) : IUserRepository { } } - override suspend fun findByUrl(url: String): UserEntity? { + override suspend fun findByUrl(url: String): User? { return query { Users.select { Users.url eq url }.singleOrNull()?.toUserEntity() } } - override suspend fun findByUrls(urls: List<String>): List<UserEntity> { + override suspend fun findByUrls(urls: List<String>): List<User> { return query { Users.select { Users.url inList urls }.map { it.toUserEntity() } } } - override suspend fun findFollowersById(id: Long): List<UserEntity> { + override suspend fun findFollowersById(id: Long): List<User> { return query { val followers = Users.alias("FOLLOWERS") Users.innerJoin( @@ -127,22 +120,26 @@ class UserRepository(private val database: Database) : IUserRepository { ) .select { Users.id eq id } .map { - UserEntity( + User( id = it[followers[Users.id]], name = it[followers[Users.name]], domain = it[followers[Users.domain]], screenName = it[followers[Users.screenName]], description = it[followers[Users.description]], + password = it[followers[Users.password]], inbox = it[followers[Users.inbox]], outbox = it[followers[Users.outbox]], url = it[followers[Users.url]], + publicKey = it[followers[Users.publicKey]], + privateKey = it[followers[Users.privateKey]], + createdAt = LocalDateTime.ofInstant(Instant.ofEpochMilli(it[followers[Users.createdAt]]), ZoneId.systemDefault()) ) } } } - override suspend fun update(userEntity: UserEntity) { + override suspend fun update(userEntity: User) { return query { Users.update({ Users.id eq userEntity.id }) { it[name] = userEntity.name @@ -174,9 +171,46 @@ class UserRepository(private val database: Database) : IUserRepository { } } - override suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long): List<UserEntity> { + override suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long): List<User> { return query { Users.selectAll().limit(limit, offset).map { it.toUserEntity() } } } } + +object Users : Table("users") { + val id = long("id").uniqueIndex() + val name = varchar("name", length = 64) + val domain = varchar("domain", length = 255) + val screenName = varchar("screen_name", length = 64) + val description = varchar("description", length = 600) + val password = varchar("password", length = 255).nullable() + val inbox = varchar("inbox", length = 255).uniqueIndex() + val outbox = varchar("outbox", length = 255).uniqueIndex() + val url = varchar("url", length = 255).uniqueIndex() + val publicKey = varchar("public_key", length = 10000) + val privateKey = varchar("private_key", length = 10000) + val createdAt = long("created_at") + + override val primaryKey: PrimaryKey = PrimaryKey(id) + init { + uniqueIndex(name, domain) + } +} + +fun ResultRow.toUser(): User { + return User( + this[Users.id], + this[Users.name], + this[Users.domain], + this[Users.screenName], + this[Users.description], + this[Users.password], + this[Users.inbox], + this[Users.outbox], + this[Users.url], + this[Users.publicKey], + this[Users.privateKey], + LocalDateTime.ofInstant(Instant.ofEpochMilli((this[Users.createdAt])), ZoneId.systemDefault()) + ) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt index 5166082a..a0cdfabc 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt @@ -4,7 +4,6 @@ import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.domain.model.User import dev.usbharu.hideout.domain.model.UserAuthentication import dev.usbharu.hideout.domain.model.UserAuthenticationEntity -import dev.usbharu.hideout.domain.model.UserEntity import dev.usbharu.hideout.exception.UserNotFoundException import dev.usbharu.hideout.repository.IUserAuthRepository import dev.usbharu.hideout.repository.IUserRepository diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt index a64ccd04..fcbc60cb 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt @@ -1,7 +1,6 @@ package dev.usbharu.hideout.service.impl import dev.usbharu.hideout.domain.model.User -import dev.usbharu.hideout.domain.model.UserEntity import dev.usbharu.hideout.exception.UserNotFoundException import dev.usbharu.hideout.repository.IUserRepository import java.lang.Integer.min @@ -9,7 +8,7 @@ import java.lang.Integer.min class UserService(private val userRepository: IUserRepository) { private val maxLimit = 100 - suspend fun findAll(limit: Int? = maxLimit, offset: Long? = 0): List<UserEntity> { + suspend fun findAll(limit: Int? = maxLimit, offset: Long? = 0): List<User> { return userRepository.findAllByLimitAndByOffset( min(limit ?: maxLimit, maxLimit), @@ -17,36 +16,36 @@ class UserService(private val userRepository: IUserRepository) { ) } - suspend fun findById(id: Long): UserEntity { + suspend fun findById(id: Long): User { return userRepository.findById(id) ?: throw UserNotFoundException("$id was not found.") } - suspend fun findByIds(ids: List<Long>): List<UserEntity> { + suspend fun findByIds(ids: List<Long>): List<User> { return userRepository.findByIds(ids) } - suspend fun findByName(name: String): UserEntity { + suspend fun findByName(name: String): User { return userRepository.findByName(name) ?: throw UserNotFoundException("$name was not found.") } - suspend fun findByNameAndDomains(names: List<Pair<String,String>>): List<UserEntity> { + suspend fun findByNameAndDomains(names: List<Pair<String,String>>): List<User> { return userRepository.findByNameAndDomains(names) } - suspend fun findByUrl(url: String): UserEntity { + suspend fun findByUrl(url: String): User { return userRepository.findByUrl(url) ?: throw UserNotFoundException("$url was not found.") } - suspend fun findByUrls(urls: List<String>): List<UserEntity> { + suspend fun findByUrls(urls: List<String>): List<User> { return userRepository.findByUrls(urls) } - suspend fun create(user: User): UserEntity { + suspend fun create(user: User): User { return userRepository.create(user) } - suspend fun findFollowersById(id: Long): List<UserEntity> { + suspend fun findFollowersById(id: Long): List<User> { return userRepository.findFollowersById(id) } diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt index b5690c99..035f3143 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt @@ -1,10 +1,9 @@ package dev.usbharu.hideout.plugins -import dev.usbharu.hideout.domain.model.ap.JsonLd import dev.usbharu.hideout.domain.model.User import dev.usbharu.hideout.domain.model.UserAuthentication import dev.usbharu.hideout.domain.model.UserAuthenticationEntity -import dev.usbharu.hideout.domain.model.UserEntity +import dev.usbharu.hideout.domain.model.ap.JsonLd import dev.usbharu.hideout.repository.IUserAuthRepository import dev.usbharu.hideout.repository.IUserRepository import dev.usbharu.hideout.service.impl.UserAuthService @@ -17,41 +16,55 @@ import org.junit.jupiter.api.Test import java.security.KeyPairGenerator import java.security.interfaces.RSAPrivateKey import java.security.interfaces.RSAPublicKey +import java.time.LocalDateTime class ActivityPubKtTest { @Test fun HttpSignTest(): Unit = runBlocking { val ktorKeyMap = KtorKeyMap(UserAuthService(object : IUserRepository { - override suspend fun create(user: User): UserEntity { + override suspend fun create(user: User): User { TODO("Not yet implemented") } - override suspend fun findById(id: Long): UserEntity? { + override suspend fun findById(id: Long): User? { TODO("Not yet implemented") } - override suspend fun findByIds(ids: List<Long>): List<UserEntity> { + override suspend fun findByIds(ids: List<Long>): List<User> { TODO("Not yet implemented") } - override suspend fun findByName(name: String): UserEntity? { - return UserEntity(1, "test", "localhost", "test", "","","","") + override suspend fun findByName(name: String): User? { + return User( + 1, + "test", + "localhost", + "test", + "", + "", + "", + "", + "", + "", + null, + LocalDateTime.now() + ) } - override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<UserEntity> { + override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> { TODO("Not yet implemented") } - override suspend fun findByUrl(url: String): UserEntity? { + override suspend fun findByUrl(url: String): User? { TODO("Not yet implemented") } - override suspend fun findByUrls(urls: List<String>): List<UserEntity> { + override suspend fun findByUrls(urls: List<String>): List<User> { TODO("Not yet implemented") } - override suspend fun update(userEntity: UserEntity) { + override suspend fun update(userEntity: User) { TODO("Not yet implemented") } @@ -63,7 +76,7 @@ class ActivityPubKtTest { TODO("Not yet implemented") } - override suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long): List<UserEntity> { + override suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long): List<User> { TODO("Not yet implemented") } @@ -75,7 +88,7 @@ class ActivityPubKtTest { TODO("Not yet implemented") } - override suspend fun findFollowersById(id: Long): List<UserEntity> { + override suspend fun findFollowersById(id: Long): List<User> { TODO("Not yet implemented") } diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt index 02cfb9b4..edaeaff3 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt @@ -3,7 +3,6 @@ package dev.usbharu.hideout.plugins import dev.usbharu.hideout.domain.model.User import dev.usbharu.hideout.domain.model.UserAuthentication import dev.usbharu.hideout.domain.model.UserAuthenticationEntity -import dev.usbharu.hideout.domain.model.UserEntity import dev.usbharu.hideout.repository.IUserAuthRepository import dev.usbharu.hideout.repository.IUserRepository import dev.usbharu.hideout.service.impl.UserAuthService @@ -12,41 +11,54 @@ import org.junit.jupiter.api.Test import java.security.KeyPairGenerator import java.security.interfaces.RSAPrivateKey import java.security.interfaces.RSAPublicKey +import java.time.LocalDateTime class KtorKeyMapTest { @Test fun getPrivateKey() { val ktorKeyMap = KtorKeyMap(UserAuthService(object : IUserRepository { - override suspend fun create(user: User): UserEntity { + override suspend fun create(user: User): User { TODO("Not yet implemented") } - override suspend fun findById(id: Long): UserEntity? { + override suspend fun findById(id: Long): User? { TODO("Not yet implemented") } - override suspend fun findByIds(ids: List<Long>): List<UserEntity> { + override suspend fun findByIds(ids: List<Long>): List<User> { TODO("Not yet implemented") } - override suspend fun findByName(name: String): UserEntity? { - return UserEntity(1, "test", "localhost", "test", "","","","") + override suspend fun findByName(name: String): User? { + return User( + 1, + "test", + "localhost", + "test", + "", + "", + "", + "", + "", + "", + createdAt = LocalDateTime.now() + ) } - override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<UserEntity> { + override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> { TODO("Not yet implemented") } - override suspend fun findByUrl(url: String): UserEntity? { + override suspend fun findByUrl(url: String): User? { TODO("Not yet implemented") } - override suspend fun findByUrls(urls: List<String>): List<UserEntity> { + override suspend fun findByUrls(urls: List<String>): List<User> { TODO("Not yet implemented") } - override suspend fun update(userEntity: UserEntity) { + override suspend fun update(userEntity: User) { TODO("Not yet implemented") } @@ -58,7 +70,7 @@ class KtorKeyMapTest { TODO("Not yet implemented") } - override suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long): List<UserEntity> { + override suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long): List<User> { TODO("Not yet implemented") } @@ -70,7 +82,7 @@ class KtorKeyMapTest { TODO("Not yet implemented") } - override suspend fun findFollowersById(id: Long): List<UserEntity> { + override suspend fun findFollowersById(id: Long): List<User> { TODO("Not yet implemented") } diff --git a/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt b/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt index 740bc90e..54b6dc69 100644 --- a/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt @@ -3,7 +3,6 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.User -import dev.usbharu.hideout.domain.model.Users import dev.usbharu.hideout.domain.model.UsersFollowers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest diff --git a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt index c5a0bb5f..3de7494d 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt @@ -6,7 +6,7 @@ package dev.usbharu.hideout.service.activitypub import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.config.ConfigData -import dev.usbharu.hideout.domain.model.UserEntity +import dev.usbharu.hideout.domain.model.User import dev.usbharu.hideout.domain.model.ap.* import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob import dev.usbharu.hideout.service.impl.UserService @@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.* import utils.JsonObjectMapper +import java.time.LocalDateTime class ActivityPubFollowServiceImplTest { @Test @@ -88,7 +89,7 @@ class ActivityPubFollowServiceImplTest { } val userService = mock<UserService> { onBlocking { findByUrls(any()) } doReturn listOf( - UserEntity( + User( id = 1L, name = "test", domain = "example.com", @@ -96,9 +97,11 @@ class ActivityPubFollowServiceImplTest { description = "This user is test user.", inbox = "https://example.com/inbox", outbox = "https://example.com/outbox", - url = "https://example.com" + url = "https://example.com", + publicKey = "", + createdAt = LocalDateTime.now() ), - UserEntity( + User( id = 2L, name = "follower", domain = "follower.example.com", @@ -106,7 +109,9 @@ class ActivityPubFollowServiceImplTest { description = "This user is test follower user.", inbox = "https://follower.example.com/inbox", outbox = "https://follower.example.com/outbox", - url = "https://follower.example.com" + url = "https://follower.example.com", + publicKey = "", + createdAt = LocalDateTime.now() ) ) onBlocking { addFollowers(any(), any()) } doReturn Unit diff --git a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt index 8d820be6..a9445572 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt @@ -6,7 +6,7 @@ package dev.usbharu.hideout.service.activitypub import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.config.ConfigData import dev.usbharu.hideout.domain.model.PostEntity -import dev.usbharu.hideout.domain.model.UserEntity +import dev.usbharu.hideout.domain.model.User import dev.usbharu.hideout.domain.model.job.DeliverPostJob import dev.usbharu.hideout.service.impl.UserService import dev.usbharu.hideout.service.job.JobQueueParentService @@ -20,13 +20,14 @@ import org.junit.jupiter.api.Test import org.mockito.Mockito.eq import org.mockito.kotlin.* import utils.JsonObjectMapper +import java.time.LocalDateTime import kotlin.test.assertEquals class ActivityPubNoteServiceImplTest { @Test fun `createPost 新しい投稿`() = runTest { - val followers = listOf<UserEntity>( - UserEntity( + val followers = listOf<User>( + User( 2L, "follower", "follower.example.com", @@ -34,9 +35,12 @@ class ActivityPubNoteServiceImplTest { "test follower user", "https://follower.example.com/inbox", "https://follower.example.com/outbox", - "https://follower.example.com" + "https://follower.example.com", + "", + publicKey = "", + createdAt = LocalDateTime.now() ), - UserEntity( + User( 3L, "follower2", "follower2.example.com", @@ -44,11 +48,14 @@ class ActivityPubNoteServiceImplTest { "test follower2 user", "https://follower2.example.com/inbox", "https://follower2.example.com/outbox", - "https:.//follower2.example.com" + "https://follower2.example.com", + "", + publicKey = "", + createdAt = LocalDateTime.now() ) ) val userService = mock<UserService> { - onBlocking { findById(eq(1L)) } doReturn UserEntity( + onBlocking { findById(eq(1L)) } doReturn User( 1L, "test", "example.com", @@ -56,7 +63,10 @@ class ActivityPubNoteServiceImplTest { "test user", "https://example.com/inbox", "https://example.com/outbox", - "https:.//example.com" + "https:.//example.com", + "", + publicKey = "", + createdAt = LocalDateTime.now() ) onBlocking { findFollowersById(eq(1L)) } doReturn followers } From 4442022f9781575aae36c23f45db5157f912a653 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 26 Apr 2023 17:10:19 +0900 Subject: [PATCH 03/45] =?UTF-8?q?fix:=20=E9=87=8D=E8=A4=87=E3=81=97?= =?UTF-8?q?=E3=81=9Findex=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/dev/usbharu/hideout/repository/UserRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt index 051ceff0..dd224212 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt @@ -179,7 +179,7 @@ class UserRepository(private val database: Database) : IUserRepository { } object Users : Table("users") { - val id = long("id").uniqueIndex() + val id = long("id") val name = varchar("name", length = 64) val domain = varchar("domain", length = 255) val screenName = varchar("screen_name", length = 64) From d417245d9291470c8ddca2a99dd507180593ac47 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 26 Apr 2023 17:28:59 +0900 Subject: [PATCH 04/45] =?UTF-8?q?refactor:=20UserAuth=E9=96=A2=E9=80=A3?= =?UTF-8?q?=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/dev/usbharu/hideout/Application.kt | 3 +- .../domain/model/UserAuthentication.kt | 17 +---- .../usbharu/hideout/plugins/ActivityPub.kt | 14 ++--- .../hideout/repository/IUserAuthRepository.kt | 15 ----- .../hideout/repository/UserAuthRepository.kt | 63 ------------------- .../hideout/service/IUserAuthService.kt | 7 --- .../activitypub/ActivityPubUserServiceImpl.kt | 23 ++----- .../hideout/service/impl/UserAuthService.kt | 35 ++--------- .../HttpSignatureVerifyServiceImpl.kt | 3 +- .../hideout/plugins/ActivityPubKtTest.kt | 38 +---------- .../usbharu/hideout/plugins/KtorKeyMapTest.kt | 38 +---------- 11 files changed, 25 insertions(+), 231 deletions(-) delete mode 100644 src/main/kotlin/dev/usbharu/hideout/repository/IUserAuthRepository.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/repository/UserAuthRepository.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/Application.kt b/src/main/kotlin/dev/usbharu/hideout/Application.kt index e4bca1fe..149a839e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/Application.kt +++ b/src/main/kotlin/dev/usbharu/hideout/Application.kt @@ -58,8 +58,7 @@ fun Application.parent() { } single<IUserRepository> { UserRepository(get()) } - single<IUserAuthRepository> { UserAuthRepository(get()) } - single<IUserAuthService> { UserAuthService(get(), get()) } + single<IUserAuthService> { UserAuthService(get()) } single<HttpSignatureVerifyService> { HttpSignatureVerifyServiceImpl(get()) } single<JobQueueParentService> { val kJobJobQueueService = KJobJobQueueParentService(get()) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt index 5754021a..9dbd767f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt @@ -11,22 +11,7 @@ data class UserAuthentication( val publicKey: String, val privateKey: String? ) -@Deprecated("") -data class UserAuthenticationEntity( - val id: Long, - val userId: Long, - val hash: String?, - val publicKey: String, - val privateKey: String? -) { - constructor(id: Long, userAuthentication: UserAuthentication) : this( - id, - userAuthentication.userId, - userAuthentication.hash, - userAuthentication.publicKey, - userAuthentication.privateKey - ) -} + @Deprecated("") object UsersAuthentication : LongIdTable("users_auth") { val userId = long("user_id").references(Users.id, onUpdate = ReferenceOption.CASCADE) diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt index db0e6a1f..50d4faaa 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt @@ -1,8 +1,8 @@ package dev.usbharu.hideout.plugins -import dev.usbharu.hideout.domain.model.ap.JsonLd import dev.usbharu.hideout.config.Config -import dev.usbharu.hideout.service.IUserAuthService +import dev.usbharu.hideout.domain.model.ap.JsonLd +import dev.usbharu.hideout.repository.IUserRepository import dev.usbharu.hideout.service.impl.UserAuthService import dev.usbharu.hideout.util.HttpUtil.Activity import io.ktor.client.* @@ -144,14 +144,14 @@ val httpSignaturePlugin = createClientPlugin("HttpSign", ::HttpSignaturePluginCo } } -class KtorKeyMap(private val userAuthRepository: IUserAuthService) : KeyMap { +class KtorKeyMap(private val userAuthRepository: IUserRepository) : KeyMap { override fun getPublicKey(keyId: String?): PublicKey = runBlocking { val username = (keyId ?: throw IllegalArgumentException("keyId is null")).substringBeforeLast("#pubkey") .substringAfterLast("/") val publicBytes = Base64.getDecoder().decode( - userAuthRepository.findByUsername( + userAuthRepository.findByName( username - ).publicKey?.replace("-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----")?.replace("", "") + )?.publicKey?.replace("-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----")?.replace("", "") ?.replace("\n", "") ) val x509EncodedKeySpec = X509EncodedKeySpec(publicBytes) @@ -162,9 +162,9 @@ class KtorKeyMap(private val userAuthRepository: IUserAuthService) : KeyMap { val username = (keyId ?: throw IllegalArgumentException("keyId is null")).substringBeforeLast("#pubkey") .substringAfterLast("/") val publicBytes = Base64.getDecoder().decode( - userAuthRepository.findByUsername( + userAuthRepository.findByName( username - ).privateKey?.replace("-----BEGIN PRIVATE KEY-----", "")?.replace("-----END PRIVATE KEY-----", "") + )?.privateKey?.replace("-----BEGIN PRIVATE KEY-----", "")?.replace("-----END PRIVATE KEY-----", "") ?.replace("\n", "") ) val x509EncodedKeySpec = PKCS8EncodedKeySpec(publicBytes) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/IUserAuthRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/IUserAuthRepository.kt deleted file mode 100644 index 2f6f46ba..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/repository/IUserAuthRepository.kt +++ /dev/null @@ -1,15 +0,0 @@ -package dev.usbharu.hideout.repository - -import dev.usbharu.hideout.domain.model.UserAuthentication -import dev.usbharu.hideout.domain.model.UserAuthenticationEntity - -interface IUserAuthRepository { - suspend fun create(userAuthentication: UserAuthentication):UserAuthenticationEntity - - suspend fun findById(id:Long):UserAuthenticationEntity? - - suspend fun update(userAuthenticationEntity: UserAuthenticationEntity) - - suspend fun delete(id:Long) - suspend fun findByUserId(id: Long): UserAuthenticationEntity? -} diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserAuthRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserAuthRepository.kt deleted file mode 100644 index 0bb5543c..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserAuthRepository.kt +++ /dev/null @@ -1,63 +0,0 @@ -package dev.usbharu.hideout.repository - -import dev.usbharu.hideout.domain.model.UserAuthentication -import dev.usbharu.hideout.domain.model.UserAuthenticationEntity -import dev.usbharu.hideout.domain.model.UsersAuthentication -import kotlinx.coroutines.Dispatchers -import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction -import org.jetbrains.exposed.sql.transactions.transaction - -class UserAuthRepository(private val database: Database) : IUserAuthRepository { - - init { - transaction(database) { - SchemaUtils.create(UsersAuthentication) - SchemaUtils.createMissingTablesAndColumns(UsersAuthentication) - } - } - - private fun ResultRow.toUserAuth():UserAuthenticationEntity{ - return UserAuthenticationEntity( - id = this[UsersAuthentication.id].value, - userId = this[UsersAuthentication.userId], - hash = this[UsersAuthentication.hash], - publicKey = this[UsersAuthentication.publicKey], - privateKey = this[UsersAuthentication.privateKey] - ) - } - - - suspend fun <T> query(block: suspend () -> T): T = - newSuspendedTransaction(Dispatchers.IO) {block()} - override suspend fun create(userAuthentication: UserAuthentication): UserAuthenticationEntity { - return query { - UserAuthenticationEntity( - UsersAuthentication.insert { - it[userId] = userAuthentication.userId - it[hash] = userAuthentication.hash - it[publicKey] = userAuthentication.publicKey - it[privateKey] = userAuthentication.privateKey - }[UsersAuthentication.id].value,userAuthentication - ) - } - } - - override suspend fun findById(id: Long): UserAuthenticationEntity? { - TODO("Not yet implemented") - } - - override suspend fun findByUserId(id:Long):UserAuthenticationEntity? { - return query { - UsersAuthentication.select { UsersAuthentication.userId eq id }.map { it.toUserAuth() }.singleOrNull() - } - } - - override suspend fun update(userAuthenticationEntity: UserAuthenticationEntity) { - TODO("Not yet implemented") - } - - override suspend fun delete(id: Long) { - TODO("Not yet implemented") - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/IUserAuthService.kt b/src/main/kotlin/dev/usbharu/hideout/service/IUserAuthService.kt index d2096d37..1702c41b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/IUserAuthService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/IUserAuthService.kt @@ -1,8 +1,5 @@ package dev.usbharu.hideout.service -import dev.usbharu.hideout.domain.model.UserAuthentication -import dev.usbharu.hideout.domain.model.UserAuthenticationEntity - interface IUserAuthService { fun hash(password: String): String @@ -11,8 +8,4 @@ interface IUserAuthService { suspend fun verifyAccount(username: String, password: String): Boolean - suspend fun findByUserId(userId: Long): UserAuthenticationEntity - - suspend fun findByUsername(username: String): UserAuthenticationEntity - suspend fun createAccount(userEntity: UserAuthentication): UserAuthenticationEntity } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt index f4dd9fec..14d4cd11 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt @@ -1,12 +1,11 @@ package dev.usbharu.hideout.service.activitypub import com.fasterxml.jackson.module.kotlin.readValue +import dev.usbharu.hideout.config.Config +import dev.usbharu.hideout.domain.model.User import dev.usbharu.hideout.domain.model.ap.Image import dev.usbharu.hideout.domain.model.ap.Key import dev.usbharu.hideout.domain.model.ap.Person -import dev.usbharu.hideout.config.Config -import dev.usbharu.hideout.domain.model.User -import dev.usbharu.hideout.domain.model.UserAuthentication import dev.usbharu.hideout.exception.UserNotFoundException import dev.usbharu.hideout.exception.ap.IllegalActivityPubObjectException import dev.usbharu.hideout.service.IUserAuthService @@ -30,7 +29,6 @@ class ActivityPubUserServiceImpl( override suspend fun getPersonByName(name: String): Person { // TODO: JOINで書き直し val userEntity = userService.findByName(name) - val userAuthEntity = userAuthService.findByUserId(userEntity.id) val userUrl = "${Config.configData.url}/users/$name" return Person( type = emptyList(), @@ -52,7 +50,7 @@ class ActivityPubUserServiceImpl( name = "Public Key", id = "$userUrl#pubkey", owner = userUrl, - publicKeyPem = userAuthEntity.publicKey + publicKeyPem = userEntity.publicKey ) ) } @@ -60,7 +58,6 @@ class ActivityPubUserServiceImpl( override suspend fun fetchPerson(url: String): Person { return try { val userEntity = userService.findByUrl(url) - val userAuthEntity = userAuthService.findByUsername(userEntity.name) return Person( type = emptyList(), name = userEntity.name, @@ -81,7 +78,7 @@ class ActivityPubUserServiceImpl( name = "Public Key", id = "$url#pubkey", owner = url, - publicKeyPem = userAuthEntity.publicKey + publicKeyPem = userEntity.publicKey ) ) @@ -90,7 +87,7 @@ class ActivityPubUserServiceImpl( accept(ContentType.Application.Activity) } val person = Config.configData.objectMapper.readValue<Person>(httpResponse.bodyAsText()) - val userEntity = userService.create( + userService.create( User( id = 0L, name = person.preferredUsername @@ -101,18 +98,10 @@ class ActivityPubUserServiceImpl( inbox = person.inbox ?: throw IllegalActivityPubObjectException("inbox is null"), outbox = person.outbox ?: throw IllegalActivityPubObjectException("outbox is null"), url = url, - publicKey = "", + publicKey = person.publicKey?.publicKeyPem ?: throw IllegalActivityPubObjectException("publicKey is null"), createdAt = LocalDateTime.now() ) ) - userAuthService.createAccount( - UserAuthentication( - userEntity.id, - null, - person.publicKey?.publicKeyPem ?: throw IllegalActivityPubObjectException("publicKey is null"), - null - ) - ) person } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt index a0cdfabc..db6dccf7 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt @@ -2,10 +2,7 @@ package dev.usbharu.hideout.service.impl import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.domain.model.User -import dev.usbharu.hideout.domain.model.UserAuthentication -import dev.usbharu.hideout.domain.model.UserAuthenticationEntity import dev.usbharu.hideout.exception.UserNotFoundException -import dev.usbharu.hideout.repository.IUserAuthRepository import dev.usbharu.hideout.repository.IUserRepository import dev.usbharu.hideout.service.IUserAuthService import io.ktor.util.* @@ -16,8 +13,7 @@ import java.time.LocalDateTime import java.util.* class UserAuthService( - val userRepository: IUserRepository, - val userAuthRepository: IUserAuthRepository + val userRepository: IUserRepository ) : IUserAuthService { @@ -31,6 +27,7 @@ class UserAuthService( return true } + @Deprecated("") override suspend fun registerAccount(username: String, hash: String) { val url = "${Config.configData.url}/users/$username" val registerUser = User( @@ -51,37 +48,13 @@ class UserAuthService( val privateKey = keyPair.private as RSAPrivateKey val publicKey = keyPair.public as RSAPublicKey - - val userAuthentication = UserAuthentication( - createdUser.id, - hash, - publicKey.toPem(), - privateKey.toPem() - ) - - userAuthRepository.create(userAuthentication) + TODO() } override suspend fun verifyAccount(username: String, password: String): Boolean { val userEntity = userRepository.findByName(username) ?: throw UserNotFoundException("$username was not found") - val userAuthEntity = userAuthRepository.findByUserId(userEntity.id) - ?: throw UserNotFoundException("$username auth data was not found") - return userAuthEntity.hash == hash(password) - } - - override suspend fun findByUserId(userId: Long): UserAuthenticationEntity { - return userAuthRepository.findByUserId(userId) ?: throw UserNotFoundException("$userId was not found") - } - - override suspend fun findByUsername(username: String): UserAuthenticationEntity { - val userEntity = userRepository.findByName(username) ?: throw UserNotFoundException("$username was not found") - return userAuthRepository.findByUserId(userEntity.id) - ?: throw UserNotFoundException("$username auth data was not found") - } - - override suspend fun createAccount(userEntity: UserAuthentication): UserAuthenticationEntity { - return userAuthRepository.create(userEntity) + return userEntity.password == hash(password) } private fun generateKeyPair(): KeyPair { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyServiceImpl.kt index 74525981..488b82cf 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyServiceImpl.kt @@ -1,12 +1,13 @@ package dev.usbharu.hideout.service.signature import dev.usbharu.hideout.plugins.KtorKeyMap +import dev.usbharu.hideout.repository.IUserRepository import dev.usbharu.hideout.service.IUserAuthService import io.ktor.http.* import tech.barbero.http.message.signing.HttpMessage import tech.barbero.http.message.signing.SignatureHeaderVerifier -class HttpSignatureVerifyServiceImpl(private val userAuthService: IUserAuthService) : HttpSignatureVerifyService { +class HttpSignatureVerifyServiceImpl(private val userAuthService: IUserRepository) : HttpSignatureVerifyService { override fun verify(headers: Headers): Boolean { val build = SignatureHeaderVerifier.builder().keyMap(KtorKeyMap(userAuthService)).build() return true; diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt index 035f3143..757c6ec7 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt @@ -1,28 +1,20 @@ package dev.usbharu.hideout.plugins import dev.usbharu.hideout.domain.model.User -import dev.usbharu.hideout.domain.model.UserAuthentication -import dev.usbharu.hideout.domain.model.UserAuthenticationEntity import dev.usbharu.hideout.domain.model.ap.JsonLd -import dev.usbharu.hideout.repository.IUserAuthRepository import dev.usbharu.hideout.repository.IUserRepository -import dev.usbharu.hideout.service.impl.UserAuthService -import dev.usbharu.hideout.service.impl.toPem import io.ktor.client.* import io.ktor.client.engine.mock.* import io.ktor.client.plugins.logging.* import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.Test -import java.security.KeyPairGenerator -import java.security.interfaces.RSAPrivateKey -import java.security.interfaces.RSAPublicKey import java.time.LocalDateTime class ActivityPubKtTest { @Test fun HttpSignTest(): Unit = runBlocking { - val ktorKeyMap = KtorKeyMap(UserAuthService(object : IUserRepository { + val ktorKeyMap = KtorKeyMap(object : IUserRepository { override suspend fun create(user: User): User { TODO("Not yet implemented") } @@ -92,33 +84,7 @@ class ActivityPubKtTest { TODO("Not yet implemented") } - }, object : IUserAuthRepository { - override suspend fun create(userAuthentication: UserAuthentication): UserAuthenticationEntity { - TODO("Not yet implemented") - } - - override suspend fun findById(id: Long): UserAuthenticationEntity? { - TODO("Not yet implemented") - } - - override suspend fun update(userAuthenticationEntity: UserAuthenticationEntity) { - TODO("Not yet implemented") - } - - override suspend fun delete(id: Long) { - TODO("Not yet implemented") - } - - override suspend fun findByUserId(id: Long): UserAuthenticationEntity? { - val keyPairGenerator = KeyPairGenerator.getInstance("RSA") - keyPairGenerator.initialize(1024) - val generateKeyPair = keyPairGenerator.generateKeyPair() - return UserAuthenticationEntity( - 1, 1, "test", (generateKeyPair.public as RSAPublicKey).toPem(), - (generateKeyPair.private as RSAPrivateKey).toPem() - ) - } - })) + }) val httpClient = HttpClient(MockEngine { httpRequestData -> respondOk() diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt index edaeaff3..9da97821 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt @@ -1,23 +1,15 @@ package dev.usbharu.hideout.plugins import dev.usbharu.hideout.domain.model.User -import dev.usbharu.hideout.domain.model.UserAuthentication -import dev.usbharu.hideout.domain.model.UserAuthenticationEntity -import dev.usbharu.hideout.repository.IUserAuthRepository import dev.usbharu.hideout.repository.IUserRepository -import dev.usbharu.hideout.service.impl.UserAuthService -import dev.usbharu.hideout.service.impl.toPem import org.junit.jupiter.api.Test -import java.security.KeyPairGenerator -import java.security.interfaces.RSAPrivateKey -import java.security.interfaces.RSAPublicKey import java.time.LocalDateTime class KtorKeyMapTest { @Test fun getPrivateKey() { - val ktorKeyMap = KtorKeyMap(UserAuthService(object : IUserRepository { + val ktorKeyMap = KtorKeyMap(object : IUserRepository { override suspend fun create(user: User): User { TODO("Not yet implemented") } @@ -86,33 +78,7 @@ class KtorKeyMapTest { TODO("Not yet implemented") } - }, object : IUserAuthRepository { - override suspend fun create(userAuthentication: UserAuthentication): UserAuthenticationEntity { - TODO("Not yet implemented") - } - - override suspend fun findById(id: Long): UserAuthenticationEntity? { - TODO("Not yet implemented") - } - - override suspend fun update(userAuthenticationEntity: UserAuthenticationEntity) { - TODO("Not yet implemented") - } - - override suspend fun delete(id: Long) { - TODO("Not yet implemented") - } - - override suspend fun findByUserId(id: Long): UserAuthenticationEntity? { - val keyPairGenerator = KeyPairGenerator.getInstance("RSA") - keyPairGenerator.initialize(1024) - val generateKeyPair = keyPairGenerator.generateKeyPair() - return UserAuthenticationEntity( - 1, 1, "test", (generateKeyPair.public as RSAPublicKey).toPem(), - (generateKeyPair.private as RSAPrivateKey).toPem() - ) - } - })) + }) ktorKeyMap.getPrivateKey("test") } From cb36a388b154f5e040ea1bfe9b1eea1f251d029c Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 26 Apr 2023 17:55:24 +0900 Subject: [PATCH 05/45] =?UTF-8?q?feat:=20LocalDateTime=E3=81=8B=E3=82=89In?= =?UTF-8?q?stant=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/domain/model/User.kt | 12 ++-- .../hideout/repository/UserRepository.kt | 20 ++++-- .../activitypub/ActivityPubUserServiceImpl.kt | 3 +- .../hideout/service/impl/UserAuthService.kt | 7 +- .../hideout/plugins/ActivityPubKtTest.kt | 12 +++- .../usbharu/hideout/plugins/KtorKeyMapTest.kt | 11 ++- .../hideout/repository/UserRepositoryTest.kt | 72 ++++++++++++------- .../ActivityPubFollowServiceImplTest.kt | 5 +- .../ActivityPubNoteServiceImplTest.kt | 8 +-- 9 files changed, 99 insertions(+), 51 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt index ee46667a..3f54f7bb 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt @@ -1,18 +1,18 @@ package dev.usbharu.hideout.domain.model -import java.time.LocalDateTime +import java.time.Instant data class User( - val id:Long, + val id: Long, val name: String, val domain: String, val screenName: String, val description: String, - val password:String? = null, + val password: String? = null, val inbox: String, val outbox: String, val url: String, - val publicKey:String, - val privateKey:String? = null, - val createdAt:LocalDateTime + val publicKey: String, + val privateKey: String? = null, + val createdAt: Instant ) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt index dd224212..7e0487b1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt @@ -9,6 +9,7 @@ import org.jetbrains.exposed.sql.transactions.transaction import java.time.Instant import java.time.LocalDateTime import java.time.ZoneId +import java.time.ZoneOffset class UserRepository(private val database: Database) : IUserRepository { init { @@ -28,13 +29,18 @@ class UserRepository(private val database: Database) : IUserRepository { override suspend fun create(user: User): User { return query { Users.insert { + it[id] = user.id it[name] = user.name it[domain] = user.domain it[screenName] = user.screenName it[description] = user.description + it[password] = user.password it[inbox] = user.inbox it[outbox] = user.outbox it[url] = user.url + it[createdAt] = user.createdAt.toEpochMilli() + it[publicKey] = user.publicKey + it[privateKey] = user.privateKey } return@query user } @@ -101,7 +107,7 @@ class UserRepository(private val database: Database) : IUserRepository { Users.innerJoin( otherTable = UsersFollowers, onColumn = { Users.id }, - otherColumn = { UsersFollowers.userId }) + otherColumn = { userId }) .innerJoin( otherTable = followers, @@ -114,9 +120,13 @@ class UserRepository(private val database: Database) : IUserRepository { followers.get(Users.domain), followers.get(Users.screenName), followers.get(Users.description), + followers.get(Users.password), followers.get(Users.inbox), followers.get(Users.outbox), - followers.get(Users.url) + followers.get(Users.url), + followers.get(Users.publicKey), + followers.get(Users.privateKey), + followers.get(Users.createdAt) ) .select { Users.id eq id } .map { @@ -132,7 +142,7 @@ class UserRepository(private val database: Database) : IUserRepository { url = it[followers[Users.url]], publicKey = it[followers[Users.publicKey]], privateKey = it[followers[Users.privateKey]], - createdAt = LocalDateTime.ofInstant(Instant.ofEpochMilli(it[followers[Users.createdAt]]), ZoneId.systemDefault()) + createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]) ) } } @@ -189,7 +199,7 @@ object Users : Table("users") { val outbox = varchar("outbox", length = 255).uniqueIndex() val url = varchar("url", length = 255).uniqueIndex() val publicKey = varchar("public_key", length = 10000) - val privateKey = varchar("private_key", length = 10000) + val privateKey = varchar("private_key", length = 10000).nullable() val createdAt = long("created_at") override val primaryKey: PrimaryKey = PrimaryKey(id) @@ -211,6 +221,6 @@ fun ResultRow.toUser(): User { this[Users.url], this[Users.publicKey], this[Users.privateKey], - LocalDateTime.ofInstant(Instant.ofEpochMilli((this[Users.createdAt])), ZoneId.systemDefault()) + Instant.ofEpochMilli((this[Users.createdAt])) ) } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt index 14d4cd11..11e855c0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt @@ -16,6 +16,7 @@ import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* import org.slf4j.LoggerFactory +import java.time.Instant import java.time.LocalDateTime class ActivityPubUserServiceImpl( @@ -99,7 +100,7 @@ class ActivityPubUserServiceImpl( outbox = person.outbox ?: throw IllegalActivityPubObjectException("outbox is null"), url = url, publicKey = person.publicKey?.publicKeyPem ?: throw IllegalActivityPubObjectException("publicKey is null"), - createdAt = LocalDateTime.now() + createdAt = Instant.now() ) ) person diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt index db6dccf7..08235238 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt @@ -9,6 +9,7 @@ import io.ktor.util.* import java.security.* import java.security.interfaces.RSAPrivateKey import java.security.interfaces.RSAPublicKey +import java.time.Instant import java.time.LocalDateTime import java.util.* @@ -40,7 +41,7 @@ class UserAuthService( outbox = "$url/outbox", url = url, publicKey = "", - createdAt = LocalDateTime.now(), + createdAt = Instant.now(), ) val createdUser = userRepository.create(registerUser) @@ -69,13 +70,13 @@ class UserAuthService( } } -public fun PublicKey.toPem(): String { +fun PublicKey.toPem(): String { return "-----BEGIN PUBLIC KEY-----\n" + Base64.getEncoder().encodeToString(encoded).chunked(64).joinToString("\n") + "\n-----END PUBLIC KEY-----\n" } -public fun PrivateKey.toPem(): String { +fun PrivateKey.toPem(): String { return "-----BEGIN PRIVATE KEY-----" + Base64.getEncoder().encodeToString(encoded).chunked(64).joinToString("\n") + "\n-----END PRIVATE KEY-----\n" diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt index 757c6ec7..87d91ca0 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt @@ -3,11 +3,14 @@ package dev.usbharu.hideout.plugins import dev.usbharu.hideout.domain.model.User import dev.usbharu.hideout.domain.model.ap.JsonLd import dev.usbharu.hideout.repository.IUserRepository +import dev.usbharu.hideout.service.impl.toPem import io.ktor.client.* import io.ktor.client.engine.mock.* import io.ktor.client.plugins.logging.* import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.Test +import java.security.KeyPairGenerator +import java.time.Instant import java.time.LocalDateTime class ActivityPubKtTest { @@ -27,7 +30,10 @@ class ActivityPubKtTest { TODO("Not yet implemented") } - override suspend fun findByName(name: String): User? { + override suspend fun findByName(name: String): User { + val keyPairGenerator = KeyPairGenerator.getInstance("RSA") + keyPairGenerator.initialize(1024) + val generateKeyPair = keyPairGenerator.generateKeyPair() return User( 1, "test", @@ -39,8 +45,8 @@ class ActivityPubKtTest { "", "", "", - null, - LocalDateTime.now() + generateKeyPair.private.toPem(), + Instant.now() ) } diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt index 9da97821..204f6c8c 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt @@ -2,7 +2,10 @@ package dev.usbharu.hideout.plugins import dev.usbharu.hideout.domain.model.User import dev.usbharu.hideout.repository.IUserRepository +import dev.usbharu.hideout.service.impl.toPem import org.junit.jupiter.api.Test +import java.security.KeyPairGenerator +import java.time.Instant import java.time.LocalDateTime class KtorKeyMapTest { @@ -22,7 +25,10 @@ class KtorKeyMapTest { TODO("Not yet implemented") } - override suspend fun findByName(name: String): User? { + override suspend fun findByName(name: String): User { + val keyPairGenerator = KeyPairGenerator.getInstance("RSA") + keyPairGenerator.initialize(1024) + val generateKeyPair = keyPairGenerator.generateKeyPair() return User( 1, "test", @@ -34,7 +40,8 @@ class KtorKeyMapTest { "", "", "", - createdAt = LocalDateTime.now() + generateKeyPair.private.toPem(), + createdAt = Instant.now() ) } diff --git a/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt b/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt index 54b6dc69..12f9162e 100644 --- a/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt @@ -14,6 +14,10 @@ import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions.assertIterableEquals import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test +import java.time.Clock +import java.time.Instant +import java.time.LocalDateTime +import java.time.ZoneId class UserRepositoryTest { @@ -43,35 +47,47 @@ class UserRepositoryTest { val userRepository = UserRepository(db) val user = userRepository.create( User( - "test", - "example.com", - "testUser", - "This user is test user.", - "https://example.com/inbox", - "https://example.com/outbox", - "https://example.com" + id = 0L, + name = "test", + domain = "example.com", + screenName = "testUser", + description = "This user is test user.", + password = "https://example.com/inbox", + inbox = "", + outbox = "https://example.com/outbox", + url = "https://example.com", + publicKey = "", + createdAt = Instant.now(Clock.tickMillis(ZoneId.systemDefault())) ) ) val follower = userRepository.create( User( - "follower", - "follower.example.com", - "followerUser", - "This user is follower user.", - "https://follower.example.com/inbox", - "https://follower.example.com/outbox", - "https://follower.example.com" + id = 1L, + name = "follower", + domain = "follower.example.com", + screenName = "followerUser", + description = "This user is follower user.", + password = "", + inbox = "https://follower.example.com/inbox", + outbox = "https://follower.example.com/outbox", + url = "https://follower.example.com", + publicKey = "", + createdAt = Instant.now(Clock.tickMillis(ZoneId.systemDefault())) ) ) val follower2 = userRepository.create( User( - "follower2", - "follower2.example.com", - "followerUser2", - "This user is follower user 2.", - "https://follower2.example.com/inbox", - "https://follower2.example.com/outbox", - "https://follower2.example.com" + id = 3L, + name = "follower2", + domain = "follower2.example.com", + screenName = "followerUser2", + description = "This user is follower user 2.", + password = "", + inbox = "https://follower2.example.com/inbox", + outbox = "https://follower2.example.com/outbox", + url = "https://follower2.example.com", + publicKey = "", + createdAt = Instant.now(Clock.tickMillis(ZoneId.systemDefault())) ) ) userRepository.createFollower(user.id, follower.id) @@ -86,25 +102,31 @@ class UserRepositoryTest { fun `createFollower フォロワー追加`() = runTest { val userRepository = UserRepository(db) val user = userRepository.create( - User( + User(0L, "test", "example.com", "testUser", "This user is test user.", "https://example.com/inbox", + "", "https://example.com/outbox", - "https://example.com" + "https://example.com", + publicKey = "", + createdAt = Instant.now() ) ) val follower = userRepository.create( - User( + User(1L, "follower", "follower.example.com", "followerUser", "This user is follower user.", + "", "https://follower.example.com/inbox", "https://follower.example.com/outbox", - "https://follower.example.com" + "https://follower.example.com", + publicKey = "", + createdAt = Instant.now() ) ) userRepository.createFollower(user.id, follower.id) diff --git a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt index 3de7494d..cb012e10 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt @@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.* import utils.JsonObjectMapper +import java.time.Instant import java.time.LocalDateTime class ActivityPubFollowServiceImplTest { @@ -99,7 +100,7 @@ class ActivityPubFollowServiceImplTest { outbox = "https://example.com/outbox", url = "https://example.com", publicKey = "", - createdAt = LocalDateTime.now() + createdAt = Instant.now() ), User( id = 2L, @@ -111,7 +112,7 @@ class ActivityPubFollowServiceImplTest { outbox = "https://follower.example.com/outbox", url = "https://follower.example.com", publicKey = "", - createdAt = LocalDateTime.now() + createdAt = Instant.now() ) ) onBlocking { addFollowers(any(), any()) } doReturn Unit diff --git a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt index a9445572..ec1fa5ee 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt @@ -20,7 +20,7 @@ import org.junit.jupiter.api.Test import org.mockito.Mockito.eq import org.mockito.kotlin.* import utils.JsonObjectMapper -import java.time.LocalDateTime +import java.time.Instant import kotlin.test.assertEquals class ActivityPubNoteServiceImplTest { @@ -38,7 +38,7 @@ class ActivityPubNoteServiceImplTest { "https://follower.example.com", "", publicKey = "", - createdAt = LocalDateTime.now() + createdAt = Instant.now() ), User( 3L, @@ -51,7 +51,7 @@ class ActivityPubNoteServiceImplTest { "https://follower2.example.com", "", publicKey = "", - createdAt = LocalDateTime.now() + createdAt = Instant.now() ) ) val userService = mock<UserService> { @@ -66,7 +66,7 @@ class ActivityPubNoteServiceImplTest { "https:.//example.com", "", publicKey = "", - createdAt = LocalDateTime.now() + createdAt = Instant.now() ) onBlocking { findFollowersById(eq(1L)) } doReturn followers } From e5c353bc46efcd37f7e631aa6f75acaca492b70a Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 26 Apr 2023 17:55:45 +0900 Subject: [PATCH 06/45] =?UTF-8?q?style:=20=E3=82=B3=E3=83=BC=E3=83=89?= =?UTF-8?q?=E3=82=92=E6=95=B4=E5=BD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/domain/model/Posts.kt | 4 ++-- .../hideout/domain/model/UsersFollowers.kt | 1 + .../usbharu/hideout/domain/model/ap/Accept.kt | 7 ++++--- .../usbharu/hideout/domain/model/ap/Create.kt | 4 ++-- .../usbharu/hideout/domain/model/ap/Follow.kt | 7 ++++--- .../usbharu/hideout/domain/model/ap/Image.kt | 2 +- .../usbharu/hideout/domain/model/ap/JsonLd.kt | 19 +++++++++++-------- .../usbharu/hideout/domain/model/ap/Key.kt | 9 +++++---- .../usbharu/hideout/domain/model/ap/Note.kt | 13 +++++++------ .../usbharu/hideout/domain/model/ap/Object.kt | 4 ++-- .../usbharu/hideout/domain/model/ap/Person.kt | 17 +++++++++-------- .../hideout/domain/model/api/Status.kt | 4 ++-- .../hideout/domain/model/job/HideoutJob.kt | 4 ++-- .../domain/model/wellknown/WebFinger.kt | 4 ++-- .../usbharu/hideout/plugins/ActivityPub.kt | 6 +++--- .../dev/usbharu/hideout/plugins/HTTP.kt | 2 +- .../dev/usbharu/hideout/plugins/Monitoring.kt | 5 ++--- .../dev/usbharu/hideout/plugins/Routing.kt | 2 +- .../dev/usbharu/hideout/plugins/Security.kt | 2 -- .../usbharu/hideout/plugins/Serialization.kt | 4 ---- .../activitypub/ActivityPubServiceImpl.kt | 2 +- .../HttpSignatureVerifyServiceImpl.kt | 2 +- .../dev/usbharu/hideout/util/HttpUtil.kt | 6 +++++- .../kjob/exposed/ExposedJobRepository.kt | 1 - src/main/web/App.tsx | 2 +- src/main/web/index.html | 8 ++++---- 26 files changed, 73 insertions(+), 68 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/Posts.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/Posts.kt index d9e13915..56ae54a3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/Posts.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/Posts.kt @@ -29,7 +29,7 @@ data class Post( data class PostEntity( val id: Long, - val userId:Long, + val userId: Long, val overview: String? = null, val text: String, val createdAt: Long, @@ -39,7 +39,7 @@ data class PostEntity( val replyId: Long? = null ) -fun ResultRow.toPost():PostEntity{ +fun ResultRow.toPost(): PostEntity { return PostEntity( id = this[Posts.id], userId = this[Posts.userId], diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/UsersFollowers.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/UsersFollowers.kt index b5078c53..ede23ade 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/UsersFollowers.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/UsersFollowers.kt @@ -6,6 +6,7 @@ import org.jetbrains.exposed.dao.id.LongIdTable object UsersFollowers : LongIdTable("users_followers") { val userId = long("user_id").references(Users.id).index() val followerId = long("follower_id").references(Users.id) + init { uniqueIndex(userId, followerId) } diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Accept.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Accept.kt index 58889069..7b6d397a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Accept.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Accept.kt @@ -1,15 +1,16 @@ package dev.usbharu.hideout.domain.model.ap open class Accept : Object { - public var `object`: Object? = null - public var actor:String? = null + var `object`: Object? = null + var actor: String? = null + protected constructor() : super() constructor( type: List<String> = emptyList(), name: String, `object`: Object?, actor: String? - ) : super(add(type,"Accept"), name) { + ) : super(add(type, "Accept"), name) { this.`object` = `object` this.actor = actor } diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Create.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Create.kt index a0766fd6..46f89ec4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Create.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Create.kt @@ -1,10 +1,10 @@ package dev.usbharu.hideout.domain.model.ap open class Create : Object { - var `object` : Object? = null + var `object`: Object? = null protected constructor() : super() - constructor(type: List<String> = emptyList(), name: String, `object`: Object?) : super(add(type,"Create"), name) { + constructor(type: List<String> = emptyList(), name: String, `object`: Object?) : super(add(type, "Create"), name) { this.`object` = `object` } diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Follow.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Follow.kt index c73c85a3..9ed6e67a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Follow.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Follow.kt @@ -1,15 +1,16 @@ package dev.usbharu.hideout.domain.model.ap open class Follow : Object { - public var `object`:String? = null - public var actor:String? = null + var `object`: String? = null + var actor: String? = null + protected constructor() : super() constructor( type: List<String> = emptyList(), name: String, `object`: String?, actor: String? - ) : super(add(type,"Follow"), name) { + ) : super(add(type, "Follow"), name) { this.`object` = `object` this.actor = actor } diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Image.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Image.kt index 5767e7b7..5763366b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Image.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Image.kt @@ -6,7 +6,7 @@ open class Image : Object { protected constructor() : super() constructor(type: List<String> = emptyList(), name: String, mediaType: String?, url: String?) : super( - add(type,"Image"), + add(type, "Image"), name ) { this.mediaType = mediaType diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/JsonLd.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/JsonLd.kt index 4965814a..9700c9d0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/JsonLd.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/JsonLd.kt @@ -16,10 +16,10 @@ open class JsonLd { @JsonProperty("@context") @JsonDeserialize(contentUsing = ContextDeserializer::class) @JsonSerialize(using = ContextSerializer::class) - var context:List<String> = emptyList() + var context: List<String> = emptyList() @JsonCreator - constructor(context:List<String>){ + constructor(context: List<String>) { this.context = context } @@ -43,9 +43,12 @@ open class JsonLd { } -public class ContextDeserializer : JsonDeserializer<String>() { - override fun deserialize(p0: com.fasterxml.jackson.core.JsonParser?, p1: com.fasterxml.jackson.databind.DeserializationContext?): String { - val readTree : JsonNode = p0?.codec?.readTree(p0) ?: return "" +class ContextDeserializer : JsonDeserializer<String>() { + override fun deserialize( + p0: com.fasterxml.jackson.core.JsonParser?, + p1: com.fasterxml.jackson.databind.DeserializationContext? + ): String { + val readTree: JsonNode = p0?.codec?.readTree(p0) ?: return "" if (readTree.isObject) { return "" } @@ -53,17 +56,17 @@ public class ContextDeserializer : JsonDeserializer<String>() { } } -public class ContextSerializer : JsonSerializer<List<String>>() { +class ContextSerializer : JsonSerializer<List<String>>() { override fun serialize(value: List<String>?, gen: JsonGenerator?, serializers: SerializerProvider?) { if (value.isNullOrEmpty()) { gen?.writeNull() return } - if (value?.size == 1) { + if (value.size == 1) { gen?.writeString(value[0]) } else { gen?.writeStartArray() - value?.forEach { + value.forEach { gen?.writeString(it) } gen?.writeEndArray() diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Key.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Key.kt index ec79ace0..3b1f168a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Key.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Key.kt @@ -1,9 +1,10 @@ package dev.usbharu.hideout.domain.model.ap open class Key : Object { - var id:String? = null - var owner:String? = null - var publicKeyPem:String? = null + var id: String? = null + var owner: String? = null + var publicKeyPem: String? = null + protected constructor() : super() constructor( type: List<String>, @@ -11,7 +12,7 @@ open class Key : Object { id: String?, owner: String?, publicKeyPem: String? - ) : super(add(type,"Key"), name) { + ) : super(add(type, "Key"), name) { this.id = id this.owner = owner this.publicKeyPem = publicKeyPem diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Note.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Note.kt index caced1da..0250301c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Note.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Note.kt @@ -1,11 +1,12 @@ package dev.usbharu.hideout.domain.model.ap open class Note : Object { - var id:String? = null - var attributedTo:String? = null - var content:String? = null - var published:String? = null - var to:List<String> = emptyList() + var id: String? = null + var attributedTo: String? = null + var content: String? = null + var published: String? = null + var to: List<String> = emptyList() + protected constructor() : super() constructor( type: List<String> = emptyList(), @@ -15,7 +16,7 @@ open class Note : Object { content: String?, published: String?, to: List<String> = emptyList() - ) : super(add(type,"Note"), name) { + ) : super(add(type, "Note"), name) { this.id = id this.attributedTo = attributedTo this.content = content diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt index faca1cd4..e13d3eb5 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt @@ -18,7 +18,7 @@ open class Object : JsonLd { companion object { @JvmStatic - protected fun add(list:List<String>,type:String):List<String> { + protected fun add(list: List<String>, type: String): List<String> { val toMutableList = list.toMutableList() toMutableList.add(type) return toMutableList.distinct() @@ -46,7 +46,7 @@ open class Object : JsonLd { } -public class TypeSerializer : JsonSerializer<List<String>>() { +class TypeSerializer : JsonSerializer<List<String>>() { override fun serialize(value: List<String>?, gen: JsonGenerator?, serializers: SerializerProvider?) { println(value) if (value?.size == 1) { diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Person.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Person.kt index cc04bceb..6fecebc6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Person.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Person.kt @@ -1,14 +1,15 @@ package dev.usbharu.hideout.domain.model.ap open class Person : Object { - private var id:String? = null - var preferredUsername:String? = null - var summary:String? = null - var inbox:String? = null - var outbox:String? = null - private var url:String? = null + private var id: String? = null + var preferredUsername: String? = null + var summary: String? = null + var inbox: String? = null + var outbox: String? = null + private var url: String? = null private var icon: Image? = null var publicKey: Key? = null + protected constructor() : super() constructor( type: List<String> = emptyList(), @@ -21,7 +22,7 @@ open class Person : Object { url: String?, icon: Image?, publicKey: Key? - ) : super(add(type,"Person"), name) { + ) : super(add(type, "Person"), name) { this.id = id this.preferredUsername = preferredUsername this.summary = summary @@ -29,7 +30,7 @@ open class Person : Object { this.outbox = outbox this.url = url this.icon = icon - this.publicKey = publicKey + this.publicKey = publicKey } override fun equals(other: Any?): Boolean { diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/api/Status.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/api/Status.kt index e8e9bfe0..b89a0516 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/api/Status.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/api/Status.kt @@ -1,6 +1,6 @@ package dev.usbharu.hideout.domain.model.api data class StatusForPost( - val status:String, - val userId:Long + val status: String, + val userId: Long ) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/job/HideoutJob.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/job/HideoutJob.kt index 6bce8a95..e2d124ad 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/job/HideoutJob.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/job/HideoutJob.kt @@ -4,13 +4,13 @@ import kjob.core.Job sealed class HideoutJob(name: String = "") : Job(name) -object ReceiveFollowJob : HideoutJob("ReceiveFollowJob"){ +object ReceiveFollowJob : HideoutJob("ReceiveFollowJob") { val actor = string("actor") val follow = string("follow") val targetActor = string("targetActor") } -object DeliverPostJob : HideoutJob("DeliverPostJob"){ +object DeliverPostJob : HideoutJob("DeliverPostJob") { val post = string("post") val actor = string("actor") val inbox = string("inbox") diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/wellknown/WebFinger.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/wellknown/WebFinger.kt index b8542f23..01f0e645 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/wellknown/WebFinger.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/wellknown/WebFinger.kt @@ -1,5 +1,5 @@ package dev.usbharu.hideout.domain.model.wellknown -data class WebFinger(val subject:String,val links:List<Link>){ - data class Link(val rel:String,val type:String,val href:String) +data class WebFinger(val subject: String, val links: List<Link>) { + data class Link(val rel: String, val type: String, val href: String) } diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt index 50d4faaa..50313a58 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt @@ -63,8 +63,8 @@ val httpSignaturePlugin = createClientPlugin("HttpSign", ::HttpSignaturePluginCo println("Digest !!") // UserAuthService.sha256.reset() val digest = - Base64.getEncoder().encodeToString(UserAuthService.sha256.digest(body.toByteArray(Charsets.UTF_8))) - request.headers.append("Digest", "sha-256="+digest) + Base64.getEncoder().encodeToString(UserAuthService.sha256.digest(body.toByteArray(Charsets.UTF_8))) + request.headers.append("Digest", "sha-256=" + digest) } if (request.headers.contains("Signature")) { @@ -126,7 +126,7 @@ val httpSignaturePlugin = createClientPlugin("HttpSign", ::HttpSignaturePluginCo override fun addHeader(name: String?, value: String?) { val split = value?.split("=").orEmpty() - name?.let { request.header(it, split.get(0)+"=\""+split.get(1).trim('"')+"\"") } + name?.let { request.header(it, split.get(0) + "=\"" + split.get(1).trim('"') + "\"") } } override fun method(): String { diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/HTTP.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/HTTP.kt index c89f9289..234130ad 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/HTTP.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/HTTP.kt @@ -1,10 +1,10 @@ package dev.usbharu.hideout.plugins import io.ktor.http.* +import io.ktor.server.application.* import io.ktor.server.plugins.cors.routing.* import io.ktor.server.plugins.defaultheaders.* import io.ktor.server.plugins.forwardedheaders.* -import io.ktor.server.application.* fun Application.configureHTTP() { install(CORS) { diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Monitoring.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Monitoring.kt index 3ce065b7..2f33df7a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Monitoring.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Monitoring.kt @@ -1,9 +1,8 @@ package dev.usbharu.hideout.plugins -import io.ktor.server.plugins.callloging.* -import org.slf4j.event.* -import io.ktor.server.request.* import io.ktor.server.application.* +import io.ktor.server.plugins.callloging.* +import org.slf4j.event.Level fun Application.configureMonitoring() { install(CallLogging) { diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt index fc4f0742..8ae17d25 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt @@ -25,7 +25,7 @@ fun Application.configureRouting( routing { inbox(httpSignatureVerifyService, activityPubService) outbox() - usersAP(activityPubUserService,userService) + usersAP(activityPubUserService, userService) webfinger(userService) route("/api/v1") { diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Security.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Security.kt index 94485569..f8a9e2b3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Security.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Security.kt @@ -3,8 +3,6 @@ package dev.usbharu.hideout.plugins import dev.usbharu.hideout.service.IUserAuthService import io.ktor.server.application.* import io.ktor.server.auth.* -import io.ktor.server.sessions.* -import kotlin.collections.set data class UserSession(val username: String) : Principal diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Serialization.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Serialization.kt index c8b71a7d..09edfe72 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Serialization.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Serialization.kt @@ -4,13 +4,9 @@ import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonSetter import com.fasterxml.jackson.annotation.Nulls import com.fasterxml.jackson.databind.DeserializationFeature -import dev.usbharu.hideout.util.HttpUtil.Activity -import io.ktor.http.* import io.ktor.serialization.jackson.* import io.ktor.server.application.* import io.ktor.server.plugins.contentnegotiation.* -import io.ktor.server.response.* -import io.ktor.server.routing.* fun Application.configureSerialization() { install(ContentNegotiation) { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubServiceImpl.kt index e86f967f..320359d3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubServiceImpl.kt @@ -33,7 +33,7 @@ class ActivityPubServiceImpl( return ActivityType.values().first { it.name.equals(type.asText(), true) } } - override suspend fun processActivity(json: String, type: ActivityType): ActivityPubResponse? { + override suspend fun processActivity(json: String, type: ActivityType): ActivityPubResponse { return when (type) { ActivityType.Accept -> TODO() ActivityType.Add -> TODO() diff --git a/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyServiceImpl.kt index 488b82cf..5c74f11d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/signature/HttpSignatureVerifyServiceImpl.kt @@ -10,7 +10,7 @@ import tech.barbero.http.message.signing.SignatureHeaderVerifier class HttpSignatureVerifyServiceImpl(private val userAuthService: IUserRepository) : HttpSignatureVerifyService { override fun verify(headers: Headers): Boolean { val build = SignatureHeaderVerifier.builder().keyMap(KtorKeyMap(userAuthService)).build() - return true; + return true build.verify(object : HttpMessage { override fun headerValues(name: String?): MutableList<String> { return name?.let { headers.getAll(it) }?.toMutableList() ?: mutableListOf() diff --git a/src/main/kotlin/dev/usbharu/hideout/util/HttpUtil.kt b/src/main/kotlin/dev/usbharu/hideout/util/HttpUtil.kt index 979b8302..90773182 100644 --- a/src/main/kotlin/dev/usbharu/hideout/util/HttpUtil.kt +++ b/src/main/kotlin/dev/usbharu/hideout/util/HttpUtil.kt @@ -30,6 +30,10 @@ object HttpUtil { get() = ContentType("application", "activity+json") val ContentType.Application.JsonLd: ContentType - get() = ContentType("application", "ld+json", listOf(HeaderValueParam("profile", "https://www.w3.org/ns/activitystreams"))) + get() = ContentType( + "application", + "ld+json", + listOf(HeaderValueParam("profile", "https://www.w3.org/ns/activitystreams")) + ) // fun } diff --git a/src/main/kotlin/dev/usbharu/kjob/exposed/ExposedJobRepository.kt b/src/main/kotlin/dev/usbharu/kjob/exposed/ExposedJobRepository.kt index 6533358a..0c7f66dd 100644 --- a/src/main/kotlin/dev/usbharu/kjob/exposed/ExposedJobRepository.kt +++ b/src/main/kotlin/dev/usbharu/kjob/exposed/ExposedJobRepository.kt @@ -14,7 +14,6 @@ import org.jetbrains.exposed.dao.id.LongIdTable import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.SqlExpressionBuilder.inList -import org.jetbrains.exposed.sql.SqlExpressionBuilder.isNull import org.jetbrains.exposed.sql.SqlExpressionBuilder.plus import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction import org.jetbrains.exposed.sql.transactions.transaction diff --git a/src/main/web/App.tsx b/src/main/web/App.tsx index 32a849b2..d1b57e50 100644 --- a/src/main/web/App.tsx +++ b/src/main/web/App.tsx @@ -1,5 +1,5 @@ import {Component} from "solid-js"; -export const App:Component = () => { +export const App: Component = () => { return (<p>aaa</p>) } diff --git a/src/main/web/index.html b/src/main/web/index.html index 856bb5e6..46837b9c 100644 --- a/src/main/web/index.html +++ b/src/main/web/index.html @@ -1,10 +1,10 @@ <!DOCTYPE html> <html lang="en"> <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <meta name="theme-color" content="#000000" /> - <title>Solid App</title> + <meta charset="utf-8"/> + <meta content="width=device-width, initial-scale=1" name="viewport"/> + <meta content="#000000" name="theme-color"/> + <title>Solid App</title> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> From 71a608882992d080d3c2b3065e439f02b97d8b1e Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 11:00:58 +0900 Subject: [PATCH 07/45] =?UTF-8?q?refactor:=20update=E3=82=92=E9=9D=9E?= =?UTF-8?q?=E6=8E=A8=E5=A5=A8=E3=81=AB=E3=81=97=E3=81=A6create=E3=82=92sav?= =?UTF-8?q?e=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/repository/IUserRepository.kt | 5 +++-- .../dev/usbharu/hideout/repository/UserRepository.kt | 9 ++++----- .../usbharu/hideout/service/impl/UserAuthService.kt | 3 +-- .../dev/usbharu/hideout/service/impl/UserService.kt | 2 +- .../dev/usbharu/hideout/plugins/ActivityPubKtTest.kt | 2 +- .../dev/usbharu/hideout/plugins/KtorKeyMapTest.kt | 2 +- .../usbharu/hideout/repository/UserRepositoryTest.kt | 11 +++++------ 7 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt index 73ac26a4..c8a0b1a3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt @@ -3,7 +3,7 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.User interface IUserRepository { - suspend fun create(user: User): User + suspend fun save(user: User): User suspend fun findById(id: Long): User? @@ -17,7 +17,8 @@ interface IUserRepository { suspend fun findByUrls(urls: List<String>): List<User> - suspend fun update(userEntity: User) + @Deprecated("", ReplaceWith("save(userEntity)")) + suspend fun update(userEntity: User) = save(userEntity) suspend fun delete(id: Long) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt index 7e0487b1..a416ff5d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt @@ -1,15 +1,13 @@ package dev.usbharu.hideout.repository -import dev.usbharu.hideout.domain.model.* +import dev.usbharu.hideout.domain.model.User +import dev.usbharu.hideout.domain.model.UsersFollowers import kotlinx.coroutines.Dispatchers import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction import org.jetbrains.exposed.sql.transactions.transaction import java.time.Instant -import java.time.LocalDateTime -import java.time.ZoneId -import java.time.ZoneOffset class UserRepository(private val database: Database) : IUserRepository { init { @@ -21,12 +19,13 @@ class UserRepository(private val database: Database) : IUserRepository { } } + @Deprecated("", ReplaceWith("toUser()")) private fun ResultRow.toUserEntity(): User = toUser() suspend fun <T> query(block: suspend () -> T): T = newSuspendedTransaction(Dispatchers.IO) { block() } - override suspend fun create(user: User): User { + override suspend fun save(user: User): User { return query { Users.insert { it[id] = user.id diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt index 08235238..0d217de1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt @@ -10,7 +10,6 @@ import java.security.* import java.security.interfaces.RSAPrivateKey import java.security.interfaces.RSAPublicKey import java.time.Instant -import java.time.LocalDateTime import java.util.* class UserAuthService( @@ -43,7 +42,7 @@ class UserAuthService( publicKey = "", createdAt = Instant.now(), ) - val createdUser = userRepository.create(registerUser) + val createdUser = userRepository.save(registerUser) val keyPair = generateKeyPair() val privateKey = keyPair.private as RSAPrivateKey diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt index fcbc60cb..09af8fc4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt @@ -42,7 +42,7 @@ class UserService(private val userRepository: IUserRepository) { } suspend fun create(user: User): User { - return userRepository.create(user) + return userRepository.save(user) } suspend fun findFollowersById(id: Long): List<User> { diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt index 87d91ca0..df9265f0 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt @@ -18,7 +18,7 @@ class ActivityPubKtTest { fun HttpSignTest(): Unit = runBlocking { val ktorKeyMap = KtorKeyMap(object : IUserRepository { - override suspend fun create(user: User): User { + override suspend fun save(user: User): User { TODO("Not yet implemented") } diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt index 204f6c8c..fd3ee6dd 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt @@ -13,7 +13,7 @@ class KtorKeyMapTest { @Test fun getPrivateKey() { val ktorKeyMap = KtorKeyMap(object : IUserRepository { - override suspend fun create(user: User): User { + override suspend fun save(user: User): User { TODO("Not yet implemented") } diff --git a/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt b/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt index 12f9162e..4ddc8e9c 100644 --- a/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt @@ -16,7 +16,6 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import java.time.Clock import java.time.Instant -import java.time.LocalDateTime import java.time.ZoneId @@ -45,7 +44,7 @@ class UserRepositoryTest { @Test fun `findFollowersById フォロワー一覧を取得`() = runTest { val userRepository = UserRepository(db) - val user = userRepository.create( + val user = userRepository.save( User( id = 0L, name = "test", @@ -60,7 +59,7 @@ class UserRepositoryTest { createdAt = Instant.now(Clock.tickMillis(ZoneId.systemDefault())) ) ) - val follower = userRepository.create( + val follower = userRepository.save( User( id = 1L, name = "follower", @@ -75,7 +74,7 @@ class UserRepositoryTest { createdAt = Instant.now(Clock.tickMillis(ZoneId.systemDefault())) ) ) - val follower2 = userRepository.create( + val follower2 = userRepository.save( User( id = 3L, name = "follower2", @@ -101,7 +100,7 @@ class UserRepositoryTest { @Test fun `createFollower フォロワー追加`() = runTest { val userRepository = UserRepository(db) - val user = userRepository.create( + val user = userRepository.save( User(0L, "test", "example.com", @@ -115,7 +114,7 @@ class UserRepositoryTest { createdAt = Instant.now() ) ) - val follower = userRepository.create( + val follower = userRepository.save( User(1L, "follower", "follower.example.com", From 7bba9efddc4313b33442cca2990d3fc54e3c95d0 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 11:08:18 +0900 Subject: [PATCH 08/45] =?UTF-8?q?feat:=20save=E3=82=92insert=E3=81=8B?= =?UTF-8?q?=E3=82=89upsert=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/repository/UserRepository.kt | 75 ++++++++++--------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt index a416ff5d..f77c17ef 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt @@ -19,27 +19,41 @@ class UserRepository(private val database: Database) : IUserRepository { } } - @Deprecated("", ReplaceWith("toUser()")) - private fun ResultRow.toUserEntity(): User = toUser() - suspend fun <T> query(block: suspend () -> T): T = newSuspendedTransaction(Dispatchers.IO) { block() } override suspend fun save(user: User): User { return query { - Users.insert { - it[id] = user.id - it[name] = user.name - it[domain] = user.domain - it[screenName] = user.screenName - it[description] = user.description - it[password] = user.password - it[inbox] = user.inbox - it[outbox] = user.outbox - it[url] = user.url - it[createdAt] = user.createdAt.toEpochMilli() - it[publicKey] = user.publicKey - it[privateKey] = user.privateKey + val singleOrNull = Users.select { Users.id eq user.id }.singleOrNull() + if (singleOrNull == null) { + Users.insert { + it[id] = user.id + it[name] = user.name + it[domain] = user.domain + it[screenName] = user.screenName + it[description] = user.description + it[password] = user.password + it[inbox] = user.inbox + it[outbox] = user.outbox + it[url] = user.url + it[createdAt] = user.createdAt.toEpochMilli() + it[publicKey] = user.publicKey + it[privateKey] = user.privateKey + } + } else { + Users.update({ Users.id eq user.id }) { + it[name] = user.name + it[domain] = user.domain + it[screenName] = user.screenName + it[description] = user.description + it[password] = user.password + it[inbox] = user.inbox + it[outbox] = user.outbox + it[url] = user.url + it[createdAt] = user.createdAt.toEpochMilli() + it[publicKey] = user.publicKey + it[privateKey] = user.privateKey + } } return@query user } @@ -57,7 +71,7 @@ class UserRepository(private val database: Database) : IUserRepository { override suspend fun findById(id: Long): User? { return query { Users.select { Users.id eq id }.map { - it.toUserEntity() + it.toUser() }.singleOrNull() } } @@ -65,7 +79,7 @@ class UserRepository(private val database: Database) : IUserRepository { override suspend fun findByIds(ids: List<Long>): List<User> { return query { Users.select { Users.id inList ids }.map { - it.toUserEntity() + it.toUser() } } } @@ -73,7 +87,7 @@ class UserRepository(private val database: Database) : IUserRepository { override suspend fun findByName(name: String): User? { return query { Users.select { Users.name eq name }.map { - it.toUserEntity() + it.toUser() }.singleOrNull() } } @@ -84,19 +98,19 @@ class UserRepository(private val database: Database) : IUserRepository { names.forEach { (name, domain) -> selectAll.orWhere { Users.name eq name and (Users.domain eq domain) } } - selectAll.map { it.toUserEntity() } + selectAll.map { it.toUser() } } } override suspend fun findByUrl(url: String): User? { return query { - Users.select { Users.url eq url }.singleOrNull()?.toUserEntity() + Users.select { Users.url eq url }.singleOrNull()?.toUser() } } override suspend fun findByUrls(urls: List<String>): List<User> { return query { - Users.select { Users.url inList urls }.map { it.toUserEntity() } + Users.select { Users.url inList urls }.map { it.toUser() } } } @@ -148,20 +162,6 @@ class UserRepository(private val database: Database) : IUserRepository { } - override suspend fun update(userEntity: User) { - return query { - Users.update({ Users.id eq userEntity.id }) { - it[name] = userEntity.name - it[domain] = userEntity.domain - it[screenName] = userEntity.screenName - it[description] = userEntity.description - it[inbox] = userEntity.inbox - it[outbox] = userEntity.outbox - it[url] = userEntity.url - } - } - } - override suspend fun delete(id: Long) { query { Users.deleteWhere { Users.id.eq(id) } @@ -182,7 +182,7 @@ class UserRepository(private val database: Database) : IUserRepository { override suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long): List<User> { return query { - Users.selectAll().limit(limit, offset).map { it.toUserEntity() } + Users.selectAll().limit(limit, offset).map { it.toUser() } } } } @@ -202,6 +202,7 @@ object Users : Table("users") { val createdAt = long("created_at") override val primaryKey: PrimaryKey = PrimaryKey(id) + init { uniqueIndex(name, domain) } From ccfd3a62f613cf188ddc6eca43f85e38ee2a24ed Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 11:46:27 +0900 Subject: [PATCH 09/45] =?UTF-8?q?test:=20=E3=83=86=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt | 4 ---- src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt index df9265f0..f110cf35 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt @@ -62,10 +62,6 @@ class ActivityPubKtTest { TODO("Not yet implemented") } - override suspend fun update(userEntity: User) { - TODO("Not yet implemented") - } - override suspend fun delete(id: Long) { TODO("Not yet implemented") } diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt index fd3ee6dd..419a0ae4 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt @@ -57,10 +57,6 @@ class KtorKeyMapTest { TODO("Not yet implemented") } - override suspend fun update(userEntity: User) { - TODO("Not yet implemented") - } - override suspend fun delete(id: Long) { TODO("Not yet implemented") } From 7100c4e531c5c6287dbb67bec8fd7194407f95c5 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 11:57:18 +0900 Subject: [PATCH 10/45] =?UTF-8?q?feat:=20Repository=E3=81=ABID=E7=99=BA?= =?UTF-8?q?=E8=A1=8C=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/dev/usbharu/hideout/Application.kt | 6 ++++-- .../usbharu/hideout/repository/IUserRepository.kt | 2 ++ .../usbharu/hideout/repository/UserRepository.kt | 7 ++++++- .../dev/usbharu/hideout/plugins/KtorKeyMapTest.kt | 4 ++++ .../hideout/repository/UserRepositoryTest.kt | 13 +++++++++++-- 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/Application.kt b/src/main/kotlin/dev/usbharu/hideout/Application.kt index 149a839e..d5ecffdc 100644 --- a/src/main/kotlin/dev/usbharu/hideout/Application.kt +++ b/src/main/kotlin/dev/usbharu/hideout/Application.kt @@ -12,6 +12,7 @@ import dev.usbharu.hideout.repository.* import dev.usbharu.hideout.routing.register import dev.usbharu.hideout.service.IPostService import dev.usbharu.hideout.service.IUserAuthService +import dev.usbharu.hideout.service.IdGenerateService import dev.usbharu.hideout.service.TwitterSnowflakeIdGenerateService import dev.usbharu.hideout.service.activitypub.* import dev.usbharu.hideout.service.impl.PostService @@ -57,7 +58,7 @@ fun Application.parent() { ) } - single<IUserRepository> { UserRepository(get()) } + single<IUserRepository> { UserRepository(get(),get()) } single<IUserAuthService> { UserAuthService(get()) } single<HttpSignatureVerifyService> { HttpSignatureVerifyServiceImpl(get()) } single<JobQueueParentService> { @@ -82,7 +83,8 @@ fun Application.parent() { single<ActivityPubUserService> { ActivityPubUserServiceImpl(get(), get(), get()) } single<ActivityPubNoteService> { ActivityPubNoteServiceImpl(get(), get(), get()) } single<IPostService> { PostService(get(), get()) } - single<IPostRepository> { PostRepositoryImpl(get(), TwitterSnowflakeIdGenerateService) } + single<IPostRepository> { PostRepositoryImpl(get(), get()) } + single<IdGenerateService> {TwitterSnowflakeIdGenerateService} } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt index c8a0b1a3..58d56ba9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt @@ -29,4 +29,6 @@ interface IUserRepository { suspend fun createFollower(id: Long, follower: Long) suspend fun deleteFollower(id: Long, follower: Long) suspend fun findFollowersById(id: Long): List<User> + + suspend fun nextId():Long } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt index f77c17ef..ceb6db1b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt @@ -2,6 +2,7 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.User import dev.usbharu.hideout.domain.model.UsersFollowers +import dev.usbharu.hideout.service.IdGenerateService import kotlinx.coroutines.Dispatchers import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq @@ -9,7 +10,7 @@ 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) : IUserRepository { +class UserRepository(private val database: Database,private val idGenerateService: IdGenerateService) : IUserRepository { init { transaction(database) { SchemaUtils.create(Users) @@ -185,6 +186,10 @@ class UserRepository(private val database: Database) : IUserRepository { Users.selectAll().limit(limit, offset).map { it.toUser() } } } + + override suspend fun nextId(): Long { + return idGenerateService.generateId() + } } object Users : Table("users") { diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt index 419a0ae4..08a1bdac 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt @@ -81,6 +81,10 @@ class KtorKeyMapTest { TODO("Not yet implemented") } + override suspend fun nextId(): Long { + TODO("Not yet implemented") + } + }) ktorKeyMap.getPrivateKey("test") diff --git a/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt b/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt index 4ddc8e9c..43dc236e 100644 --- a/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt @@ -4,6 +4,7 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.User import dev.usbharu.hideout.domain.model.UsersFollowers +import dev.usbharu.hideout.service.IdGenerateService import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.jetbrains.exposed.sql.Database @@ -43,7 +44,11 @@ class UserRepositoryTest { @Test fun `findFollowersById フォロワー一覧を取得`() = runTest { - val userRepository = UserRepository(db) + val userRepository = UserRepository(db, object : IdGenerateService { + override suspend fun generateId(): Long { + TODO("Not yet implemented") + } + }) val user = userRepository.save( User( id = 0L, @@ -99,7 +104,11 @@ class UserRepositoryTest { @Test fun `createFollower フォロワー追加`() = runTest { - val userRepository = UserRepository(db) + val userRepository = UserRepository(db, object : IdGenerateService { + override suspend fun generateId(): Long { + TODO("Not yet implemented") + } + }) val user = userRepository.save( User(0L, "test", From f7beff3295ebb44a74036f640956b082eb7bfeb1 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 13:49:57 +0900 Subject: [PATCH 11/45] =?UTF-8?q?refactor:=20UsersFollowers=E3=82=92?= =?UTF-8?q?=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usbharu/hideout/domain/model/UsersFollowers.kt | 13 ------------- .../usbharu/hideout/repository/UserRepository.kt | 12 +++++++++++- .../hideout/repository/UserRepositoryTest.kt | 1 - 3 files changed, 11 insertions(+), 15 deletions(-) delete mode 100644 src/main/kotlin/dev/usbharu/hideout/domain/model/UsersFollowers.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/UsersFollowers.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/UsersFollowers.kt deleted file mode 100644 index ede23ade..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/UsersFollowers.kt +++ /dev/null @@ -1,13 +0,0 @@ -package dev.usbharu.hideout.domain.model - -import dev.usbharu.hideout.repository.Users -import org.jetbrains.exposed.dao.id.LongIdTable - -object UsersFollowers : LongIdTable("users_followers") { - val userId = long("user_id").references(Users.id).index() - val followerId = long("follower_id").references(Users.id) - - init { - uniqueIndex(userId, followerId) - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt index ceb6db1b..a1ff7791 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt @@ -1,9 +1,10 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.User -import dev.usbharu.hideout.domain.model.UsersFollowers +import dev.usbharu.hideout.repository.UsersFollowers import dev.usbharu.hideout.service.IdGenerateService import kotlinx.coroutines.Dispatchers +import org.jetbrains.exposed.dao.id.LongIdTable import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction @@ -229,3 +230,12 @@ fun ResultRow.toUser(): User { Instant.ofEpochMilli((this[Users.createdAt])) ) } + +object UsersFollowers : LongIdTable("users_followers") { + val userId = long("user_id").references(Users.id).index() + val followerId = long("follower_id").references(Users.id) + + init { + uniqueIndex(userId, followerId) + } +} diff --git a/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt b/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt index 43dc236e..a1c3bfeb 100644 --- a/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt @@ -3,7 +3,6 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.User -import dev.usbharu.hideout.domain.model.UsersFollowers import dev.usbharu.hideout.service.IdGenerateService import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest From e040f6c8118646e25225db35cb5a55803ca84766 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 13:51:48 +0900 Subject: [PATCH 12/45] =?UTF-8?q?refactor:=20UserAuthentication=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/model/UserAuthentication.kt | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt deleted file mode 100644 index 9dbd767f..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/UserAuthentication.kt +++ /dev/null @@ -1,21 +0,0 @@ -package dev.usbharu.hideout.domain.model - -import dev.usbharu.hideout.repository.Users -import org.jetbrains.exposed.dao.id.LongIdTable -import org.jetbrains.exposed.sql.ReferenceOption - -@Deprecated("") -data class UserAuthentication( - val userId: Long, - val hash: String?, - val publicKey: String, - val privateKey: String? -) - -@Deprecated("") -object UsersAuthentication : LongIdTable("users_auth") { - val userId = long("user_id").references(Users.id, onUpdate = ReferenceOption.CASCADE) - val hash = varchar("hash", length = 64).nullable() - val publicKey = varchar("public_key", length = 1000_000) - val privateKey = varchar("private_key", length = 1000_000).nullable() -} From 79205fc253f1d7e05dd2bcc1a81507bfe9ed601a Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 13:56:20 +0900 Subject: [PATCH 13/45] =?UTF-8?q?feat:=20UserCreateDto=E3=82=92=E4=BD=9C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/domain/model/hideout/dto/UserCreateDto.kt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/UserCreateDto.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/UserCreateDto.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/UserCreateDto.kt new file mode 100644 index 00000000..ddab1b2f --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/UserCreateDto.kt @@ -0,0 +1,9 @@ +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 +) From f77d1512341b9feee9ead7d619b9d126df9ff2ae Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 13:56:46 +0900 Subject: [PATCH 14/45] =?UTF-8?q?refactor:=20User=E3=82=92=E7=A7=BB?= =?UTF-8?q?=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usbharu/hideout/domain/model/{ => hideout/entity}/User.kt | 2 +- .../kotlin/dev/usbharu/hideout/repository/IUserRepository.kt | 2 +- .../kotlin/dev/usbharu/hideout/repository/UserRepository.kt | 3 +-- .../hideout/service/activitypub/ActivityPubUserServiceImpl.kt | 3 +-- .../kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt | 2 +- .../kotlin/dev/usbharu/hideout/service/impl/UserService.kt | 2 +- .../kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt | 3 +-- src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt | 3 +-- .../dev/usbharu/hideout/repository/UserRepositoryTest.kt | 2 +- .../service/activitypub/ActivityPubFollowServiceImplTest.kt | 3 +-- .../service/activitypub/ActivityPubNoteServiceImplTest.kt | 2 +- 11 files changed, 11 insertions(+), 16 deletions(-) rename src/main/kotlin/dev/usbharu/hideout/domain/model/{ => hideout/entity}/User.kt (86%) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt similarity index 86% rename from src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt rename to src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt index 3f54f7bb..319d1f8c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/User.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt @@ -1,4 +1,4 @@ -package dev.usbharu.hideout.domain.model +package dev.usbharu.hideout.domain.model.hideout.entity import java.time.Instant diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt index 58d56ba9..1f198526 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt @@ -1,6 +1,6 @@ package dev.usbharu.hideout.repository -import dev.usbharu.hideout.domain.model.User +import dev.usbharu.hideout.domain.model.hideout.entity.User interface IUserRepository { suspend fun save(user: User): User diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt index a1ff7791..8ab5cce7 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt @@ -1,7 +1,6 @@ package dev.usbharu.hideout.repository -import dev.usbharu.hideout.domain.model.User -import dev.usbharu.hideout.repository.UsersFollowers +import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.service.IdGenerateService import kotlinx.coroutines.Dispatchers import org.jetbrains.exposed.dao.id.LongIdTable diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt index 11e855c0..71e10238 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt @@ -2,7 +2,7 @@ package dev.usbharu.hideout.service.activitypub import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.config.Config -import dev.usbharu.hideout.domain.model.User +import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.domain.model.ap.Image import dev.usbharu.hideout.domain.model.ap.Key import dev.usbharu.hideout.domain.model.ap.Person @@ -17,7 +17,6 @@ import io.ktor.client.statement.* import io.ktor.http.* import org.slf4j.LoggerFactory import java.time.Instant -import java.time.LocalDateTime class ActivityPubUserServiceImpl( private val userService: UserService, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt index 0d217de1..cd2d6ccb 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt @@ -1,7 +1,7 @@ package dev.usbharu.hideout.service.impl import dev.usbharu.hideout.config.Config -import dev.usbharu.hideout.domain.model.User +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 diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt index 09af8fc4..7c426341 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt @@ -1,6 +1,6 @@ package dev.usbharu.hideout.service.impl -import dev.usbharu.hideout.domain.model.User +import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.exception.UserNotFoundException import dev.usbharu.hideout.repository.IUserRepository import java.lang.Integer.min diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt index f110cf35..de740d9a 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt @@ -1,6 +1,6 @@ package dev.usbharu.hideout.plugins -import dev.usbharu.hideout.domain.model.User +import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.domain.model.ap.JsonLd import dev.usbharu.hideout.repository.IUserRepository import dev.usbharu.hideout.service.impl.toPem @@ -11,7 +11,6 @@ import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.Test import java.security.KeyPairGenerator import java.time.Instant -import java.time.LocalDateTime class ActivityPubKtTest { @Test diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt index 08a1bdac..331e7b5e 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt @@ -1,12 +1,11 @@ package dev.usbharu.hideout.plugins -import dev.usbharu.hideout.domain.model.User +import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.repository.IUserRepository import dev.usbharu.hideout.service.impl.toPem import org.junit.jupiter.api.Test import java.security.KeyPairGenerator import java.time.Instant -import java.time.LocalDateTime class KtorKeyMapTest { diff --git a/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt b/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt index a1c3bfeb..36bbcf4d 100644 --- a/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/repository/UserRepositoryTest.kt @@ -2,7 +2,7 @@ package dev.usbharu.hideout.repository -import dev.usbharu.hideout.domain.model.User +import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.service.IdGenerateService import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest diff --git a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt index cb012e10..c50749f1 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt @@ -6,7 +6,7 @@ package dev.usbharu.hideout.service.activitypub import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.config.ConfigData -import dev.usbharu.hideout.domain.model.User +import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.domain.model.ap.* import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob import dev.usbharu.hideout.service.impl.UserService @@ -24,7 +24,6 @@ import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.* import utils.JsonObjectMapper import java.time.Instant -import java.time.LocalDateTime class ActivityPubFollowServiceImplTest { @Test diff --git a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt index ec1fa5ee..a0a85f3c 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt @@ -6,7 +6,7 @@ package dev.usbharu.hideout.service.activitypub import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.config.ConfigData import dev.usbharu.hideout.domain.model.PostEntity -import dev.usbharu.hideout.domain.model.User +import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.domain.model.job.DeliverPostJob import dev.usbharu.hideout.service.impl.UserService import dev.usbharu.hideout.service.job.JobQueueParentService From 48411751dec61457a8fd857973bb11de526bf44f Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 15:04:59 +0900 Subject: [PATCH 15/45] =?UTF-8?q?refactor:=20=E4=B8=80=E9=83=A8=E3=81=AE?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E3=82=92=E5=A4=89=E6=9B=B4=E3=80=82=E3=83=A6?= =?UTF-8?q?=E3=83=BC=E3=82=B6=E3=83=BC=E3=82=92=E4=BD=9C=E6=88=90=E3=81=A7?= =?UTF-8?q?=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/dev/usbharu/hideout/Application.kt | 4 +- .../domain/model/hideout/dto/UserCreateDto.kt | 1 - .../usbharu/hideout/plugins/ActivityPub.kt | 8 ++-- .../hideout/repository/IUserRepository.kt | 6 ++- .../hideout/repository/UserRepository.kt | 21 ++++++++-- .../hideout/routing/RegisterRouting.kt | 14 +++---- .../routing/activitypub/UserRouting.kt | 3 +- .../routing/wellknown/WebfingerRouting.kt | 2 +- .../hideout/service/IUserAuthService.kt | 5 ++- .../activitypub/ActivityPubUserServiceImpl.kt | 2 +- .../hideout/service/impl/UserAuthService.kt | 32 +-------------- .../hideout/service/impl/UserService.kt | 41 +++++++++++++++++-- 12 files changed, 82 insertions(+), 57 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/Application.kt b/src/main/kotlin/dev/usbharu/hideout/Application.kt index d5ecffdc..487dcb65 100644 --- a/src/main/kotlin/dev/usbharu/hideout/Application.kt +++ b/src/main/kotlin/dev/usbharu/hideout/Application.kt @@ -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, diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/UserCreateDto.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/UserCreateDto.kt index ddab1b2f..e8a59f26 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/UserCreateDto.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/UserCreateDto.kt @@ -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 diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt index 50313a58..cbb6cab4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt @@ -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", "") ) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt index 1f198526..0d19094f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/IUserRepository.kt @@ -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> diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt index 8ab5cce7..9a577a83 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt @@ -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() + } } } diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/RegisterRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/RegisterRouting.kt index a6ba6d4c..b0e2f47e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/RegisterRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/RegisterRouting.kt @@ -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") } } diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt index 66fc511c..d25fca2a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt @@ -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)) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/wellknown/WebfingerRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/wellknown/WebfingerRouting.kt index f862f745..36948523 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/wellknown/WebfingerRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/wellknown/WebfingerRouting.kt @@ -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, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/IUserAuthService.kt b/src/main/kotlin/dev/usbharu/hideout/service/IUserAuthService.kt index 1702c41b..5c792ec8 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/IUserAuthService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/IUserAuthService.kt @@ -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 diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt index 71e10238..57d73d39 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt @@ -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(), diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt index cd2d6ccb..41a38a41 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt @@ -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() diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt index 7c426341..c67d8ecf 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt @@ -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) } From 6d2999452a8723b96301d872764eaa4321692492 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 15:28:30 +0900 Subject: [PATCH 16/45] =?UTF-8?q?refactor:=20=E4=B8=8D=E8=A6=81=E3=81=AA?= =?UTF-8?q?=E3=83=95=E3=82=A3=E3=83=BC=E3=83=AB=E3=83=89=E3=82=92=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/dev/usbharu/hideout/Application.kt | 2 +- .../hideout/service/activitypub/ActivityPubUserServiceImpl.kt | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/Application.kt b/src/main/kotlin/dev/usbharu/hideout/Application.kt index 487dcb65..baeec6e5 100644 --- a/src/main/kotlin/dev/usbharu/hideout/Application.kt +++ b/src/main/kotlin/dev/usbharu/hideout/Application.kt @@ -80,7 +80,7 @@ fun Application.parent() { single<ActivityPubFollowService> { ActivityPubFollowServiceImpl(get(), get(), get(), get()) } single<ActivityPubService> { ActivityPubServiceImpl(get(), get()) } single<UserService> { UserService(get(),get()) } - single<ActivityPubUserService> { ActivityPubUserServiceImpl(get(), get(), get()) } + single<ActivityPubUserService> { ActivityPubUserServiceImpl(get(), get()) } single<ActivityPubNoteService> { ActivityPubNoteServiceImpl(get(), get(), get()) } single<IPostService> { PostService(get(), get()) } single<IPostRepository> { PostRepositoryImpl(get(), get()) } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt index 57d73d39..014f3ffa 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt @@ -8,7 +8,6 @@ import dev.usbharu.hideout.domain.model.ap.Key import dev.usbharu.hideout.domain.model.ap.Person import dev.usbharu.hideout.exception.UserNotFoundException import dev.usbharu.hideout.exception.ap.IllegalActivityPubObjectException -import dev.usbharu.hideout.service.IUserAuthService import dev.usbharu.hideout.service.impl.UserService import dev.usbharu.hideout.util.HttpUtil.Activity import io.ktor.client.* @@ -20,7 +19,6 @@ import java.time.Instant class ActivityPubUserServiceImpl( private val userService: UserService, - private val userAuthService: IUserAuthService, private val httpClient: HttpClient ) : ActivityPubUserService { From 943b09a3a59cdbae361d2ab14ce3782161e21f6f Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 15:41:31 +0900 Subject: [PATCH 17/45] =?UTF-8?q?feat:=20=E3=83=AA=E3=83=A2=E3=83=BC?= =?UTF-8?q?=E3=83=88=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E3=81=AE=E4=BD=9C?= =?UTF-8?q?=E6=88=90=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/hideout/dto/RemoteUserCreateDto.kt | 12 ++++++++++ .../activitypub/ActivityPubUserServiceImpl.kt | 10 ++++---- .../hideout/service/impl/UserService.kt | 23 +++++++++++++++---- 3 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/RemoteUserCreateDto.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/RemoteUserCreateDto.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/RemoteUserCreateDto.kt new file mode 100644 index 00000000..35081932 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/RemoteUserCreateDto.kt @@ -0,0 +1,12 @@ +package dev.usbharu.hideout.domain.model.hideout.dto + +data class RemoteUserCreateDto( + val name:String, + val domain:String, + val screenName:String, + val description:String, + val inbox:String, + val outbox:String, + val url:String, + val publicKey:String, +) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt index 014f3ffa..318cff08 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt @@ -2,10 +2,10 @@ package dev.usbharu.hideout.service.activitypub import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.config.Config -import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.domain.model.ap.Image import dev.usbharu.hideout.domain.model.ap.Key import dev.usbharu.hideout.domain.model.ap.Person +import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto import dev.usbharu.hideout.exception.UserNotFoundException import dev.usbharu.hideout.exception.ap.IllegalActivityPubObjectException import dev.usbharu.hideout.service.impl.UserService @@ -15,7 +15,6 @@ import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* import org.slf4j.LoggerFactory -import java.time.Instant class ActivityPubUserServiceImpl( private val userService: UserService, @@ -85,9 +84,9 @@ class ActivityPubUserServiceImpl( accept(ContentType.Application.Activity) } val person = Config.configData.objectMapper.readValue<Person>(httpResponse.bodyAsText()) - userService.create( - User( - id = 0L, + + userService.createRemoteUser( + RemoteUserCreateDto( name = person.preferredUsername ?: throw IllegalActivityPubObjectException("preferredUsername is null"), domain = url.substringAfter(":").substringBeforeLast("/"), @@ -97,7 +96,6 @@ class ActivityPubUserServiceImpl( outbox = person.outbox ?: throw IllegalActivityPubObjectException("outbox is null"), url = url, publicKey = person.publicKey?.publicKeyPem ?: throw IllegalActivityPubObjectException("publicKey is null"), - createdAt = Instant.now() ) ) person diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt index c67d8ecf..8e0f0f06 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt @@ -1,6 +1,7 @@ package dev.usbharu.hideout.service.impl import dev.usbharu.hideout.config.Config +import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.exception.UserNotFoundException @@ -54,11 +55,6 @@ class UserService(private val userRepository: IUserRepository, private val userA 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) @@ -80,6 +76,23 @@ class UserService(private val userRepository: IUserRepository, private val userA return userRepository.save(userEntity) } + suspend fun createRemoteUser(user: RemoteUserCreateDto): User { + val nextId = userRepository.nextId() + val userEntity = User( + id = nextId, + name = user.name, + domain = user.domain, + screenName = user.screenName, + description = user.description, + inbox = user.inbox, + outbox = user.outbox, + url = user.url, + publicKey = user.publicKey, + createdAt = Instant.now() + ) + return userRepository.save(userEntity) + } + suspend fun findFollowersById(id: Long): List<User> { return userRepository.findFollowersById(id) } From b21e658cd00c5c76fb61ad9f014980003ee47e79 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 16:00:01 +0900 Subject: [PATCH 18/45] =?UTF-8?q?refactor:=20UserService=E3=82=92=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E3=82=BF=E3=83=BC=E3=83=95=E3=82=A7=E3=83=BC=E3=82=B9?= =?UTF-8?q?=E3=81=AB=E6=8A=BD=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/dev/usbharu/hideout/Application.kt | 12 ++++--- .../dev/usbharu/hideout/plugins/Routing.kt | 4 +-- .../hideout/routing/RegisterRouting.kt | 4 +-- .../routing/activitypub/UserRouting.kt | 5 ++- .../routing/wellknown/WebfingerRouting.kt | 4 +-- .../ActivityPubFollowServiceImpl.kt | 8 ++--- .../activitypub/ActivityPubNoteServiceImpl.kt | 4 +-- .../activitypub/ActivityPubUserServiceImpl.kt | 4 +-- .../hideout/service/impl/IUserService.kt | 33 +++++++++++++++++++ .../hideout/service/impl/UserService.kt | 29 ++++++++-------- .../hideout/plugins/ActivityPubKtTest.kt | 16 +++++++-- .../usbharu/hideout/plugins/KtorKeyMapTest.kt | 11 ++++++- .../routing/activitypub/InboxRoutingKtTest.kt | 5 +-- .../routing/activitypub/UsersAPTest.kt | 3 +- .../ActivityPubFollowServiceImplTest.kt | 6 ++-- .../ActivityPubNoteServiceImplTest.kt | 4 +-- 16 files changed, 106 insertions(+), 46 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/impl/IUserService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/Application.kt b/src/main/kotlin/dev/usbharu/hideout/Application.kt index baeec6e5..3fe5d5a1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/Application.kt +++ b/src/main/kotlin/dev/usbharu/hideout/Application.kt @@ -8,13 +8,17 @@ import dev.usbharu.hideout.config.ConfigData import dev.usbharu.hideout.domain.model.job.DeliverPostJob import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob import dev.usbharu.hideout.plugins.* -import dev.usbharu.hideout.repository.* +import dev.usbharu.hideout.repository.IPostRepository +import dev.usbharu.hideout.repository.IUserRepository +import dev.usbharu.hideout.repository.PostRepositoryImpl +import dev.usbharu.hideout.repository.UserRepository import dev.usbharu.hideout.routing.register import dev.usbharu.hideout.service.IPostService import dev.usbharu.hideout.service.IUserAuthService import dev.usbharu.hideout.service.IdGenerateService import dev.usbharu.hideout.service.TwitterSnowflakeIdGenerateService import dev.usbharu.hideout.service.activitypub.* +import dev.usbharu.hideout.service.impl.IUserService import dev.usbharu.hideout.service.impl.PostService import dev.usbharu.hideout.service.impl.UserAuthService import dev.usbharu.hideout.service.impl.UserService @@ -79,7 +83,7 @@ fun Application.parent() { } single<ActivityPubFollowService> { ActivityPubFollowServiceImpl(get(), get(), get(), get()) } single<ActivityPubService> { ActivityPubServiceImpl(get(), get()) } - single<UserService> { UserService(get(),get()) } + single<IUserService> { UserService(get(),get()) } single<ActivityPubUserService> { ActivityPubUserServiceImpl(get(), get()) } single<ActivityPubNoteService> { ActivityPubNoteServiceImpl(get(), get(), get()) } single<IPostService> { PostService(get(), get()) } @@ -93,11 +97,11 @@ fun Application.parent() { configureStaticRouting() configureMonitoring() configureSerialization() - register(inject<UserService>().value) + register(inject<IUserService>().value) configureRouting( inject<HttpSignatureVerifyService>().value, inject<ActivityPubService>().value, - inject<UserService>().value, + inject<IUserService>().value, inject<ActivityPubUserService>().value, inject<IPostService>().value ) diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt index 8ae17d25..f6bebf53 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt @@ -8,7 +8,7 @@ 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.ActivityPubUserService -import dev.usbharu.hideout.service.impl.UserService +import dev.usbharu.hideout.service.impl.IUserService import dev.usbharu.hideout.service.signature.HttpSignatureVerifyService import io.ktor.server.application.* import io.ktor.server.plugins.autohead.* @@ -17,7 +17,7 @@ import io.ktor.server.routing.* fun Application.configureRouting( httpSignatureVerifyService: HttpSignatureVerifyService, activityPubService: ActivityPubService, - userService: UserService, + userService: IUserService, activityPubUserService: ActivityPubUserService, postService: IPostService ) { diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/RegisterRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/RegisterRouting.kt index b0e2f47e..c20221cc 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/RegisterRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/RegisterRouting.kt @@ -1,7 +1,7 @@ package dev.usbharu.hideout.routing import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto -import dev.usbharu.hideout.service.impl.UserService +import dev.usbharu.hideout.service.impl.IUserService import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.auth.* @@ -9,7 +9,7 @@ import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* -fun Application.register(userService: UserService) { +fun Application.register(userService: IUserService) { routing { get("/register") { diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt index d25fca2a..95b22635 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt @@ -1,10 +1,9 @@ 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 -import dev.usbharu.hideout.service.impl.UserService +import dev.usbharu.hideout.service.impl.IUserService import dev.usbharu.hideout.util.HttpUtil.Activity import dev.usbharu.hideout.util.HttpUtil.JsonLd import io.ktor.http.* @@ -13,7 +12,7 @@ import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* -fun Routing.usersAP(activityPubUserService: ActivityPubUserService, userService: UserService) { +fun Routing.usersAP(activityPubUserService: ActivityPubUserService, userService: IUserService) { route("/users/{name}") { createChild(ContentTypeRouteSelector(ContentType.Application.Activity, ContentType.Application.JsonLd)).handle { val name = diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/wellknown/WebfingerRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/wellknown/WebfingerRouting.kt index 36948523..411e3095 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/wellknown/WebfingerRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/wellknown/WebfingerRouting.kt @@ -4,14 +4,14 @@ import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.domain.model.wellknown.WebFinger import dev.usbharu.hideout.exception.IllegalParameterException import dev.usbharu.hideout.exception.ParameterNotExistException -import dev.usbharu.hideout.service.impl.UserService +import dev.usbharu.hideout.service.impl.IUserService import dev.usbharu.hideout.util.HttpUtil.Activity import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.response.* import io.ktor.server.routing.* -fun Routing.webfinger(userService:UserService){ +fun Routing.webfinger(userService: IUserService){ route("/.well-known/webfinger"){ get { val acct = call.request.queryParameters["resource"]?.decodeURLPart() diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImpl.kt index b734aba1..fcd94662 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImpl.kt @@ -1,14 +1,14 @@ package dev.usbharu.hideout.service.activitypub import com.fasterxml.jackson.module.kotlin.readValue -import dev.usbharu.hideout.domain.model.ap.Accept -import dev.usbharu.hideout.domain.model.ap.Follow import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.domain.model.ActivityPubResponse import dev.usbharu.hideout.domain.model.ActivityPubStringResponse +import dev.usbharu.hideout.domain.model.ap.Accept +import dev.usbharu.hideout.domain.model.ap.Follow import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob import dev.usbharu.hideout.plugins.postAp -import dev.usbharu.hideout.service.impl.UserService +import dev.usbharu.hideout.service.impl.IUserService import dev.usbharu.hideout.service.job.JobQueueParentService import io.ktor.client.* import io.ktor.http.* @@ -17,7 +17,7 @@ import kjob.core.job.JobProps class ActivityPubFollowServiceImpl( private val jobQueueParentService: JobQueueParentService, private val activityPubUserService: ActivityPubUserService, - private val userService: UserService, + private val userService: IUserService, private val httpClient: HttpClient ) : ActivityPubFollowService { override suspend fun receiveFollow(follow: Follow): ActivityPubResponse { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt index 445e5a48..f9b4702c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt @@ -7,7 +7,7 @@ import dev.usbharu.hideout.domain.model.ap.Create import dev.usbharu.hideout.domain.model.ap.Note import dev.usbharu.hideout.domain.model.job.DeliverPostJob import dev.usbharu.hideout.plugins.postAp -import dev.usbharu.hideout.service.impl.UserService +import dev.usbharu.hideout.service.impl.IUserService import dev.usbharu.hideout.service.job.JobQueueParentService import io.ktor.client.* import kjob.core.job.JobProps @@ -17,7 +17,7 @@ import java.time.Instant class ActivityPubNoteServiceImpl( private val httpClient: HttpClient, private val jobQueueParentService: JobQueueParentService, - private val userService: UserService + private val userService: IUserService ) : ActivityPubNoteService { private val logger = LoggerFactory.getLogger(this::class.java) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt index 318cff08..4aca8b88 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt @@ -8,7 +8,7 @@ import dev.usbharu.hideout.domain.model.ap.Person import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto import dev.usbharu.hideout.exception.UserNotFoundException import dev.usbharu.hideout.exception.ap.IllegalActivityPubObjectException -import dev.usbharu.hideout.service.impl.UserService +import dev.usbharu.hideout.service.impl.IUserService import dev.usbharu.hideout.util.HttpUtil.Activity import io.ktor.client.* import io.ktor.client.request.* @@ -17,7 +17,7 @@ import io.ktor.http.* import org.slf4j.LoggerFactory class ActivityPubUserServiceImpl( - private val userService: UserService, + private val userService: IUserService, private val httpClient: HttpClient ) : ActivityPubUserService { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/IUserService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/IUserService.kt new file mode 100644 index 00000000..b41f31fd --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/IUserService.kt @@ -0,0 +1,33 @@ +package dev.usbharu.hideout.service.impl + +import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto +import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto +import dev.usbharu.hideout.domain.model.hideout.entity.User + +interface IUserService { + suspend fun findAll(limit: Int? = 100, offset: Long? = 0): List<User> + + suspend fun findById(id: Long): User + + suspend fun findByIds(ids: List<Long>): List<User> + + suspend fun findByName(name: String): List<User> + + suspend fun findByNameLocalUser(name: String): User + + suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> + + suspend fun findByUrl(url: String): User + + suspend fun findByUrls(urls: List<String>): List<User> + + suspend fun usernameAlreadyUse(username: String): Boolean + + suspend fun createLocalUser(user: UserCreateDto): User + + suspend fun createRemoteUser(user: RemoteUserCreateDto): User + + suspend fun findFollowersById(id: Long): List<User> + + suspend fun addFollowers(id: Long, follower: Long) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt index 8e0f0f06..560eaebf 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt @@ -10,10 +10,11 @@ import dev.usbharu.hideout.service.IUserAuthService import java.lang.Integer.min import java.time.Instant -class UserService(private val userRepository: IUserRepository, private val userAuthService: IUserAuthService) { +class UserService(private val userRepository: IUserRepository, private val userAuthService: IUserAuthService) : + IUserService { private val maxLimit = 100 - suspend fun findAll(limit: Int? = maxLimit, offset: Long? = 0): List<User> { + override suspend fun findAll(limit: Int?, offset: Long?): List<User> { return userRepository.findAllByLimitAndByOffset( min(limit ?: maxLimit, maxLimit), @@ -21,41 +22,41 @@ class UserService(private val userRepository: IUserRepository, private val userA ) } - suspend fun findById(id: Long): User { + override suspend fun findById(id: Long): User { return userRepository.findById(id) ?: throw UserNotFoundException("$id was not found.") } - suspend fun findByIds(ids: List<Long>): List<User> { + override suspend fun findByIds(ids: List<Long>): List<User> { return userRepository.findByIds(ids) } - suspend fun findByName(name: String): List<User> { + override suspend fun findByName(name: String): List<User> { return userRepository.findByName(name) } - suspend fun findByNameLocalUser(name: String): User { + override 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> { + override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> { return userRepository.findByNameAndDomains(names) } - suspend fun findByUrl(url: String): User { + override suspend fun findByUrl(url: String): User { return userRepository.findByUrl(url) ?: throw UserNotFoundException("$url was not found.") } - suspend fun findByUrls(urls: List<String>): List<User> { + override suspend fun findByUrls(urls: List<String>): List<User> { return userRepository.findByUrls(urls) } - suspend fun usernameAlreadyUse(username: String): Boolean { + override suspend fun usernameAlreadyUse(username: String): Boolean { val findByNameAndDomain = userRepository.findByNameAndDomain(username, Config.configData.domain) return findByNameAndDomain != null } - suspend fun createLocalUser(user: UserCreateDto): User { + override suspend fun createLocalUser(user: UserCreateDto): User { val nextId = userRepository.nextId() val HashedPassword = userAuthService.hash(user.password) val keyPair = userAuthService.generateKeyPair() @@ -76,7 +77,7 @@ class UserService(private val userRepository: IUserRepository, private val userA return userRepository.save(userEntity) } - suspend fun createRemoteUser(user: RemoteUserCreateDto): User { + override suspend fun createRemoteUser(user: RemoteUserCreateDto): User { val nextId = userRepository.nextId() val userEntity = User( id = nextId, @@ -93,11 +94,11 @@ class UserService(private val userRepository: IUserRepository, private val userA return userRepository.save(userEntity) } - suspend fun findFollowersById(id: Long): List<User> { + override suspend fun findFollowersById(id: Long): List<User> { return userRepository.findFollowersById(id) } - suspend fun addFollowers(id: Long, follower: Long) { + override suspend fun addFollowers(id: Long, follower: Long) { return userRepository.createFollower(id, follower) } diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt index de740d9a..63ff36cf 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/ActivityPubKtTest.kt @@ -1,7 +1,7 @@ package dev.usbharu.hideout.plugins -import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.domain.model.ap.JsonLd +import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.repository.IUserRepository import dev.usbharu.hideout.service.impl.toPem import io.ktor.client.* @@ -29,7 +29,11 @@ class ActivityPubKtTest { TODO("Not yet implemented") } - override suspend fun findByName(name: String): User { + override suspend fun findByName(name: String): List<User> { + TODO() + } + + override suspend fun findByNameAndDomain(name: String, domain: String): User? { val keyPairGenerator = KeyPairGenerator.getInstance("RSA") keyPairGenerator.initialize(1024) val generateKeyPair = keyPairGenerator.generateKeyPair() @@ -49,6 +53,10 @@ class ActivityPubKtTest { ) } + override suspend fun findByDomain(domain: String): List<User> { + TODO("Not yet implemented") + } + override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> { TODO("Not yet implemented") } @@ -85,6 +93,10 @@ class ActivityPubKtTest { TODO("Not yet implemented") } + override suspend fun nextId(): Long { + TODO("Not yet implemented") + } + }) val httpClient = HttpClient(MockEngine { httpRequestData -> diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt index 331e7b5e..ad462b04 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/KtorKeyMapTest.kt @@ -24,7 +24,11 @@ class KtorKeyMapTest { TODO("Not yet implemented") } - override suspend fun findByName(name: String): User { + override suspend fun findByName(name: String): List<User> { + TODO() + } + + override suspend fun findByNameAndDomain(name: String, domain: String): User? { val keyPairGenerator = KeyPairGenerator.getInstance("RSA") keyPairGenerator.initialize(1024) val generateKeyPair = keyPairGenerator.generateKeyPair() @@ -42,6 +46,11 @@ class KtorKeyMapTest { generateKeyPair.private.toPem(), createdAt = Instant.now() ) + + } + + override suspend fun findByDomain(domain: String): List<User> { + TODO("Not yet implemented") } override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> { diff --git a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/InboxRoutingKtTest.kt b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/InboxRoutingKtTest.kt index 5fa97051..94ee5880 100644 --- a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/InboxRoutingKtTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/InboxRoutingKtTest.kt @@ -6,6 +6,7 @@ import dev.usbharu.hideout.plugins.configureSerialization import dev.usbharu.hideout.plugins.configureStatusPages import dev.usbharu.hideout.service.activitypub.ActivityPubService import dev.usbharu.hideout.service.activitypub.ActivityPubUserService +import dev.usbharu.hideout.service.impl.IUserService import dev.usbharu.hideout.service.impl.UserService import dev.usbharu.hideout.service.signature.HttpSignatureVerifyService import io.ktor.client.request.* @@ -45,7 +46,7 @@ class InboxRoutingKtTest { val activityPubService = mock<ActivityPubService>{ on { parseActivity(any()) } doThrow JsonParseException() } - val userService = mock<UserService>() + val userService = mock<IUserService>() val activityPubUserService = mock<ActivityPubUserService>() application { configureStatusPages() @@ -82,7 +83,7 @@ class InboxRoutingKtTest { val activityPubService = mock<ActivityPubService>{ on { parseActivity(any()) } doThrow JsonParseException() } - val userService = mock<UserService>() + val userService = mock<IUserService>() val activityPubUserService = mock<ActivityPubUserService>() application { configureStatusPages() diff --git a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt index fd537617..d4db2cff 100644 --- a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt @@ -13,6 +13,7 @@ import dev.usbharu.hideout.plugins.configureRouting import dev.usbharu.hideout.plugins.configureSerialization import dev.usbharu.hideout.service.activitypub.ActivityPubService import dev.usbharu.hideout.service.activitypub.ActivityPubUserService +import dev.usbharu.hideout.service.impl.IUserService import dev.usbharu.hideout.service.impl.UserService import dev.usbharu.hideout.service.signature.HttpSignatureVerifyService import dev.usbharu.hideout.util.HttpUtil.Activity @@ -62,7 +63,7 @@ class UsersAPTest { val httpSignatureVerifyService = mock<HttpSignatureVerifyService> {} val activityPubService = mock<ActivityPubService> {} - val userService = mock<UserService> {} + val userService = mock<IUserService> {} val activityPubUserService = mock<ActivityPubUserService> { onBlocking { getPersonByName(anyString()) } doReturn person diff --git a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt index c50749f1..e37652dd 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt @@ -6,10 +6,10 @@ package dev.usbharu.hideout.service.activitypub import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.config.ConfigData -import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.domain.model.ap.* +import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob -import dev.usbharu.hideout.service.impl.UserService +import dev.usbharu.hideout.service.impl.IUserService import dev.usbharu.hideout.service.job.JobQueueParentService import io.ktor.client.* import io.ktor.client.engine.mock.* @@ -87,7 +87,7 @@ class ActivityPubFollowServiceImplTest { val activityPubUserService = mock<ActivityPubUserService> { onBlocking { fetchPerson(anyString()) } doReturn person } - val userService = mock<UserService> { + val userService = mock<IUserService> { onBlocking { findByUrls(any()) } doReturn listOf( User( id = 1L, diff --git a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt index a0a85f3c..bb15ffde 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImplTest.kt @@ -8,7 +8,7 @@ import dev.usbharu.hideout.config.ConfigData import dev.usbharu.hideout.domain.model.PostEntity import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.domain.model.job.DeliverPostJob -import dev.usbharu.hideout.service.impl.UserService +import dev.usbharu.hideout.service.impl.IUserService import dev.usbharu.hideout.service.job.JobQueueParentService import io.ktor.client.* import io.ktor.client.engine.mock.* @@ -54,7 +54,7 @@ class ActivityPubNoteServiceImplTest { createdAt = Instant.now() ) ) - val userService = mock<UserService> { + val userService = mock<IUserService> { onBlocking { findById(eq(1L)) } doReturn User( 1L, "test", From d2183c4b477eea1852610da8c8d20fa1e14dc74d Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 17:54:42 +0900 Subject: [PATCH 19/45] =?UTF-8?q?fix:=20PrivateKey=E3=82=92=E6=96=87?= =?UTF-8?q?=E5=AD=97=E5=88=97=E3=81=AB=E3=81=99=E3=82=8B=E5=87=A6=E7=90=86?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt index 560eaebf..5e0018ab 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt @@ -71,7 +71,7 @@ class UserService(private val userRepository: IUserRepository, private val userA outbox = "${Config.configData.url}/users/$nextId/outbox", url = "${Config.configData.url}/users/$nextId", publicKey = keyPair.public.toPem(), - privateKey = keyPair.private.toString(), + privateKey = keyPair.private.toPem(), Instant.now() ) return userRepository.save(userEntity) From 84e84694ea7c673a9292fbebafbc680254a6f976 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 17:54:59 +0900 Subject: [PATCH 20/45] =?UTF-8?q?test:=20UserService=E3=81=AE=E3=83=86?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/service/impl/UserServiceTest.kt | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/test/kotlin/dev/usbharu/hideout/service/impl/UserServiceTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/service/impl/UserServiceTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/impl/UserServiceTest.kt new file mode 100644 index 00000000..45965180 --- /dev/null +++ b/src/test/kotlin/dev/usbharu/hideout/service/impl/UserServiceTest.kt @@ -0,0 +1,88 @@ +@file:OptIn(ExperimentalCoroutinesApi::class) + +package dev.usbharu.hideout.service.impl + +import dev.usbharu.hideout.config.Config +import dev.usbharu.hideout.config.ConfigData +import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto +import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto +import dev.usbharu.hideout.repository.IUserRepository +import dev.usbharu.hideout.service.IUserAuthService +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.Test +import org.mockito.ArgumentMatchers.anyString +import org.mockito.kotlin.* +import java.security.KeyPairGenerator +import kotlin.test.assertEquals +import kotlin.test.assertNull + +class UserServiceTest{ + @Test + fun `createLocalUser ローカルユーザーを作成できる`() = runTest { + Config.configData = ConfigData(domain = "example.com", url = "https://example.com") + val userRepository = mock<IUserRepository> { + onBlocking { nextId() } doReturn 110001L + } + val generateKeyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair() + val userAuthService = mock<IUserAuthService> { + onBlocking { hash(anyString()) } doReturn "hashedPassword" + onBlocking { generateKeyPair() } doReturn generateKeyPair + } + val userService = UserService(userRepository, userAuthService) + userService.createLocalUser(UserCreateDto("test", "testUser", "XXXXXXXXXXXXX", "test")) + verify(userRepository, times(1)).save(any()) + argumentCaptor<dev.usbharu.hideout.domain.model.hideout.entity.User> { + verify(userRepository, times(1)).save(capture()) + assertEquals("test", firstValue.name) + assertEquals("testUser", firstValue.screenName) + assertEquals("XXXXXXXXXXXXX", firstValue.description) + assertEquals("hashedPassword", firstValue.password) + assertEquals(110001L, firstValue.id) + assertEquals("https://example.com/users/110001", firstValue.url) + assertEquals("example.com", firstValue.domain) + assertEquals("https://example.com/users/110001/inbox", firstValue.inbox) + assertEquals("https://example.com/users/110001/outbox", firstValue.outbox) + assertEquals(generateKeyPair.public.toPem(),firstValue.publicKey) + assertEquals(generateKeyPair.private.toPem(),firstValue.privateKey) + } + } + + @Test + fun `createRemoteUser リモートユーザーを作成できる`() = runTest { + + Config.configData = ConfigData(domain = "example.com", url = "https://example.com") + + + val userRepository = mock<IUserRepository>{ + onBlocking { nextId() } doReturn 113345L + } + val userService = UserService(userRepository,mock()) + val user = RemoteUserCreateDto( + "test", + "example.com", + "testUser", + "test user", + "https://example.com/inbox", + "https://example.com/outbox", + "https://example.com", + "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----" + ) + userService.createRemoteUser(user) + verify(userRepository, times(1)).save(any()) + argumentCaptor<dev.usbharu.hideout.domain.model.hideout.entity.User> { + verify(userRepository, times(1)).save(capture()) + assertEquals("test", firstValue.name) + assertEquals("testUser", firstValue.screenName) + assertEquals("test user", firstValue.description) + assertNull(firstValue.password) + assertEquals(113345L, firstValue.id) + assertEquals("https://example.com", firstValue.url) + assertEquals("example.com", firstValue.domain) + assertEquals("https://example.com/inbox", firstValue.inbox) + assertEquals("https://example.com/outbox", firstValue.outbox) + assertEquals("-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----",firstValue.publicKey) + assertNull(firstValue.privateKey) + } + } +} From 5be32970dafbd3586074aba453ae6f7980cffdcf Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 23:06:07 +0900 Subject: [PATCH 21/45] =?UTF-8?q?fix:=20User=E3=81=AEinbox/outbox/url?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/dev/usbharu/hideout/service/impl/UserService.kt | 6 +++--- .../dev/usbharu/hideout/service/impl/UserServiceTest.kt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt index 5e0018ab..fcf30dcb 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt @@ -67,9 +67,9 @@ class UserService(private val userRepository: IUserRepository, private val userA 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", + inbox = "${Config.configData.url}/users/${user.name}/inbox", + outbox = "${Config.configData.url}/users/${user.name}/outbox", + url = "${Config.configData.url}/users/${user.name}", publicKey = keyPair.public.toPem(), privateKey = keyPair.private.toPem(), Instant.now() diff --git a/src/test/kotlin/dev/usbharu/hideout/service/impl/UserServiceTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/impl/UserServiceTest.kt index 45965180..31967bbe 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/impl/UserServiceTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/impl/UserServiceTest.kt @@ -39,10 +39,10 @@ class UserServiceTest{ assertEquals("XXXXXXXXXXXXX", firstValue.description) assertEquals("hashedPassword", firstValue.password) assertEquals(110001L, firstValue.id) - assertEquals("https://example.com/users/110001", firstValue.url) + assertEquals("https://example.com/users/test", firstValue.url) assertEquals("example.com", firstValue.domain) - assertEquals("https://example.com/users/110001/inbox", firstValue.inbox) - assertEquals("https://example.com/users/110001/outbox", firstValue.outbox) + assertEquals("https://example.com/users/test/inbox", firstValue.inbox) + assertEquals("https://example.com/users/test/outbox", firstValue.outbox) assertEquals(generateKeyPair.public.toPem(),firstValue.publicKey) assertEquals(generateKeyPair.private.toPem(),firstValue.privateKey) } From e4046b5c778774c1b57347869873c2658db6822f Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 28 Apr 2023 23:36:27 +0900 Subject: [PATCH 22/45] =?UTF-8?q?fix:=20=E3=83=89=E3=83=A1=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E3=81=AE=E6=8A=BD=E5=87=BA=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/domain/model/ap/JsonLd.kt | 10 +++++++++- .../service/activitypub/ActivityPubUserServiceImpl.kt | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/JsonLd.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/JsonLd.kt index 9700c9d0..f6c4c73a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/JsonLd.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/JsonLd.kt @@ -2,6 +2,7 @@ package dev.usbharu.hideout.domain.model.ap import com.fasterxml.jackson.annotation.JsonAutoDetect import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.databind.JsonDeserializer @@ -15,7 +16,8 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize open class JsonLd { @JsonProperty("@context") @JsonDeserialize(contentUsing = ContextDeserializer::class) - @JsonSerialize(using = ContextSerializer::class) + @JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY, using = ContextSerializer::class) + @JsonInclude(JsonInclude.Include.NON_EMPTY) var context: List<String> = emptyList() @JsonCreator @@ -57,6 +59,12 @@ class ContextDeserializer : JsonDeserializer<String>() { } class ContextSerializer : JsonSerializer<List<String>>() { + + + override fun isEmpty(value: List<String>?): Boolean { + return value.isNullOrEmpty() + } + override fun serialize(value: List<String>?, gen: JsonGenerator?, serializers: SerializerProvider?) { if (value.isNullOrEmpty()) { gen?.writeNull() diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt index 4aca8b88..d63c048f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt @@ -89,7 +89,7 @@ class ActivityPubUserServiceImpl( RemoteUserCreateDto( name = person.preferredUsername ?: throw IllegalActivityPubObjectException("preferredUsername is null"), - domain = url.substringAfter(":").substringBeforeLast("/"), + domain = url.substringAfter("://").substringBefore("/"), screenName = (person.name ?: person.preferredUsername) ?: throw IllegalActivityPubObjectException("preferredUsername is null"), description = person.summary ?: "", inbox = person.inbox ?: throw IllegalActivityPubObjectException("inbox is null"), From 4ac23c225a492dd078455fceed6faf948099153b Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 13:02:38 +0900 Subject: [PATCH 23/45] =?UTF-8?q?fix:=20=E8=BB=BD=E5=BE=AE=E3=81=AA?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E3=80=81=E3=83=AD=E3=82=AC=E3=83=BC=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/routing/activitypub/UserRouting.kt | 3 ++- .../hideout/service/activitypub/ActivityPubNoteServiceImpl.kt | 2 +- .../hideout/service/activitypub/ActivityPubUserServiceImpl.kt | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt index 95b22635..6f5e8f2b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt @@ -31,10 +31,11 @@ fun Routing.usersAP(activityPubUserService: ActivityPubUserService, userService: } class ContentTypeRouteSelector(private vararg val contentType: ContentType) : RouteSelector() { - override fun evaluate(context: RoutingResolveContext, segmentIndex: Int): RouteSelectorEvaluation { + override fun evaluate(context: RoutingResolveContext, segmentIndex: Int): RouteSelectorEvaluation { val requestContentType = ContentType.parse(context.call.request.accept() ?: return RouteSelectorEvaluation.FailedParameter) + context.call.application.log.debug("Content-Type: {}", contentType) return if (contentType.any { contentType -> contentType.match(requestContentType) }) { RouteSelectorEvaluation.Constant } else { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt index f9b4702c..bca90430 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt @@ -45,7 +45,7 @@ class ActivityPubNoteServiceImpl( attributedTo = actor, content = postEntity.text, published = Instant.ofEpochMilli(postEntity.createdAt).toString(), - to = listOf("https://www.w3.org/ns/activitystreams#Public", actor + "/followers") + to = listOf("https://www.w3.org/ns/activitystreams#Public", actor + "/follower") ) val inbox = props[DeliverPostJob.inbox] logger.debug("createNoteJob: actor={}, note={}, inbox={}", actor, postEntity, inbox) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt index d63c048f..e8444ba0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt @@ -89,7 +89,7 @@ class ActivityPubUserServiceImpl( RemoteUserCreateDto( name = person.preferredUsername ?: throw IllegalActivityPubObjectException("preferredUsername is null"), - domain = url.substringAfter("://").substringBefore("/"), + domain = url.substringAfter("://").substringBeforeLast("/"), screenName = (person.name ?: person.preferredUsername) ?: throw IllegalActivityPubObjectException("preferredUsername is null"), description = person.summary ?: "", inbox = person.inbox ?: throw IllegalActivityPubObjectException("inbox is null"), From fc3ab2854b2f44614d97b1db9189381a4a8196b1 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 13:25:12 +0900 Subject: [PATCH 24/45] =?UTF-8?q?feat:=20Accept=E3=83=98=E3=83=83=E3=83=80?= =?UTF-8?q?=E3=83=BC=E3=81=AE=E3=83=AD=E3=82=B0=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../routing/activitypub/UserRouting.kt | 7 +- .../routing/activitypub/UsersAPTest.kt | 87 ++++++++++++++++++- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt index 6f5e8f2b..70201496 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt @@ -35,8 +35,11 @@ class ContentTypeRouteSelector(private vararg val contentType: ContentType) : Ro val requestContentType = ContentType.parse(context.call.request.accept() ?: return RouteSelectorEvaluation.FailedParameter) - context.call.application.log.debug("Content-Type: {}", contentType) - return if (contentType.any { contentType -> contentType.match(requestContentType) }) { + context.call.application.log.debug("Content-Type: {}", requestContentType) + return if (contentType.any { contentType -> + context.call.application.log.debug(contentType.toString()) + contentType.match(requestContentType) + }) { RouteSelectorEvaluation.Constant } else { RouteSelectorEvaluation.FailedParameter diff --git a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt index d4db2cff..30a3e0bd 100644 --- a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt @@ -14,19 +14,21 @@ import dev.usbharu.hideout.plugins.configureSerialization import dev.usbharu.hideout.service.activitypub.ActivityPubService import dev.usbharu.hideout.service.activitypub.ActivityPubUserService import dev.usbharu.hideout.service.impl.IUserService -import dev.usbharu.hideout.service.impl.UserService import dev.usbharu.hideout.service.signature.HttpSignatureVerifyService import dev.usbharu.hideout.util.HttpUtil.Activity +import dev.usbharu.hideout.util.HttpUtil.JsonLd import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* import io.ktor.server.config.* import io.ktor.server.testing.* +import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import kotlin.test.assertEquals +import kotlin.test.assertTrue class UsersAPTest { @@ -71,7 +73,13 @@ class UsersAPTest { application { configureSerialization() - configureRouting(httpSignatureVerifyService, activityPubService, userService, activityPubUserService,mock()) + configureRouting( + httpSignatureVerifyService, + activityPubService, + userService, + activityPubUserService, + mock() + ) } client.get("/users/test") { accept(ContentType.Application.Activity) @@ -89,4 +97,79 @@ class UsersAPTest { assertEquals(person, readValue) } } + + @Test() + @Disabled + fun `ユーザのURLにAcceptヘッダーをActivityとJson-LDにしてアクセスしたときPersonが返ってくる`() = testApplication { + environment { + config = ApplicationConfig("empty.conf") + } + val person = Person( + type = emptyList(), + name = "test", + id = "http://example.com/users/test", + preferredUsername = "test", + summary = "test user", + inbox = "http://example.com/users/test/inbox", + outbox = "http://example.com/users/test/outbox", + url = "http://example.com/users/test", + icon = Image( + type = emptyList(), + name = "http://example.com/users/test/icon.png", + mediaType = "image/png", + url = "http://example.com/users/test/icon.png" + ), + publicKey = Key( + type = emptyList(), + name = "Public Key", + id = "http://example.com/users/test#pubkey", + owner = "https://example.com/users/test", + publicKeyPem = "-----BEGIN PUBLIC KEY-----\n\n-----END PUBLIC KEY-----" + ) + ) + person.context = listOf("https://www.w3.org/ns/activitystreams") + + val httpSignatureVerifyService = mock<HttpSignatureVerifyService> {} + val activityPubService = mock<ActivityPubService> {} + val userService = mock<IUserService> {} + + val activityPubUserService = mock<ActivityPubUserService> { + onBlocking { getPersonByName(anyString()) } doReturn person + } + + application { + configureSerialization() + configureRouting( + httpSignatureVerifyService, + activityPubService, + userService, + activityPubUserService, + mock() + ) + } + client.get("/users/test") { + accept(ContentType.Application.JsonLd) + accept(ContentType.Application.Activity) + }.let { + val objectMapper = jacksonObjectMapper().enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY) + .setSerializationInclusion(JsonInclude.Include.NON_EMPTY) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + objectMapper.configOverride(List::class.java).setSetterInfo( + JsonSetter.Value.forValueNulls( + Nulls.AS_EMPTY + ) + ) + val actual = it.bodyAsText() + val readValue = objectMapper.readValue<Person>(actual) + assertEquals(person, readValue) + } + } + + @Test + @Disabled + fun contentType_Test() { + val listOf = listOf(ContentType.Application.JsonLd, ContentType.Application.Activity) + assertTrue(listOf.any { contentType -> contentType.match("application/ld+json; profile=\"\\\"https://www.w3.org/ns/activitystreams\\\",application/activity+json\"") }) + assertTrue(ContentType.Application.JsonLd.match("application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")) + } } From 68d438bdb465c30d83f38723decb0aa464b019d7 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 13:36:41 +0900 Subject: [PATCH 25/45] =?UTF-8?q?fix:=20Accept=E3=83=98=E3=83=83=E3=83=80?= =?UTF-8?q?=E3=83=BC=E3=81=AE=E5=88=A4=E5=AE=9A=E6=96=B9=E6=B3=95=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/routing/activitypub/UserRouting.kt | 11 +++++------ .../hideout/routing/activitypub/UsersAPTest.kt | 7 +++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt index 70201496..2864ba23 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt @@ -31,15 +31,14 @@ fun Routing.usersAP(activityPubUserService: ActivityPubUserService, userService: } class ContentTypeRouteSelector(private vararg val contentType: ContentType) : RouteSelector() { - override fun evaluate(context: RoutingResolveContext, segmentIndex: Int): RouteSelectorEvaluation { + override fun evaluate(context: RoutingResolveContext, segmentIndex: Int): RouteSelectorEvaluation { + context.call.application.log.debug("Accept: ${context.call.request.accept()}") val requestContentType = ContentType.parse(context.call.request.accept() ?: return RouteSelectorEvaluation.FailedParameter) - context.call.application.log.debug("Content-Type: {}", requestContentType) - return if (contentType.any { contentType -> - context.call.application.log.debug(contentType.toString()) - contentType.match(requestContentType) - }) { + + return if (contentType.find { contentType: ContentType -> contentType.match(requestContentType) } + .let { true }) { RouteSelectorEvaluation.Constant } else { RouteSelectorEvaluation.FailedParameter diff --git a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt index 30a3e0bd..e5ec1457 100644 --- a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt @@ -22,7 +22,6 @@ import io.ktor.client.statement.* import io.ktor.http.* import io.ktor.server.config.* import io.ktor.server.testing.* -import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.doReturn @@ -99,7 +98,7 @@ class UsersAPTest { } @Test() - @Disabled +// @Disabled fun `ユーザのURLにAcceptヘッダーをActivityとJson-LDにしてアクセスしたときPersonが返ってくる`() = testApplication { environment { config = ApplicationConfig("empty.conf") @@ -166,10 +165,10 @@ class UsersAPTest { } @Test - @Disabled +// @Disabled fun contentType_Test() { val listOf = listOf(ContentType.Application.JsonLd, ContentType.Application.Activity) - assertTrue(listOf.any { contentType -> contentType.match("application/ld+json; profile=\"\\\"https://www.w3.org/ns/activitystreams\\\",application/activity+json\"") }) + assertTrue(listOf.find { contentType -> contentType.match("application/ld+json; profile=\"\\\"https://www.w3.org/ns/activitystreams\\\",application/activity+json\"") }.let { true }) assertTrue(ContentType.Application.JsonLd.match("application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")) } } From 54145dbde10ef8a4ff96da20ac37c1057700eca1 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 14:16:48 +0900 Subject: [PATCH 26/45] =?UTF-8?q?feat:=20Get=E3=83=AA=E3=82=AF=E3=82=A8?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=82=82=E7=BD=B2=E5=90=8D=E3=81=A7=E3=81=8D?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt | 7 +++++++ .../activitypub/ActivityPubFollowServiceImpl.kt | 4 ++-- .../service/activitypub/ActivityPubUserService.kt | 2 +- .../service/activitypub/ActivityPubUserServiceImpl.kt | 11 ++++++++--- .../activitypub/ActivityPubFollowServiceImplTest.kt | 2 +- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt index cbb6cab4..87397704 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt @@ -44,6 +44,13 @@ suspend fun HttpClient.postAp(urlString: String, username: String, jsonLd: JsonL } } +suspend fun HttpClient.getAp(urlString: String,username: String):HttpResponse { + return this.get(urlString){ + header("Accept",ContentType.Application.Activity) + header("Signature","keyId=\"$username\",algorithm=\"#rsa-sha\",headers=\"(request-target) digest date\"") + } +} + class HttpSignaturePluginConfig { lateinit var keyMap: KeyMap } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImpl.kt index fcd94662..988cb81e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImpl.kt @@ -32,9 +32,9 @@ class ActivityPubFollowServiceImpl( override suspend fun receiveFollowJob(props: JobProps<ReceiveFollowJob>) { val actor = props[ReceiveFollowJob.actor] - val person = activityPubUserService.fetchPerson(actor) - val follow = Config.configData.objectMapper.readValue<Follow>(props[ReceiveFollowJob.follow]) val targetActor = props[ReceiveFollowJob.targetActor] + val person = activityPubUserService.fetchPerson(actor,targetActor) + val follow = Config.configData.objectMapper.readValue<Follow>(props[ReceiveFollowJob.follow]) httpClient.postAp( urlString = person.inbox ?: throw IllegalArgumentException("inbox is not found"), username = "$targetActor#pubkey", diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserService.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserService.kt index a698670b..3446da24 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserService.kt @@ -5,5 +5,5 @@ import dev.usbharu.hideout.domain.model.ap.Person interface ActivityPubUserService { suspend fun getPersonByName(name:String): Person - suspend fun fetchPerson(url:String): Person + suspend fun fetchPerson(url: String, targetActor: String? = null): Person } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt index e8444ba0..94c8557a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubUserServiceImpl.kt @@ -8,6 +8,7 @@ import dev.usbharu.hideout.domain.model.ap.Person import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto import dev.usbharu.hideout.exception.UserNotFoundException import dev.usbharu.hideout.exception.ap.IllegalActivityPubObjectException +import dev.usbharu.hideout.plugins.getAp import dev.usbharu.hideout.service.impl.IUserService import dev.usbharu.hideout.util.HttpUtil.Activity import io.ktor.client.* @@ -52,7 +53,7 @@ class ActivityPubUserServiceImpl( ) } - override suspend fun fetchPerson(url: String): Person { + override suspend fun fetchPerson(url: String, targetActor: String?): Person { return try { val userEntity = userService.findByUrl(url) return Person( @@ -80,8 +81,12 @@ class ActivityPubUserServiceImpl( ) } catch (e: UserNotFoundException) { - val httpResponse = httpClient.get(url) { - accept(ContentType.Application.Activity) + val httpResponse = if (targetActor != null) { + httpClient.getAp(url,"$targetActor#pubkey") + }else { + httpClient.get(url) { + accept(ContentType.Application.Activity) + } } val person = Config.configData.objectMapper.readValue<Person>(httpResponse.bodyAsText()) diff --git a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt index e37652dd..6a668e34 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt @@ -85,7 +85,7 @@ class ActivityPubFollowServiceImplTest { ) val activityPubUserService = mock<ActivityPubUserService> { - onBlocking { fetchPerson(anyString()) } doReturn person + onBlocking { fetchPerson(anyString(), any()) } doReturn person } val userService = mock<IUserService> { onBlocking { findByUrls(any()) } doReturn listOf( From 97c18b07547967cbe90f372997d65827620c7b19 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 14:25:12 +0900 Subject: [PATCH 27/45] =?UTF-8?q?fix:=20Signature=E3=83=98=E3=83=83?= =?UTF-8?q?=E3=83=80=E3=83=BC=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt index 87397704..6013cea5 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt @@ -47,7 +47,7 @@ suspend fun HttpClient.postAp(urlString: String, username: String, jsonLd: JsonL suspend fun HttpClient.getAp(urlString: String,username: String):HttpResponse { return this.get(urlString){ header("Accept",ContentType.Application.Activity) - header("Signature","keyId=\"$username\",algorithm=\"#rsa-sha\",headers=\"(request-target) digest date\"") + header("Signature","keyId=\"$username\",algorithm=\"rsa-sha256\",headers=\"(request-target) digest date\"") } } From bd927677a0a629a7ca95037e8f8f0977b26e0ad2 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 14:44:43 +0900 Subject: [PATCH 28/45] =?UTF-8?q?fix:=20=E3=81=AA=E3=81=9C=E3=81=8B?= =?UTF-8?q?=E5=BF=85=E3=81=9AJson=E3=82=92=E8=BF=94=E3=81=99=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=E3=81=AA=E3=81=A3=E3=81=A6=E3=81=84=E3=81=9F?= =?UTF-8?q?=E3=81=AE=E3=81=A7=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../routing/activitypub/UserRouting.kt | 3 +- .../routing/activitypub/UsersAPTest.kt | 45 ++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt index 2864ba23..559ca0a0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt @@ -37,8 +37,7 @@ class ContentTypeRouteSelector(private vararg val contentType: ContentType) : Ro val requestContentType = ContentType.parse(context.call.request.accept() ?: return RouteSelectorEvaluation.FailedParameter) - return if (contentType.find { contentType: ContentType -> contentType.match(requestContentType) } - .let { true }) { + return if (contentType.find { contentType: ContentType -> contentType.match(requestContentType) } != null) { RouteSelectorEvaluation.Constant } else { RouteSelectorEvaluation.FailedParameter diff --git a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt index e5ec1457..9f713056 100644 --- a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt @@ -9,6 +9,7 @@ import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.domain.model.ap.Image import dev.usbharu.hideout.domain.model.ap.Key import dev.usbharu.hideout.domain.model.ap.Person +import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.plugins.configureRouting import dev.usbharu.hideout.plugins.configureSerialization import dev.usbharu.hideout.service.activitypub.ActivityPubService @@ -25,7 +26,9 @@ import io.ktor.server.testing.* import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.doReturn +import org.mockito.kotlin.eq import org.mockito.kotlin.mock +import java.time.Instant import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -168,7 +171,47 @@ class UsersAPTest { // @Disabled fun contentType_Test() { val listOf = listOf(ContentType.Application.JsonLd, ContentType.Application.Activity) - assertTrue(listOf.find { contentType -> contentType.match("application/ld+json; profile=\"\\\"https://www.w3.org/ns/activitystreams\\\",application/activity+json\"") }.let { true }) + assertTrue(listOf.find { contentType -> + contentType.match("application/ld+json; profile=\"\\\"https://www.w3.org/ns/activitystreams\\\",application/activity+json\"") + }.let { it != null }) assertTrue(ContentType.Application.JsonLd.match("application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")) } + + @Test + fun ユーザーのURLにAcceptヘッダーをhtmlにしてアクセスしたときはただの文字を返す() = testApplication { + environment { + config = ApplicationConfig("empty.conf") + } + val userService = mock<IUserService> { + onBlocking { findByNameLocalUser(eq("test")) } doReturn User( + 1L, + "test", + "example.com", + "test", + "", + "hashedPassword", + "https://example.com/inbox", + "https://example.com/outbox", + "https://example.com", + "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----", + "-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----", + Instant.now() + ) + } + application { + configureRouting( + mock(), + mock(), + userService, + mock(), + mock() + ) + } + client.get("/users/test") { + accept(ContentType.Text.Html) + }.let { + assertEquals(HttpStatusCode.OK, it.status) + assertTrue(it.contentType()?.match(ContentType.Text.Plain) == true) + } + } } From 2e5dab4378f6b8720aeae95d93d639faa0eed18e Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 14:46:22 +0900 Subject: [PATCH 29/45] =?UTF-8?q?fix:=20get=E3=83=AA=E3=82=AF=E3=82=A8?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=81=8B=E3=82=89digest=E3=82=92=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt index 6013cea5..74fcfff7 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt @@ -47,7 +47,7 @@ suspend fun HttpClient.postAp(urlString: String, username: String, jsonLd: JsonL suspend fun HttpClient.getAp(urlString: String,username: String):HttpResponse { return this.get(urlString){ header("Accept",ContentType.Application.Activity) - header("Signature","keyId=\"$username\",algorithm=\"rsa-sha256\",headers=\"(request-target) digest date\"") + header("Signature","keyId=\"$username\",algorithm=\"rsa-sha256\",headers=\"(request-target) date\"") } } From 26b98ab9c5462eda1e420bf9c5064746a7665a79 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 15:11:24 +0900 Subject: [PATCH 30/45] =?UTF-8?q?fix:=20ContentType=E3=81=AE=E5=88=A4?= =?UTF-8?q?=E5=AE=9A=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usbharu/hideout/routing/activitypub/UserRouting.kt | 8 ++++---- .../usbharu/hideout/routing/activitypub/UsersAPTest.kt | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt index 559ca0a0..6212297a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt @@ -34,10 +34,10 @@ class ContentTypeRouteSelector(private vararg val contentType: ContentType) : Ro override fun evaluate(context: RoutingResolveContext, segmentIndex: Int): RouteSelectorEvaluation { context.call.application.log.debug("Accept: ${context.call.request.accept()}") - val requestContentType = - ContentType.parse(context.call.request.accept() ?: return RouteSelectorEvaluation.FailedParameter) - - return if (contentType.find { contentType: ContentType -> contentType.match(requestContentType) } != null) { + val requestContentType = context.call.request.accept() ?: return RouteSelectorEvaluation.FailedParameter + return if (requestContentType.split(",") + .find { contentType.find { contentType -> contentType.match(it) } != null } != null + ) { RouteSelectorEvaluation.Constant } else { RouteSelectorEvaluation.FailedParameter diff --git a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt index 9f713056..0e997f43 100644 --- a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/UsersAPTest.kt @@ -170,9 +170,11 @@ class UsersAPTest { @Test // @Disabled fun contentType_Test() { + + assertTrue(ContentType.Application.Activity.match("application/activity+json")) val listOf = listOf(ContentType.Application.JsonLd, ContentType.Application.Activity) assertTrue(listOf.find { contentType -> - contentType.match("application/ld+json; profile=\"\\\"https://www.w3.org/ns/activitystreams\\\",application/activity+json\"") + contentType.match("application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") }.let { it != null }) assertTrue(ContentType.Application.JsonLd.match("application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")) } From bb7123564cee90d7fa198bf0ea1e21d65f5aa61d Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 15:24:28 +0900 Subject: [PATCH 31/45] =?UTF-8?q?feat:=20Get=E3=83=AA=E3=82=AF=E3=82=A8?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=81=AE=E3=83=AD=E3=82=B0=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/routing/activitypub/UserRouting.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt index 6212297a..10401627 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt @@ -15,6 +15,8 @@ import io.ktor.server.routing.* fun Routing.usersAP(activityPubUserService: ActivityPubUserService, userService: IUserService) { route("/users/{name}") { createChild(ContentTypeRouteSelector(ContentType.Application.Activity, ContentType.Application.JsonLd)).handle { + call.application.log.debug("Signature: ${call.request.header("Signature")}") + call.application.log.debug("Authorization: ${call.request.header("Authorization")}") val name = call.parameters["name"] ?: throw ParameterNotExistException("Parameter(name='name') does not exist.") val person = activityPubUserService.getPersonByName(name) From 50a5eef279e262f027274838baafa8d031c319a5 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 15:44:48 +0900 Subject: [PATCH 32/45] =?UTF-8?q?feat:=20Host=E3=81=AE=E7=BD=B2=E5=90=8D?= =?UTF-8?q?=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt index 74fcfff7..6ed1783d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt @@ -47,7 +47,7 @@ suspend fun HttpClient.postAp(urlString: String, username: String, jsonLd: JsonL suspend fun HttpClient.getAp(urlString: String,username: String):HttpResponse { return this.get(urlString){ header("Accept",ContentType.Application.Activity) - header("Signature","keyId=\"$username\",algorithm=\"rsa-sha256\",headers=\"(request-target) date\"") + header("Signature","keyId=\"$username\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date\"") } } @@ -63,6 +63,7 @@ val httpSignaturePlugin = createClientPlugin("HttpSign", ::HttpSignaturePluginCo request.header("Date", format.format(Date())) + request.header("Host",request.url.host+request.url.port.toString()) println(request.bodyType) println(request.bodyType?.type) if (request.bodyType?.type == String::class) { @@ -110,7 +111,9 @@ val httpSignaturePlugin = createClientPlugin("HttpSign", ::HttpSignaturePluginCo "date" -> { "Date" } - + "host" -> { + "Host" + } else -> { it } From b72e36ba8c7558e4ad57029c7efcdab7cd639079 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 15:52:59 +0900 Subject: [PATCH 33/45] =?UTF-8?q?fix:=20=E3=83=9B=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=81=AE=E3=83=9D=E3=83=BC=E3=83=88=E7=95=AA=E5=8F=B7=E3=81=8C?= =?UTF-8?q?=E3=81=8A=E3=81=8B=E3=81=97=E3=81=8F=E3=81=AA=E3=82=8B=E3=81=AE?= =?UTF-8?q?=E3=81=A7=E3=81=A8=E3=82=8A=E3=81=82=E3=81=88=E3=81=9A=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt index 6ed1783d..c76d52e0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt @@ -63,7 +63,7 @@ val httpSignaturePlugin = createClientPlugin("HttpSign", ::HttpSignaturePluginCo request.header("Date", format.format(Date())) - request.header("Host",request.url.host+request.url.port.toString()) + request.header("Host", "${request.url.host}") println(request.bodyType) println(request.bodyType?.type) if (request.bodyType?.type == String::class) { From 7915189163b31949a53c765fb41e4fba7df12c14 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 16:04:17 +0900 Subject: [PATCH 34/45] =?UTF-8?q?fix:=20Signature=E3=83=98=E3=83=83?= =?UTF-8?q?=E3=83=80=E3=83=BC=E3=82=92=E5=B0=91=E3=81=97=E6=96=B0=E3=81=97?= =?UTF-8?q?=E3=81=84=E4=BB=95=E6=A7=98=E3=81=AB=E6=BA=96=E6=8B=A0=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt index c76d52e0..ffdaaf21 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt @@ -149,6 +149,11 @@ val httpSignaturePlugin = createClientPlugin("HttpSign", ::HttpSignaturePluginCo }) + + val signatureHeader = request.headers.get("Signature") + val replace = signatureHeader?.replace("; ", ",")?.replace(";",",") + request.headers.remove("Signature") + request.header("Signature", replace) } } From 2fde447e5aa1e2d9c6cd620d65b5664f4b5c492d Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 16:19:07 +0900 Subject: [PATCH 35/45] =?UTF-8?q?fix:=20Signature=E3=83=98=E3=83=83?= =?UTF-8?q?=E3=83=80=E3=83=BC=E3=81=AE=E5=A4=89=E6=9B=B4=E3=82=92=E3=81=99?= =?UTF-8?q?=E3=81=B9=E3=81=A6=E3=81=AE=E3=83=98=E3=83=83=E3=83=80=E3=83=BC?= =?UTF-8?q?=E3=81=AB=E9=81=A9=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt index ffdaaf21..46140f4f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt @@ -150,10 +150,9 @@ val httpSignaturePlugin = createClientPlugin("HttpSign", ::HttpSignaturePluginCo }) - val signatureHeader = request.headers.get("Signature") - val replace = signatureHeader?.replace("; ", ",")?.replace(";",",") + val signatureHeader = request.headers.getAll("Signature").orEmpty() request.headers.remove("Signature") - request.header("Signature", replace) + signatureHeader.map { it.replace("; ",",").replace(";",",") }.forEach { request.header("Signature", it) } } } From 93a554e988542daacb0e116fc321c89faed45a0b Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 16:27:42 +0900 Subject: [PATCH 36/45] =?UTF-8?q?fix:=20PEM=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/service/impl/UserAuthService.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt index 41a38a41..74355630 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt @@ -44,11 +44,11 @@ class UserAuthService( fun PublicKey.toPem(): String { return "-----BEGIN PUBLIC KEY-----\n" + Base64.getEncoder().encodeToString(encoded).chunked(64).joinToString("\n") + - "\n-----END PUBLIC KEY-----\n" + "\n-----END PUBLIC KEY-----" } fun PrivateKey.toPem(): String { - return "-----BEGIN PRIVATE KEY-----" + + return "-----BEGIN PRIVATE KEY-----\n" + Base64.getEncoder().encodeToString(encoded).chunked(64).joinToString("\n") + - "\n-----END PRIVATE KEY-----\n" + "\n-----END PRIVATE KEY-----" } From 887db080d03671c339ab729ba4276ba21278b317 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 16:47:58 +0900 Subject: [PATCH 37/45] =?UTF-8?q?fix:=20=E9=8D=B5=E3=82=92=E5=BC=B7?= =?UTF-8?q?=E5=9B=BA=E3=81=AB=E3=80=81PEM=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/service/impl/UserAuthService.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt index 74355630..60aa97a4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserAuthService.kt @@ -31,7 +31,7 @@ class UserAuthService( override suspend fun generateKeyPair(): KeyPair { val keyPairGenerator = KeyPairGenerator.getInstance("RSA") - keyPairGenerator.initialize(1024) + keyPairGenerator.initialize(2048) return keyPairGenerator.generateKeyPair() } @@ -44,11 +44,11 @@ class UserAuthService( fun PublicKey.toPem(): String { return "-----BEGIN PUBLIC KEY-----\n" + Base64.getEncoder().encodeToString(encoded).chunked(64).joinToString("\n") + - "\n-----END PUBLIC KEY-----" + "\n-----END PUBLIC KEY-----\n" } fun PrivateKey.toPem(): String { return "-----BEGIN PRIVATE KEY-----\n" + Base64.getEncoder().encodeToString(encoded).chunked(64).joinToString("\n") + - "\n-----END PRIVATE KEY-----" + "\n-----END PRIVATE KEY-----\n" } From b5b8a6a73fb17d34271c384077988556a651588c Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 17:01:02 +0900 Subject: [PATCH 38/45] =?UTF-8?q?fix:=20Signature=E3=83=98=E3=83=83?= =?UTF-8?q?=E3=83=80=E3=83=BC=E3=81=AE=E5=BD=A2=E5=BC=8F=E3=82=92=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt index 46140f4f..312c38e0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt @@ -152,7 +152,7 @@ val httpSignaturePlugin = createClientPlugin("HttpSign", ::HttpSignaturePluginCo val signatureHeader = request.headers.getAll("Signature").orEmpty() request.headers.remove("Signature") - signatureHeader.map { it.replace("; ",",").replace(";",",") }.forEach { request.header("Signature", it) } + signatureHeader.map { it.replace("; ",",").replace(";",",") }.joinToString().let { request.header("Signature", it)} } } From 01bb4fc56b9ff74bfeea39586d4f08b898e0c590 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 17:10:58 +0900 Subject: [PATCH 39/45] =?UTF-8?q?fix:=20Signature=E3=83=98=E3=83=83?= =?UTF-8?q?=E3=83=80=E3=83=BC=E3=81=AE=E5=BD=A2=E5=BC=8F=E3=82=92=E5=A4=89?= =?UTF-8?q?=E6=9B=B42?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/plugins/ActivityPub.kt | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt index 312c38e0..af7c4b86 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt @@ -44,10 +44,10 @@ suspend fun HttpClient.postAp(urlString: String, username: String, jsonLd: JsonL } } -suspend fun HttpClient.getAp(urlString: String,username: String):HttpResponse { - return this.get(urlString){ - header("Accept",ContentType.Application.Activity) - header("Signature","keyId=\"$username\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date\"") +suspend fun HttpClient.getAp(urlString: String, username: String): HttpResponse { + return this.get(urlString) { + header("Accept", ContentType.Application.Activity) + header("Signature", "keyId=\"$username\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date\"") } } @@ -111,9 +111,11 @@ val httpSignaturePlugin = createClientPlugin("HttpSign", ::HttpSignaturePluginCo "date" -> { "Date" } + "host" -> { "Host" } + else -> { it } @@ -152,7 +154,8 @@ val httpSignaturePlugin = createClientPlugin("HttpSign", ::HttpSignaturePluginCo val signatureHeader = request.headers.getAll("Signature").orEmpty() request.headers.remove("Signature") - signatureHeader.map { it.replace("; ",",").replace(";",",") }.joinToString().let { request.header("Signature", it)} + signatureHeader.map { it.replace("; ", ",").replace(";", ",") }.joinToString(",") + .let { request.header("Signature", it) } } } @@ -164,7 +167,7 @@ class KtorKeyMap(private val userAuthRepository: IUserRepository) : KeyMap { .substringAfterLast("/") val publicBytes = Base64.getDecoder().decode( userAuthRepository.findByNameAndDomain( - username,Config.configData.domain + username, Config.configData.domain )?.publicKey?.replace("-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----")?.replace("", "") ?.replace("\n", "") ) @@ -177,7 +180,7 @@ class KtorKeyMap(private val userAuthRepository: IUserRepository) : KeyMap { .substringAfterLast("/") val publicBytes = Base64.getDecoder().decode( userAuthRepository.findByNameAndDomain( - username,Config.configData.domain + username, Config.configData.domain )?.privateKey?.replace("-----BEGIN PRIVATE KEY-----", "")?.replace("-----END PRIVATE KEY-----", "") ?.replace("\n", "") ) From b5f6c60e056970747a412ad8af71e2c4d1b4b008 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 17:49:29 +0900 Subject: [PATCH 40/45] =?UTF-8?q?feat:=20Create=E3=82=A2=E3=82=AF=E3=83=86?= =?UTF-8?q?=E3=82=A3=E3=83=93=E3=83=86=E3=82=A3=E3=81=ABactor=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/domain/model/ap/Create.kt | 11 ++++++++++- .../dev/usbharu/hideout/domain/model/ap/Object.kt | 15 +++++++++++---- .../activitypub/ActivityPubNoteServiceImpl.kt | 3 ++- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Create.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Create.kt index 46f89ec4..4739176a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Create.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Create.kt @@ -4,7 +4,16 @@ open class Create : Object { var `object`: Object? = null protected constructor() : super() - constructor(type: List<String> = emptyList(), name: String, `object`: Object?) : super(add(type, "Create"), name) { + constructor( + type: List<String> = emptyList(), + name: String? = null, + `object`: Object?, + actor: String? = null + ) : super( + add(type, "Create"), + name, + actor + ) { this.`object` = `object` } diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt index e13d3eb5..efcaedf3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt @@ -9,9 +9,10 @@ open class Object : JsonLd { @JsonSerialize(using = TypeSerializer::class) private var type: List<String> = emptyList() var name: String? = null + var actor: String? = null protected constructor() - constructor(type: List<String>, name: String) : super() { + constructor(type: List<String>, name: String? = null,actor:String? = null) : super() { this.type = type this.name = name } @@ -25,22 +26,28 @@ open class Object : JsonLd { } } + + override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Object) return false + if (!super.equals(other)) return false if (type != other.type) return false - return name == other.name + if (name != other.name) return false + return actor == other.actor } override fun hashCode(): Int { - var result = type.hashCode() + var result = super.hashCode() + result = 31 * result + type.hashCode() result = 31 * result + (name?.hashCode() ?: 0) + result = 31 * result + (actor?.hashCode() ?: 0) return result } override fun toString(): String { - return "Object(type=$type, name=$name) ${super.toString()}" + return "Object(type=$type, name=$name, actor=$actor) ${super.toString()}" } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt index bca90430..80f0666b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt @@ -54,7 +54,8 @@ class ActivityPubNoteServiceImpl( username = "$actor#pubkey", jsonLd = Create( name = "Create Note", - `object` = note + `object` = note, + actor = note.attributedTo ) ) } From f31f89a5403bb48d2db52e31e684d9df42d9f2e2 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 17:54:36 +0900 Subject: [PATCH 41/45] =?UTF-8?q?feat:=20Create=E3=82=A2=E3=82=AF=E3=83=86?= =?UTF-8?q?=E3=82=A3=E3=83=93=E3=83=86=E3=82=A3=E3=81=ABactor=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Accept.kt | 4 +--- src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Follow.kt | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Accept.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Accept.kt index 7b6d397a..b2274eb6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Accept.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Accept.kt @@ -2,7 +2,6 @@ package dev.usbharu.hideout.domain.model.ap open class Accept : Object { var `object`: Object? = null - var actor: String? = null protected constructor() : super() constructor( @@ -10,9 +9,8 @@ open class Accept : Object { name: String, `object`: Object?, actor: String? - ) : super(add(type, "Accept"), name) { + ) : super(add(type, "Accept"), name,actor) { this.`object` = `object` - this.actor = actor } override fun equals(other: Any?): Boolean { diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Follow.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Follow.kt index 9ed6e67a..cf6d1303 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Follow.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Follow.kt @@ -2,7 +2,6 @@ package dev.usbharu.hideout.domain.model.ap open class Follow : Object { var `object`: String? = null - var actor: String? = null protected constructor() : super() constructor( @@ -10,9 +9,8 @@ open class Follow : Object { name: String, `object`: String?, actor: String? - ) : super(add(type, "Follow"), name) { + ) : super(add(type, "Follow"), name,actor) { this.`object` = `object` - this.actor = actor } From 814fe4857913470389fa50540805639eab903684 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 17:59:57 +0900 Subject: [PATCH 42/45] =?UTF-8?q?fix:=20actor=E3=81=8C=E5=88=9D=E6=9C=9F?= =?UTF-8?q?=E5=8C=96=E3=81=95=E3=82=8C=E3=81=A6=E3=81=84=E3=81=AA=E3=81=8B?= =?UTF-8?q?=E3=81=A3=E3=81=9F=E3=81=AE=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt index efcaedf3..080f21ef 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt @@ -15,6 +15,7 @@ open class Object : JsonLd { constructor(type: List<String>, name: String? = null,actor:String? = null) : super() { this.type = type this.name = name + this.actor = actor } companion object { From ef713e6d364553449407905e801e3c92c5617729 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 18:27:15 +0900 Subject: [PATCH 43/45] =?UTF-8?q?feat:=20Create=E3=81=ABid=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/dev/usbharu/hideout/domain/model/ap/Create.kt | 6 ++++-- .../kotlin/dev/usbharu/hideout/domain/model/ap/Key.kt | 4 +--- .../kotlin/dev/usbharu/hideout/domain/model/ap/Note.kt | 8 +++++--- .../kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt | 4 +++- .../kotlin/dev/usbharu/hideout/domain/model/ap/Person.kt | 4 +--- .../service/activitypub/ActivityPubNoteServiceImpl.kt | 3 ++- 6 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Create.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Create.kt index 4739176a..540e57aa 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Create.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Create.kt @@ -8,11 +8,13 @@ open class Create : Object { type: List<String> = emptyList(), name: String? = null, `object`: Object?, - actor: String? = null + actor: String? = null, + id: String? = null ) : super( add(type, "Create"), name, - actor + actor, + id ) { this.`object` = `object` } diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Key.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Key.kt index 3b1f168a..935a531b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Key.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Key.kt @@ -1,7 +1,6 @@ package dev.usbharu.hideout.domain.model.ap open class Key : Object { - var id: String? = null var owner: String? = null var publicKeyPem: String? = null @@ -12,8 +11,7 @@ open class Key : Object { id: String?, owner: String?, publicKeyPem: String? - ) : super(add(type, "Key"), name) { - this.id = id + ) : super(add(type, "Key"), name,id) { this.owner = owner this.publicKeyPem = publicKeyPem } diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Note.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Note.kt index 0250301c..e62fccc2 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Note.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Note.kt @@ -1,7 +1,6 @@ package dev.usbharu.hideout.domain.model.ap open class Note : Object { - var id: String? = null var attributedTo: String? = null var content: String? = null var published: String? = null @@ -16,8 +15,11 @@ open class Note : Object { content: String?, published: String?, to: List<String> = emptyList() - ) : super(add(type, "Note"), name) { - this.id = id + ) : super( + type = add(type, "Note"), + name = name, + id = id + ) { this.attributedTo = attributedTo this.content = content this.published = published diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt index 080f21ef..c66e7224 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Object.kt @@ -10,12 +10,14 @@ open class Object : JsonLd { private var type: List<String> = emptyList() var name: String? = null var actor: String? = null + var id:String? = null protected constructor() - constructor(type: List<String>, name: String? = null,actor:String? = null) : super() { + constructor(type: List<String>, name: String? = null,actor:String? = null,id:String? = null) : super() { this.type = type this.name = name this.actor = actor + this.id = id } companion object { diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Person.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Person.kt index 6fecebc6..8a4e5711 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Person.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Person.kt @@ -1,7 +1,6 @@ package dev.usbharu.hideout.domain.model.ap open class Person : Object { - private var id: String? = null var preferredUsername: String? = null var summary: String? = null var inbox: String? = null @@ -22,8 +21,7 @@ open class Person : Object { url: String?, icon: Image?, publicKey: Key? - ) : super(add(type, "Person"), name) { - this.id = id + ) : super(add(type, "Person"), name,id = id) { this.preferredUsername = preferredUsername this.summary = summary this.inbox = inbox diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt index 80f0666b..d111f5d9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt @@ -55,7 +55,8 @@ class ActivityPubNoteServiceImpl( jsonLd = Create( name = "Create Note", `object` = note, - actor = note.attributedTo + actor = note.attributedTo, + id = "${Config.configData.url}/create/${postEntity.id}" ) ) } From 58bf367d60588f72af86cb4887b7a5164026496d Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 18:52:37 +0900 Subject: [PATCH 44/45] =?UTF-8?q?feat:=20Create=E3=81=AEID=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/service/activitypub/ActivityPubNoteServiceImpl.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt index d111f5d9..72eb6acf 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubNoteServiceImpl.kt @@ -56,7 +56,7 @@ class ActivityPubNoteServiceImpl( name = "Create Note", `object` = note, actor = note.attributedTo, - id = "${Config.configData.url}/create/${postEntity.id}" + id = "${Config.configData.url}/create/note/${postEntity.id}" ) ) } From f2766ea65eb88b662f80c6902c10ec76096e75e1 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 29 Apr 2023 21:50:01 +0900 Subject: [PATCH 45/45] =?UTF-8?q?test:=20Json=E3=81=AE=E3=82=B7=E3=83=AA?= =?UTF-8?q?=E3=82=A2=E3=83=A9=E3=82=A4=E3=82=BA=E3=81=8C=E5=B0=91=E3=81=97?= =?UTF-8?q?=E5=A4=89=E3=82=8F=E3=81=A3=E3=81=A6=E3=81=84=E3=81=9F=E3=81=AE?= =?UTF-8?q?=E3=81=A7=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/activitypub/ActivityPubFollowServiceImplTest.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt index 6a668e34..a8eae660 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubFollowServiceImplTest.kt @@ -50,8 +50,9 @@ class ActivityPubFollowServiceImplTest { val follow = scheduleContext.props.props[ReceiveFollowJob.follow.name] assertEquals("https://follower.example.com", actor) assertEquals("https://example.com", targetActor) + //language=JSON assertEquals( - """{"type":"Follow","name":"Follow","object":"https://example.com","actor":"https://follower.example.com","@context":null}""", + """{"type":"Follow","name":"Follow","actor":"https://follower.example.com","object":"https://example.com","@context":null}""", follow ) }