feat: UserBUilderを追加

This commit is contained in:
usbharu 2023-10-23 12:35:48 +09:00
parent 657936c3d9
commit 45e196edab
3 changed files with 128 additions and 7 deletions

View File

@ -1,7 +1,10 @@
package dev.usbharu.hideout.domain.model.hideout.entity
import dev.usbharu.hideout.config.ApplicationConfig
import dev.usbharu.hideout.config.CharacterLimit
import dev.usbharu.hideout.config.Config
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
import java.time.Instant
data class User private constructor(
@ -145,4 +148,121 @@ data class User private constructor(
)
}
}
@Component
class UserBuilder(private val characterLimit: CharacterLimit, private val applicationConfig: ApplicationConfig) {
private val logger = LoggerFactory.getLogger(UserBuilder::class.java)
@Suppress("LongParameterList", "FunctionMinLength", "LongMethod")
fun of(
id: Long,
name: String,
domain: String,
screenName: String,
description: String,
password: String? = null,
inbox: String,
outbox: String,
url: String,
publicKey: String,
privateKey: String? = null,
createdAt: Instant,
keyId: String,
following: String? = null,
followers: String? = null
): User {
// idは0未満ではいけない
require(id >= 0) { "id must be greater than or equal to 0." }
// nameは空文字以外を含める必要がある
require(name.isNotBlank()) { "name must contain non-blank characters." }
// nameは指定された長さ以下である必要がある
val limitedName = if (name.length >= characterLimit.account.id) {
logger.warn("name must not exceed ${characterLimit.account.id} characters.")
name.substring(0, characterLimit.account.id)
} else {
name
}
// domainは空文字以外を含める必要がある
require(domain.isNotBlank()) { "domain must contain non-blank characters." }
// domainは指定された長さ以下である必要がある
require(domain.length <= characterLimit.general.domain) {
"domain must not exceed ${characterLimit.general.domain} characters."
}
// screenNameは空文字以外を含める必要がある
require(screenName.isNotBlank()) { "screenName must contain non-blank characters." }
// screenNameは指定された長さ以下である必要がある
val limitedScreenName = if (screenName.length >= characterLimit.account.name) {
logger.warn("screenName must not exceed ${characterLimit.account.name} characters.")
screenName.substring(0, characterLimit.account.name)
} else {
screenName
}
// descriptionは指定された長さ以下である必要がある
val limitedDescription = if (description.length >= characterLimit.account.description) {
logger.warn("description must not exceed ${characterLimit.account.description} characters.")
description.substring(0, characterLimit.account.description)
} else {
description
}
// ローカルユーザーはpasswordとprivateKeyをnullにしてはいけない
if (domain == applicationConfig.url.host) {
requireNotNull(password) { "password and privateKey must not be null for local users." }
requireNotNull(privateKey) { "password and privateKey must not be null for local users." }
}
// urlは空文字以外を含める必要がある
require(url.isNotBlank()) { "url must contain non-blank characters." }
// urlは指定された長さ以下である必要がある
require(url.length <= characterLimit.general.url) {
"url must not exceed ${characterLimit.general.url} characters."
}
// inboxは空文字以外を含める必要がある
require(inbox.isNotBlank()) { "inbox must contain non-blank characters." }
// inboxは指定された長さ以下である必要がある
require(inbox.length <= characterLimit.general.url) {
"inbox must not exceed ${characterLimit.general.url} characters."
}
// outboxは空文字以外を含める必要がある
require(outbox.isNotBlank()) { "outbox must contain non-blank characters." }
// outboxは指定された長さ以下である必要がある
require(outbox.length <= characterLimit.general.url) {
"outbox must not exceed ${characterLimit.general.url} characters."
}
require(keyId.isNotBlank()) {
"keyId must contain non-blank characters."
}
return User(
id = id,
name = limitedName,
domain = domain,
screenName = limitedScreenName,
description = limitedDescription,
password = password,
inbox = inbox,
outbox = outbox,
url = url,
publicKey = publicKey,
privateKey = privateKey,
createdAt = createdAt,
keyId = keyId,
followers = followers,
following = following
)
}
}
}

View File

@ -9,7 +9,7 @@ import org.springframework.stereotype.Repository
import java.time.Instant
@Repository
class FollowerQueryServiceImpl : FollowerQueryService {
class FollowerQueryServiceImpl(private val userBuilder: User.UserBuilder) : FollowerQueryService {
override suspend fun findFollowersById(id: Long): List<User> {
val followers = Users.alias("FOLLOWERS")
return Users.innerJoin(
@ -41,7 +41,7 @@ class FollowerQueryServiceImpl : FollowerQueryService {
)
.select { Users.id eq id }
.map {
User.of(
userBuilder.of(
id = it[followers[Users.id]],
name = it[followers[Users.name]],
domain = it[followers[Users.domain]],
@ -92,7 +92,7 @@ class FollowerQueryServiceImpl : FollowerQueryService {
)
.select { Users.name eq name and (Users.domain eq domain) }
.map {
User.of(
userBuilder.of(
id = it[followers[Users.id]],
name = it[followers[Users.name]],
domain = it[followers[Users.domain]],
@ -143,7 +143,7 @@ class FollowerQueryServiceImpl : FollowerQueryService {
)
.select { followers[Users.id] eq id }
.map {
User.of(
userBuilder.of(
id = it[followers[Users.id]],
name = it[followers[Users.name]],
domain = it[followers[Users.domain]],
@ -194,7 +194,7 @@ class FollowerQueryServiceImpl : FollowerQueryService {
)
.select { followers[Users.name] eq name and (followers[Users.domain] eq domain) }
.map {
User.of(
userBuilder.of(
id = it[followers[Users.id]],
name = it[followers[Users.name]],
domain = it[followers[Users.domain]],

View File

@ -21,6 +21,7 @@ class UserServiceImpl(
private val apSendFollowService: APSendFollowService,
private val userQueryService: UserQueryService,
private val followerQueryService: FollowerQueryService,
private val userBuilder: User.UserBuilder,
private val applicationConfig: ApplicationConfig
) :
UserService {
@ -35,7 +36,7 @@ class UserServiceImpl(
val hashedPassword = userAuthService.hash(user.password)
val keyPair = userAuthService.generateKeyPair()
val userUrl = "${applicationConfig.url}/users/${user.name}"
val userEntity = User.of(
val userEntity = userBuilder.of(
id = nextId,
name = user.name,
domain = applicationConfig.url.host,
@ -57,7 +58,7 @@ class UserServiceImpl(
override suspend fun createRemoteUser(user: RemoteUserCreateDto): User {
val nextId = userRepository.nextId()
val userEntity = User.of(
val userEntity = userBuilder.of(
id = nextId,
name = user.name,
domain = user.domain,