mirror of https://github.com/usbharu/Hideout.git
feat: アプリケーションサービスの操作ログを残せるように
This commit is contained in:
parent
cf48ae651b
commit
a13fe45d0d
|
@ -16,6 +16,8 @@
|
|||
|
||||
package dev.usbharu.hideout.core.application.actor
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.config.ApplicationConfig
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||
|
@ -27,12 +29,13 @@ import dev.usbharu.hideout.core.domain.service.actor.local.LocalActorDomainServi
|
|||
import dev.usbharu.hideout.core.domain.service.userdetail.UserDetailDomainService
|
||||
import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService
|
||||
import dev.usbharu.hideout.core.infrastructure.factory.ActorFactoryImpl
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
import java.net.URI
|
||||
|
||||
@Service
|
||||
class RegisterLocalActorApplicationService(
|
||||
private val transaction: Transaction,
|
||||
transaction: Transaction,
|
||||
private val actorDomainService: LocalActorDomainService,
|
||||
private val actorRepository: ActorRepository,
|
||||
private val actorFactoryImpl: ActorFactoryImpl,
|
||||
|
@ -41,17 +44,17 @@ class RegisterLocalActorApplicationService(
|
|||
private val userDetailDomainService: UserDetailDomainService,
|
||||
private val userDetailRepository: UserDetailRepository,
|
||||
private val idGenerateService: IdGenerateService,
|
||||
) {
|
||||
suspend fun register(registerLocalActor: RegisterLocalActor): URI {
|
||||
return transaction.transaction {
|
||||
if (actorDomainService.usernameAlreadyUse(registerLocalActor.name)) {
|
||||
) : AbstractApplicationService<RegisterLocalActor, URI>(transaction, Companion.logger) {
|
||||
|
||||
override suspend fun internalExecute(command: RegisterLocalActor, executor: CommandExecutor): URI {
|
||||
if (actorDomainService.usernameAlreadyUse(command.name)) {
|
||||
// todo 適切な例外を考える
|
||||
throw Exception("Username already exists")
|
||||
}
|
||||
val instance = instanceRepository.findByUrl(applicationConfig.url.toURI())!!
|
||||
|
||||
val actor = actorFactoryImpl.createLocal(
|
||||
registerLocalActor.name,
|
||||
command.name,
|
||||
actorDomainService.generateKeyPair(),
|
||||
instance.id
|
||||
)
|
||||
|
@ -59,10 +62,13 @@ class RegisterLocalActorApplicationService(
|
|||
val userDetail = UserDetail.create(
|
||||
id = UserDetailId(idGenerateService.generateId()),
|
||||
actorId = actor.id,
|
||||
password = userDetailDomainService.hashPassword(registerLocalActor.password),
|
||||
password = userDetailDomainService.hashPassword(command.password),
|
||||
)
|
||||
userDetailRepository.save(userDetail)
|
||||
actor.url
|
||||
}
|
||||
return actor.url
|
||||
}
|
||||
|
||||
companion object {
|
||||
val logger = LoggerFactory.getLogger(RegisterLocalActorApplicationService::class.java)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.shared
|
||||
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import org.slf4j.Logger
|
||||
|
||||
abstract class AbstractApplicationService<T : Any, R>(
|
||||
protected val transaction: Transaction,
|
||||
protected val logger: Logger,
|
||||
) : ApplicationService<T, R> {
|
||||
override suspend fun execute(command: T, executor: CommandExecutor): R {
|
||||
return try {
|
||||
logger.debug("START ${command::class.simpleName} by $executor")
|
||||
val response = transaction.transaction<R> {
|
||||
internalExecute(command, executor)
|
||||
}
|
||||
logger.info("SUCCESS ${command::class.simpleName} by ${executor.executor}")
|
||||
response
|
||||
} catch (e: CancellationException) {
|
||||
logger.debug("Coroutine canceled", e)
|
||||
throw e
|
||||
} catch (e: Exception) {
|
||||
logger.warn("Command execution error", e)
|
||||
throw e
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected abstract suspend fun internalExecute(command: T, executor: CommandExecutor): R
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.shared
|
||||
|
||||
interface ApplicationService<T : Any, R> {
|
||||
suspend fun execute(command: T, executor: CommandExecutor): R
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.shared
|
||||
|
||||
interface CommandExecutor {
|
||||
val executor: String
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.springframework
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
|
||||
open class HttpCommandExecutor(
|
||||
override val executor: String,
|
||||
val ip: String,
|
||||
val userAgent: String,
|
||||
) : CommandExecutor {
|
||||
override fun toString(): String {
|
||||
return "HttpCommandExecutor(executor='$executor', ip='$ip', userAgent='$userAgent')"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.springframework
|
||||
|
||||
import org.springframework.security.core.context.SecurityContextHolder
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.web.context.request.RequestContextHolder
|
||||
import org.springframework.web.context.request.ServletRequestAttributes
|
||||
|
||||
|
||||
@Component
|
||||
class SpringMvcCommandExecutorFactory {
|
||||
fun getCommandExecutor(): HttpCommandExecutor {
|
||||
val name = SecurityContextHolder.getContext().authentication?.name ?: "ANONYMOUS"
|
||||
val request = (RequestContextHolder.currentRequestAttributes() as ServletRequestAttributes).request
|
||||
return HttpCommandExecutor(name, request.remoteAddr, request.getHeader("user-agent").orEmpty())
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ package dev.usbharu.hideout.core.interfaces.api.auth
|
|||
|
||||
import dev.usbharu.hideout.core.application.actor.RegisterLocalActor
|
||||
import dev.usbharu.hideout.core.application.actor.RegisterLocalActorApplicationService
|
||||
import dev.usbharu.hideout.core.infrastructure.springframework.SpringMvcCommandExecutorFactory
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import org.springframework.stereotype.Controller
|
||||
import org.springframework.validation.annotation.Validated
|
||||
|
@ -26,7 +27,10 @@ import org.springframework.web.bind.annotation.ModelAttribute
|
|||
import org.springframework.web.bind.annotation.PostMapping
|
||||
|
||||
@Controller
|
||||
class AuthController(private val registerLocalActorApplicationService: RegisterLocalActorApplicationService) {
|
||||
class AuthController(
|
||||
private val registerLocalActorApplicationService: RegisterLocalActorApplicationService,
|
||||
private val springMvcCommandExecutorFactory: SpringMvcCommandExecutorFactory,
|
||||
) {
|
||||
@GetMapping("/auth/sign_up")
|
||||
fun signUp(): String {
|
||||
return "sign_up"
|
||||
|
@ -35,7 +39,10 @@ class AuthController(private val registerLocalActorApplicationService: RegisterL
|
|||
@PostMapping("/auth/sign_up")
|
||||
suspend fun signUp(@Validated @ModelAttribute signUpForm: SignUpForm, request: HttpServletRequest): String {
|
||||
val registerLocalActor = RegisterLocalActor(signUpForm.username, signUpForm.password)
|
||||
val uri = registerLocalActorApplicationService.register(registerLocalActor)
|
||||
val uri = registerLocalActorApplicationService.execute(
|
||||
registerLocalActor,
|
||||
springMvcCommandExecutorFactory.getCommandExecutor()
|
||||
)
|
||||
request.login(signUpForm.username, signUpForm.password)
|
||||
return "redirect:$uri"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue