Skip to content
Merged
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,6 @@ out/
.env.docker.dev

# Docker Data
/minio/
/minio/

/logs/
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import jakarta.servlet.http.Cookie
import jakarta.servlet.http.HttpServletResponse
import me.daegyeo.maru.auth.adaptor.`in`.web.dto.RegisterUserDto
import me.daegyeo.maru.auth.application.domain.AccessTokenPayload
import me.daegyeo.maru.auth.application.domain.CustomUserDetails
import me.daegyeo.maru.auth.application.port.`in`.GenerateJWTUseCase
import me.daegyeo.maru.auth.application.port.`in`.GetAuthInfoUseCase
import me.daegyeo.maru.auth.application.port.`in`.RegisterUserUseCase
import me.daegyeo.maru.auth.application.port.`in`.command.RegisterUserCommand
import me.daegyeo.maru.auth.application.port.`in`.result.AuthInfoResult
import me.daegyeo.maru.auth.constant.Auth
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.web.bind.annotation.*

@RestController
Expand All @@ -23,9 +25,9 @@ class AuthController(
@PreAuthorize("hasRole('USER')")
@GetMapping("/me")
fun getMyInfo(
@CookieValue(Auth.ACCESS_TOKEN_COOKIE) accessToken: String,
@AuthenticationPrincipal auth: CustomUserDetails,
): AuthInfoResult {
return getAuthInfoUseCase.getAuthInfo(accessToken)
return getAuthInfoUseCase.getAuthInfo(auth)
}

@PreAuthorize("permitAll()")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package me.daegyeo.maru.auth.application.domain

import me.daegyeo.maru.shared.constant.Vendor
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.userdetails.UserDetails
import java.time.ZonedDateTime
import java.util.UUID

class CustomUserDetails(private val email: String, val userId: UUID) : UserDetails {
class CustomUserDetails(
private val email: String,
val userId: UUID,
val nickname: String,
val vendor: Vendor,
val createdAt: ZonedDateTime,
) : UserDetails {
override fun getAuthorities(): Collection<GrantedAuthority> {
return listOf("ROLE_USER").map { SimpleGrantedAuthority(it) }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package me.daegyeo.maru.auth.application.port.`in`

import me.daegyeo.maru.auth.application.domain.CustomUserDetails
import me.daegyeo.maru.auth.application.port.`in`.result.AuthInfoResult

fun interface GetAuthInfoUseCase {
fun getAuthInfo(accessToken: String): AuthInfoResult
fun getAuthInfo(customUserDetails: CustomUserDetails): AuthInfoResult
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class CustomUserDetailsService(private val getUserUseCase: GetUserUseCase) : Cus
override fun loadUserByUsername(username: String?): UserDetails {
try {
val user = getUserUseCase.getUserByEmail(username!!)
return CustomUserDetails(user.email, user.userId)
return CustomUserDetails(user.email, user.userId, user.nickname, user.vendor, user.createdAt)
} catch (e: ServiceException) {
throw UsernameNotFoundException("User not found")
} catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import me.daegyeo.maru.auth.application.domain.AccessTokenPayload
import me.daegyeo.maru.auth.application.domain.RegisterTokenPayload
import me.daegyeo.maru.auth.application.port.`in`.GenerateJWTUseCase
import me.daegyeo.maru.shared.util.DateFormat
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import java.time.Instant
Expand All @@ -25,6 +26,8 @@ class GenerateJWTService : GenerateJWTUseCase {
@Value("\${jwt.register-token.expiration}")
private lateinit var registerTokenExpiration: String

private val logger = LoggerFactory.getLogger(this::class.java)

override fun generateAccessToken(payload: AccessTokenPayload): String {
val token =
Jwts.builder()
Expand All @@ -34,6 +37,7 @@ class GenerateJWTService : GenerateJWTUseCase {
.expiration(DateFormat.parseDurationToDate(accessTokenExpiration))
.signWith(Keys.hmacShaKeyFor(accessTokenSecret.toByteArray()))
.compact()
logger.info("Access Token을 생성했습니다. email: ${payload.email}")
return token
}

Expand All @@ -46,6 +50,7 @@ class GenerateJWTService : GenerateJWTUseCase {
.expiration(DateFormat.parseDurationToDate(registerTokenExpiration))
.signWith(Keys.hmacShaKeyFor(registerTokenSecret.toByteArray()))
.compact()
logger.info("Register Token을 생성했습니다. email: ${payload.email}")
return token
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
package me.daegyeo.maru.auth.application.service

import me.daegyeo.maru.auth.application.domain.CustomUserDetails
import me.daegyeo.maru.auth.application.port.`in`.GetAuthInfoUseCase
import me.daegyeo.maru.auth.application.port.`in`.ParseJWTUseCase
import me.daegyeo.maru.auth.application.port.`in`.result.AuthInfoResult
import me.daegyeo.maru.user.application.port.`in`.GetUserUseCase
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
class GetAuthInfoService(private val getUserUseCase: GetUserUseCase, private val parseJWTUseCase: ParseJWTUseCase) :
GetAuthInfoUseCase {
@Transactional(readOnly = true)
override fun getAuthInfo(accessToken: String): AuthInfoResult {
val payload = parseJWTUseCase.parseAccessToken(accessToken)
val user = getUserUseCase.getUserByEmail(payload.email)
class GetAuthInfoService : GetAuthInfoUseCase {
private val logger = LoggerFactory.getLogger(this::class.java)

override fun getAuthInfo(customUserDetails: CustomUserDetails): AuthInfoResult {
logger.info("User 인증 정보를 조회했습니다. ${customUserDetails.username}")
return AuthInfoResult(
email = user.email,
nickname = user.nickname,
vendor = user.vendor,
createdAt = user.createdAt,
email = customUserDetails.username,
nickname = customUserDetails.nickname,
vendor = customUserDetails.vendor,
createdAt = customUserDetails.createdAt,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import me.daegyeo.maru.shared.constant.Vendor
import me.daegyeo.maru.shared.exception.ServiceException
import me.daegyeo.maru.user.application.error.UserError
import me.daegyeo.maru.user.application.port.`in`.GetUserUseCase
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Value
import org.springframework.security.core.Authentication
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken
Expand All @@ -30,6 +31,8 @@ class OAuthUserSuccessHandler(
@Value("\${oauth.success-url}")
private lateinit var successUrl: String

private val logger = LoggerFactory.getLogger(this::class.java)

override fun onAuthenticationSuccess(
request: HttpServletRequest?,
response: HttpServletResponse?,
Expand Down Expand Up @@ -66,6 +69,8 @@ class OAuthUserSuccessHandler(
}
response?.addCookie(tokenCookie)
response?.sendRedirect(successUrl)

logger.info("소셜 로그인에 성공했습니다. $email")
} catch (e: Exception) {
if (e is ServiceException && e.error == UserError.USER_NOT_FOUND) {
val registerToken =
Expand All @@ -77,6 +82,8 @@ class OAuthUserSuccessHandler(
)

response?.sendRedirect("$redirectUrl?token=$registerToken")

logger.info("소셜 로그인으로 신규 가입을 진행했습니다. $email")
} else {
throw e
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import me.daegyeo.maru.auth.application.port.`in`.command.RegisterUserCommand
import me.daegyeo.maru.auth.application.port.`in`.result.RegisterUserResult
import me.daegyeo.maru.user.application.port.`in`.CreateUserUseCase
import me.daegyeo.maru.user.application.port.`in`.command.CreateUserUseCaseCommand
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

Expand All @@ -14,6 +15,8 @@ class RegisterUserService(
private val parseJWTUseCase: ParseJWTUseCase,
private val createUserUseCase: CreateUserUseCase,
) : RegisterUserUseCase {
private val logger = LoggerFactory.getLogger(this::class.java)

@Transactional
override fun registerUser(input: RegisterUserCommand): RegisterUserResult {
val payload = parseJWTUseCase.parseRegisterToken(input.registerToken)
Expand All @@ -26,6 +29,8 @@ class RegisterUserService(
),
)

logger.info("회원가입을 했습니다. ${payload.email}")

return RegisterUserResult(
email = payload.email,
vendor = payload.vendor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class DiaryEntity(
@Column(columnDefinition = "TEXT", nullable = false)
var content: String,

@ManyToOne(targetEntity = UserEntity::class)
@ManyToOne(targetEntity = UserEntity::class, fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false)
val user: UserEntity? = null,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import me.daegyeo.maru.diary.application.port.out.dto.CreateDiaryFileDto
import me.daegyeo.maru.file.application.port.out.ReadFilePort
import me.daegyeo.maru.file.application.port.out.UpdateFilePort
import me.daegyeo.maru.file.constant.FileStatus
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service

@Service
Expand All @@ -17,6 +18,8 @@ class AttachDiaryFileFromContentService(
private val createDiaryFilePort: CreateDiaryFilePort,
private val getImagePathInContentUseCase: GetImagePathInContentUseCase,
) : AttachDiaryFileFromContentUseCase {
private val logger = LoggerFactory.getLogger(this::class.java)

override fun attachDiaryFileFromContent(input: AttachDiaryFileFromContentCommand) {
val imagePaths = getImagePathInContentUseCase.getImagePathInContent(input.content)
imagePaths.forEach {
Expand All @@ -29,5 +32,9 @@ class AttachDiaryFileFromContentService(
),
)
}

if (imagePaths.isNotEmpty()) {
logger.info("DiaryFile 데이터를 생성했습니다. diaryId: ${input.diaryId}")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import me.daegyeo.maru.diary.application.port.`in`.command.CreateDiaryCommand
import me.daegyeo.maru.diary.application.port.out.CreateDiaryPort
import me.daegyeo.maru.diary.application.port.out.dto.CreateDiaryDto
import me.daegyeo.maru.user.application.port.`in`.GetUserUseCase
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

Expand All @@ -20,6 +21,8 @@ class CreateDiaryService(
private val attachDiaryFileFromContentUseCase: AttachDiaryFileFromContentUseCase,
) :
CreateDiaryUseCase {
private val logger = LoggerFactory.getLogger(this::class.java)

@Transactional
override fun createDiary(input: CreateDiaryCommand): Diary {
val user = getUserUseCase.getUser(input.userId)
Expand All @@ -42,6 +45,8 @@ class CreateDiaryService(
),
)

logger.info("Diary 데이터를 생성했습니다. ${diary.diaryId}")

return diary.let {
it.content = ""
it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import me.daegyeo.maru.diary.application.port.out.ReadAllDiaryFilePort
import me.daegyeo.maru.file.application.port.out.DeleteFilePort
import me.daegyeo.maru.shared.error.CommonError
import me.daegyeo.maru.shared.exception.ServiceException
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
Expand All @@ -24,18 +25,19 @@ class DeleteDiaryService(
private val deleteDiaryFilePort: DeleteDiaryFilePort,
private val deleteFilePort: DeleteFilePort,
private val minioClient: MinioClient,
) :
DeleteDiaryUseCase {
) : DeleteDiaryUseCase {
@Value("\${minio.bucket-name}")
private lateinit var bucket: String

private val logger = LoggerFactory.getLogger(this::class.java)

@Transactional
override fun deleteDiary(
diaryId: Long,
userId: UUID,
): Boolean {
val diary = getDiaryUseCase.getDiaryByDiaryId(diaryId, userId)
return diary.let {
diary.let {
val deletedFiles = readAllDiaryFilePort.readAllDiaryFileByDiaryIdWithFile(it.diaryId)
val deletedObjects = deletedFiles.map { diaryFile -> DeleteObject(diaryFile.file.path) }

Expand All @@ -50,10 +52,11 @@ class DeleteDiaryService(
try {
val error = result.get()
if (error != null) {
// TODO: log error
logger.error("Diary 데이터와 연결된 File 데이터 삭제 중 오류가 발생했습니다. ${error.message()}")
throw ServiceException(CommonError.INTERNAL_SERVER_ERROR)
}
} catch (e: Exception) {
logger.error("Diary 데이터와 연결된 File 데이터 삭제 중 오류가 발생했습니다.")
e.printStackTrace()
throw ServiceException(CommonError.INTERNAL_SERVER_ERROR)
}
Expand All @@ -64,6 +67,9 @@ class DeleteDiaryService(
deleteFilePort.deleteFile(it.fileId)
}
deleteDiaryPort.deleteDiary(it.diaryId)

logger.info("Diary 데이터와 관련 파일을 삭제했습니다. ${it.diaryId}")
}
return true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@ package me.daegyeo.maru.diary.application.service
import me.daegyeo.maru.diary.application.domain.Diary
import me.daegyeo.maru.diary.application.port.`in`.GetAllDiaryUseCase
import me.daegyeo.maru.diary.application.port.out.ReadAllDiaryPort
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.UUID

@Service
class GetAllDiaryService(private val readAllDiaryPort: ReadAllDiaryPort) : GetAllDiaryUseCase {
private val logger = LoggerFactory.getLogger(this::class.java)

@Transactional(readOnly = true)
override fun getAllDiaryByUserId(userId: UUID): List<Diary> {
logger.info("User의 전체 Diary 데이터를 조회했습니다. userId: $userId")
return readAllDiaryPort.readAllDiaryByUserId(userId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import me.daegyeo.maru.diary.application.port.`in`.DecryptDiaryUseCase
import me.daegyeo.maru.diary.application.port.`in`.GetDiaryUseCase
import me.daegyeo.maru.diary.application.port.out.ReadDiaryPort
import me.daegyeo.maru.shared.exception.ServiceException
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.UUID

@Service
class GetDiaryService(private val readDiaryPort: ReadDiaryPort, private val decryptDiaryUseCase: DecryptDiaryUseCase) :
GetDiaryUseCase {
private val logger = LoggerFactory.getLogger(this::class.java)

@Transactional(readOnly = true)
override fun getDiaryByDiaryId(
diaryId: Long,
Expand All @@ -23,6 +26,7 @@ class GetDiaryService(private val readDiaryPort: ReadDiaryPort, private val decr
throw ServiceException(DiaryError.DIARY_IS_NOT_OWNED)
}
val decryptedContent = decryptDiaryUseCase.decryptDiary(result.content)
logger.info("Diary 데이터를 조회했습니다. diaryId: $diaryId")
return Diary(
diaryId = result.diaryId,
title = result.title,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import me.daegyeo.maru.diary.application.port.out.ReadAllDiaryFilePort
import me.daegyeo.maru.diary.application.port.out.UpdateDiaryPort
import me.daegyeo.maru.file.application.port.out.UpdateFilePort
import me.daegyeo.maru.file.constant.FileStatus
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.UUID
Expand All @@ -25,6 +26,8 @@ class UpdateDiaryService(
private val encryptDiaryUseCase: EncryptDiaryUseCase,
private val attachDiaryFileFromContentUseCase: AttachDiaryFileFromContentUseCase,
) : UpdateDiaryUseCase {
private val logger = LoggerFactory.getLogger(this::class.java)

@Transactional
override fun updateDiary(
diaryId: Long,
Expand Down Expand Up @@ -53,6 +56,9 @@ class UpdateDiaryService(
title = input.title,
content = encryptedContent,
)

logger.info("Diary 데이터를 수정했습니다. diaryId: $diaryId")

return true
}
}
Loading