mirror of https://github.com/usbharu/Hideout.git
feat: DBにfollowing,followersとkeyidを追加
This commit is contained in:
parent
72289625b4
commit
34ed98c82b
|
@ -9,6 +9,8 @@ open class Person : Object {
|
|||
private var icon: Image? = null
|
||||
var publicKey: Key? = null
|
||||
var endpoints: Map<String, String> = emptyMap()
|
||||
var following: String? = null
|
||||
var followers: String? = null
|
||||
|
||||
protected constructor() : super()
|
||||
|
||||
|
@ -24,7 +26,9 @@ open class Person : Object {
|
|||
url: String?,
|
||||
icon: Image?,
|
||||
publicKey: Key?,
|
||||
endpoints: Map<String, String> = emptyMap()
|
||||
endpoints: Map<String, String> = emptyMap(),
|
||||
followers: String?,
|
||||
following: String?
|
||||
) : super(add(type, "Person"), name, id = id) {
|
||||
this.preferredUsername = preferredUsername
|
||||
this.summary = summary
|
||||
|
@ -34,6 +38,8 @@ open class Person : Object {
|
|||
this.icon = icon
|
||||
this.publicKey = publicKey
|
||||
this.endpoints = endpoints
|
||||
this.followers = followers
|
||||
this.following = following
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
|
|
|
@ -9,4 +9,7 @@ data class RemoteUserCreateDto(
|
|||
val outbox: String,
|
||||
val url: String,
|
||||
val publicKey: String,
|
||||
val keyId: String,
|
||||
val followers: String?,
|
||||
val following: String?
|
||||
)
|
||||
|
|
|
@ -16,15 +16,17 @@ data class User private constructor(
|
|||
val url: String,
|
||||
val publicKey: String,
|
||||
val privateKey: String? = null,
|
||||
val createdAt: Instant
|
||||
val createdAt: Instant,
|
||||
val keyId: String,
|
||||
val followers: String? = null,
|
||||
val following: String? = null
|
||||
) {
|
||||
override fun toString(): String {
|
||||
return "User(id=$id, name='$name', domain='$domain', screenName='$screenName', description='$description'," +
|
||||
" password=****, inbox='$inbox', outbox='$outbox', url='$url', publicKey='$publicKey'," +
|
||||
" privateKey=****, createdAt=$createdAt)"
|
||||
return "User(id=$id, name='$name', domain='$domain', screenName='$screenName', description='$description', password=$password, inbox='$inbox', outbox='$outbox', url='$url', publicKey='$publicKey', privateKey=$privateKey, createdAt=$createdAt, keyId='$keyId', followers=$followers, following=$following)"
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val logger = LoggerFactory.getLogger(User::class.java)
|
||||
|
||||
@Suppress("LongParameterList", "FunctionMinLength")
|
||||
|
@ -40,7 +42,10 @@ data class User private constructor(
|
|||
url: String,
|
||||
publicKey: String,
|
||||
privateKey: String? = null,
|
||||
createdAt: Instant
|
||||
createdAt: Instant,
|
||||
keyId: String,
|
||||
following: String? = null,
|
||||
followers: String? = null
|
||||
): User {
|
||||
val characterLimit = Config.configData.characterLimit
|
||||
|
||||
|
@ -115,6 +120,10 @@ data class User private constructor(
|
|||
"outbox must not exceed ${characterLimit.general.url} characters."
|
||||
}
|
||||
|
||||
require(keyId.isNotBlank()) {
|
||||
"keyId must contain non-blank characters."
|
||||
}
|
||||
|
||||
return User(
|
||||
id = id,
|
||||
name = limitedName,
|
||||
|
@ -127,7 +136,10 @@ data class User private constructor(
|
|||
url = url,
|
||||
publicKey = publicKey,
|
||||
privateKey = privateKey,
|
||||
createdAt = createdAt
|
||||
createdAt = createdAt,
|
||||
keyId = keyId,
|
||||
followers = followers,
|
||||
following = following
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,10 @@ class FollowerQueryServiceImpl : FollowerQueryService {
|
|||
followers[Users.url],
|
||||
followers[Users.publicKey],
|
||||
followers[Users.privateKey],
|
||||
followers[Users.createdAt]
|
||||
followers[Users.createdAt],
|
||||
followers[Users.keyId],
|
||||
followers[Users.following],
|
||||
followers[Users.followers]
|
||||
)
|
||||
.select { Users.id eq id }
|
||||
.map {
|
||||
|
@ -50,7 +53,10 @@ class FollowerQueryServiceImpl : FollowerQueryService {
|
|||
url = it[followers[Users.url]],
|
||||
publicKey = it[followers[Users.publicKey]],
|
||||
privateKey = it[followers[Users.privateKey]],
|
||||
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]])
|
||||
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]),
|
||||
keyId = it[followers[Users.keyId]],
|
||||
followers = it[followers[Users.followers]],
|
||||
following = it[followers[Users.following]]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +85,10 @@ class FollowerQueryServiceImpl : FollowerQueryService {
|
|||
followers[Users.url],
|
||||
followers[Users.publicKey],
|
||||
followers[Users.privateKey],
|
||||
followers[Users.createdAt]
|
||||
followers[Users.createdAt],
|
||||
followers[Users.keyId],
|
||||
followers[Users.following],
|
||||
followers[Users.followers]
|
||||
)
|
||||
.select { Users.name eq name and (Users.domain eq domain) }
|
||||
.map {
|
||||
|
@ -95,7 +104,10 @@ class FollowerQueryServiceImpl : FollowerQueryService {
|
|||
url = it[followers[Users.url]],
|
||||
publicKey = it[followers[Users.publicKey]],
|
||||
privateKey = it[followers[Users.privateKey]],
|
||||
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]])
|
||||
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]),
|
||||
keyId = it[followers[Users.keyId]],
|
||||
followers = it[followers[Users.followers]],
|
||||
following = it[followers[Users.following]]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +136,10 @@ class FollowerQueryServiceImpl : FollowerQueryService {
|
|||
followers[Users.url],
|
||||
followers[Users.publicKey],
|
||||
followers[Users.privateKey],
|
||||
followers[Users.createdAt]
|
||||
followers[Users.createdAt],
|
||||
followers[Users.keyId],
|
||||
followers[Users.following],
|
||||
followers[Users.followers]
|
||||
)
|
||||
.select { followers[Users.id] eq id }
|
||||
.map {
|
||||
|
@ -140,7 +155,10 @@ class FollowerQueryServiceImpl : FollowerQueryService {
|
|||
url = it[followers[Users.url]],
|
||||
publicKey = it[followers[Users.publicKey]],
|
||||
privateKey = it[followers[Users.privateKey]],
|
||||
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]])
|
||||
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]),
|
||||
keyId = it[followers[Users.keyId]],
|
||||
followers = it[followers[Users.followers]],
|
||||
following = it[followers[Users.following]]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +187,10 @@ class FollowerQueryServiceImpl : FollowerQueryService {
|
|||
followers[Users.url],
|
||||
followers[Users.publicKey],
|
||||
followers[Users.privateKey],
|
||||
followers[Users.createdAt]
|
||||
followers[Users.createdAt],
|
||||
followers[Users.keyId],
|
||||
followers[Users.following],
|
||||
followers[Users.followers]
|
||||
)
|
||||
.select { followers[Users.name] eq name and (followers[Users.domain] eq domain) }
|
||||
.map {
|
||||
|
@ -185,7 +206,10 @@ class FollowerQueryServiceImpl : FollowerQueryService {
|
|||
url = it[followers[Users.url]],
|
||||
publicKey = it[followers[Users.publicKey]],
|
||||
privateKey = it[followers[Users.privateKey]],
|
||||
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]])
|
||||
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]),
|
||||
keyId = it[followers[Users.keyId]],
|
||||
followers = it[followers[Users.followers]],
|
||||
following = it[followers[Users.following]]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,6 +89,9 @@ object Users : Table("users") {
|
|||
length = Config.configData.characterLimit.general.privateKey
|
||||
).nullable()
|
||||
val createdAt: Column<Long> = long("created_at")
|
||||
val keyId = varchar("key_id", length = Config.configData.characterLimit.general.url)
|
||||
val following = varchar("following", length = Config.configData.characterLimit.general.url).nullable()
|
||||
val followers = varchar("followers", length = Config.configData.characterLimit.general.url).nullable()
|
||||
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||
|
||||
|
@ -110,7 +113,10 @@ fun ResultRow.toUser(): User {
|
|||
url = this[Users.url],
|
||||
publicKey = this[Users.publicKey],
|
||||
privateKey = this[Users.privateKey],
|
||||
createdAt = Instant.ofEpochMilli((this[Users.createdAt]))
|
||||
createdAt = Instant.ofEpochMilli((this[Users.createdAt])),
|
||||
keyId = this[Users.keyId],
|
||||
followers = this[Users.followers],
|
||||
following = this[Users.following]
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -64,11 +64,13 @@ class APUserServiceImpl(
|
|||
publicKey = Key(
|
||||
type = emptyList(),
|
||||
name = "Public Key",
|
||||
id = "$userUrl#pubkey",
|
||||
id = userEntity.keyId,
|
||||
owner = userUrl,
|
||||
publicKeyPem = userEntity.publicKey
|
||||
),
|
||||
endpoints = mapOf("sharedInbox" to "${applicationConfig.url}/inbox")
|
||||
endpoints = mapOf("sharedInbox" to "${applicationConfig.url}/inbox"),
|
||||
followers = userEntity.followers,
|
||||
following = userEntity.following
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -96,11 +98,13 @@ class APUserServiceImpl(
|
|||
publicKey = Key(
|
||||
type = emptyList(),
|
||||
name = "Public Key",
|
||||
id = "$url#pubkey",
|
||||
id = userEntity.keyId,
|
||||
owner = url,
|
||||
publicKeyPem = userEntity.publicKey
|
||||
),
|
||||
endpoints = mapOf("sharedInbox" to "${applicationConfig.url}/inbox")
|
||||
endpoints = mapOf("sharedInbox" to "${applicationConfig.url}/inbox"),
|
||||
followers = userEntity.followers,
|
||||
following = userEntity.following
|
||||
) to userEntity
|
||||
} catch (ignore: FailedToGetResourcesException) {
|
||||
val person = apResourceResolveService.resolve<Person>(url, null as Long?)
|
||||
|
@ -118,6 +122,9 @@ class APUserServiceImpl(
|
|||
url = url,
|
||||
publicKey = person.publicKey?.publicKeyPem
|
||||
?: throw IllegalActivityPubObjectException("publicKey is null"),
|
||||
keyId = person.publicKey?.id ?: throw IllegalActivityPubObjectException("publicKey keyId is null"),
|
||||
following = person.following,
|
||||
followers = person.followers
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ class UserServiceImpl(
|
|||
val nextId = userRepository.nextId()
|
||||
val hashedPassword = userAuthService.hash(user.password)
|
||||
val keyPair = userAuthService.generateKeyPair()
|
||||
val userUrl = "${applicationConfig.url}/users/${user.name}"
|
||||
val userEntity = User.of(
|
||||
id = nextId,
|
||||
name = user.name,
|
||||
|
@ -41,12 +42,15 @@ class UserServiceImpl(
|
|||
screenName = user.screenName,
|
||||
description = user.description,
|
||||
password = hashedPassword,
|
||||
inbox = "${applicationConfig.url}/users/${user.name}/inbox",
|
||||
outbox = "${applicationConfig.url}/users/${user.name}/outbox",
|
||||
url = "${applicationConfig.url}/users/${user.name}",
|
||||
inbox = "$userUrl/inbox",
|
||||
outbox = "$userUrl/outbox",
|
||||
url = userUrl,
|
||||
publicKey = keyPair.public.toPem(),
|
||||
privateKey = keyPair.private.toPem(),
|
||||
createdAt = Instant.now()
|
||||
createdAt = Instant.now(),
|
||||
following = "$userUrl/following",
|
||||
followers = "$userUrl/followers",
|
||||
keyId = "$userUrl#pubkey"
|
||||
)
|
||||
return userRepository.save(userEntity)
|
||||
}
|
||||
|
@ -63,7 +67,10 @@ class UserServiceImpl(
|
|||
outbox = user.outbox,
|
||||
url = user.url,
|
||||
publicKey = user.publicKey,
|
||||
createdAt = Instant.now()
|
||||
createdAt = Instant.now(),
|
||||
followers = user.followers,
|
||||
following = user.following,
|
||||
keyId = user.keyId
|
||||
)
|
||||
return try {
|
||||
userRepository.save(userEntity)
|
||||
|
|
|
@ -48,7 +48,8 @@ class APNoteServiceImplTest {
|
|||
"https://follower.example.com",
|
||||
"https://follower.example.com",
|
||||
publicKey = "",
|
||||
createdAt = Instant.now()
|
||||
createdAt = Instant.now(),
|
||||
keyId = "a"
|
||||
),
|
||||
User.of(
|
||||
3L,
|
||||
|
@ -61,7 +62,8 @@ class APNoteServiceImplTest {
|
|||
"https://follower2.example.com",
|
||||
"https://follower2.example.com",
|
||||
publicKey = "",
|
||||
createdAt = Instant.now()
|
||||
createdAt = Instant.now(),
|
||||
keyId = "a"
|
||||
)
|
||||
)
|
||||
val userQueryService = mock<UserQueryService> {
|
||||
|
@ -77,7 +79,8 @@ class APNoteServiceImplTest {
|
|||
"https://example.com",
|
||||
publicKey = "",
|
||||
privateKey = "a",
|
||||
createdAt = Instant.now()
|
||||
createdAt = Instant.now(),
|
||||
keyId = "a"
|
||||
)
|
||||
}
|
||||
val followerQueryService = mock<FollowerQueryService> {
|
||||
|
|
|
@ -102,7 +102,9 @@ class APReceiveFollowServiceImplTest {
|
|||
id = "https://follower.example.com#main-key",
|
||||
owner = "https://follower.example.com",
|
||||
publicKeyPem = "BEGIN PUBLIC KEY...END PUBLIC KEY",
|
||||
)
|
||||
),
|
||||
followers = "",
|
||||
following = ""
|
||||
|
||||
)
|
||||
val apUserService = mock<APUserService> {
|
||||
|
@ -120,7 +122,8 @@ class APReceiveFollowServiceImplTest {
|
|||
outbox = "https://example.com/outbox",
|
||||
url = "https://example.com",
|
||||
publicKey = "",
|
||||
createdAt = Instant.now()
|
||||
createdAt = Instant.now(),
|
||||
keyId = "a"
|
||||
)
|
||||
onBlocking { findByUrl(eq("https://follower.example.com")) } doReturn
|
||||
User.of(
|
||||
|
@ -133,7 +136,8 @@ class APReceiveFollowServiceImplTest {
|
|||
outbox = "https://follower.example.com/outbox",
|
||||
url = "https://follower.example.com",
|
||||
publicKey = "",
|
||||
createdAt = Instant.now()
|
||||
createdAt = Instant.now(),
|
||||
keyId = "a"
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,8 @@ class APResourceResolveServiceImplTest {
|
|||
"https://follower.example.com",
|
||||
"https://follower.example.com",
|
||||
publicKey = "",
|
||||
createdAt = Instant.now()
|
||||
createdAt = Instant.now(),
|
||||
keyId = ""
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -82,7 +83,8 @@ class APResourceResolveServiceImplTest {
|
|||
"https://follower.example.com",
|
||||
"https://follower.example.com",
|
||||
publicKey = "",
|
||||
createdAt = Instant.now()
|
||||
createdAt = Instant.now(),
|
||||
keyId = ""
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -120,7 +122,8 @@ class APResourceResolveServiceImplTest {
|
|||
"https://follower.example.com",
|
||||
"https://follower.example.com",
|
||||
publicKey = "",
|
||||
createdAt = Instant.now()
|
||||
createdAt = Instant.now(),
|
||||
keyId = ""
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -169,7 +172,8 @@ class APResourceResolveServiceImplTest {
|
|||
"https://follower.example.com",
|
||||
"https://follower.example.com",
|
||||
publicKey = "",
|
||||
createdAt = Instant.now()
|
||||
createdAt = Instant.now(),
|
||||
keyId = ""
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -58,14 +58,17 @@ class UserServiceTest {
|
|||
}
|
||||
val userService = UserServiceImpl(userRepository, mock(), mock(), mock(), mock(), testApplicationConfig)
|
||||
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-----"
|
||||
name = "test",
|
||||
domain = "example.com",
|
||||
screenName = "testUser",
|
||||
description = "test user",
|
||||
inbox = "https://example.com/inbox",
|
||||
outbox = "https://example.com/outbox",
|
||||
url = "https://example.com",
|
||||
publicKey = "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----",
|
||||
keyId = "a",
|
||||
following = "",
|
||||
followers = ""
|
||||
)
|
||||
userService.createRemoteUser(user)
|
||||
verify(userRepository, times(1)).save(any())
|
||||
|
|
Loading…
Reference in New Issue