Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge: 데이터 암호화 구현 #493

Closed
wants to merge 13 commits into from
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ object Dependencies {
// aws
const val SPRING_AWS = "org.springframework.cloud:spring-cloud-starter-aws:${DependencyVersions.AWS_VERSION}"
const val AWS_SES = "com.amazonaws:aws-java-sdk-ses:${DependencyVersions.SES_VERSION}"
const val AWS_KMS = "com.amazonaws:aws-java-sdk-kms:${DependencyVersions.KMS_VERSION}"

// test
const val SPRING_TEST = "org.springframework.boot:spring-boot-starter-test:${PluginVersions.SPRING_BOOT_VERSION}"
Expand Down
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/DependencyVersions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ object DependencyVersions {
const val JWT_VERSION = "0.9.1"
const val AWS_VERSION = "2.2.6.RELEASE"
const val SES_VERSION = "1.11.852"
const val KMS_VERSION ="1.12.464"
const val REDIS_VERSION = "2.7.2"
const val SERVLET_VERSION = "4.0.1"
const val UUID_TIME_VERSION = "3.1.4"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package team.aliens.dms.common.model

import java.util.UUID

data class SchoolSecret(
val schoolId: UUID,
val secretKey: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ interface SecurityService {
fun getCurrentUserId(): UUID

fun checkIsPasswordMatches(rawPassword: String, encodedPassword: String)

fun createSchoolSecretBySchoolId(schoolId: UUID)
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package team.aliens.dms.common.service.security

import java.util.UUID
import team.aliens.dms.common.annotation.Service
import team.aliens.dms.common.model.SchoolSecret
import team.aliens.dms.common.spi.SchoolSecretPort
import team.aliens.dms.common.spi.SecurityPort
import team.aliens.dms.common.util.StringUtil
import team.aliens.dms.domain.auth.exception.PasswordMismatchException

@Service
class SecurityServiceImpl(
private val securityPort: SecurityPort
private val securityPort: SecurityPort,
private val schoolSecretPort: SchoolSecretPort
) : SecurityService {

override fun encodePassword(password: String) =
Expand All @@ -20,4 +25,13 @@ class SecurityServiceImpl(
throw PasswordMismatchException
}
}

override fun createSchoolSecretBySchoolId(schoolId: UUID) {
schoolSecretPort.saveSchoolSecret(
SchoolSecret(
schoolId = schoolId,
secretKey = StringUtil.randomKey()
)
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package team.aliens.dms.common.spi

interface EncryptPort {

fun symmetricEncrypt(secretKey: String, plainText: String): String

fun symmetricDecrypt(secretKey: String, cipherText: String): String

fun asymmetricEncrypt(plainText: String): String

fun asymmetricDecrypt(cipherText: String): String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package team.aliens.dms.common.spi

import java.util.UUID
import team.aliens.dms.common.model.SchoolSecret

interface SchoolSecretPort {

fun saveSchoolSecret(schoolSecret: SchoolSecret)

fun querySchoolSecretBySchoolId(schoolId: UUID): String?
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package team.aliens.dms.common.util

import java.security.SecureRandom
import java.util.Base64

object StringUtil {

Expand All @@ -18,17 +19,23 @@ object StringUtil {
return sb.toString()
}

private val RANDOM = SecureRandom()

fun randomNumber(number: Int): String {
val random = SecureRandom()
val codeList: List<Char> = listOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
val authCodeList: MutableList<String> = mutableListOf()

for (i: Int in 0 until number) {
authCodeList.add(i, codeList[random.nextInt(codeList.size)].toString())
authCodeList.add(i, codeList[RANDOM.nextInt(codeList.size)].toString())
}

return authCodeList.toString().replace("[^0-9]".toRegex(), "")
}

fun randomKey(byteSize: Int = 24): String =
Base64.getUrlEncoder().encodeToString(
ByteArray(byteSize).also { RANDOM.nextBytes(it) }
)

fun <T> List<T>.toStringWithoutBracket() = toString().replace("[\\[\\]]".toRegex(), "")
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import team.aliens.dms.domain.student.model.Student
import team.aliens.dms.domain.tag.model.Tag
import java.util.UUID

data class StudentWithTag(
open class StudentWithTag(
val id: UUID,
val name: String,
open val name: String,
val grade: Int,
val classRoom: Int,
val number: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package team.aliens.dms.domain.point.spi.vo
import team.aliens.dms.domain.point.model.PointType
import team.aliens.dms.domain.student.model.Student

data class StudentWithPointVO(
val name: String,
open class StudentWithPointVO(
open val name: String,
val grade: Int,
val classRoom: Int,
val number: Int,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package team.aliens.dms.domain.room.service

import org.springframework.stereotype.Service
import team.aliens.dms.common.annotation.Service

@Service
class RoomService(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package team.aliens.dms.domain.school.dto

import java.time.LocalDate
import java.util.UUID
import team.aliens.dms.common.util.StringUtil
import team.aliens.dms.domain.school.model.AvailableFeature
import team.aliens.dms.domain.school.model.School

class CreateSchoolRequest(
val schoolName: String,
val schoolAddress: String,
val mealService: Boolean,
val noticeService: Boolean,
val pointService: Boolean,
val studyRoomService: Boolean,
val remainService: Boolean
) {
fun toSchool() =
School(
name = schoolName,
code = StringUtil.randomNumber(School.SCHOOL_CODE_SIZE),
question = "우리 학교 이름은?",
answer = schoolName,
address = schoolAddress,
contractStartedAt = LocalDate.now()
)

fun toAvailableFeature(schoolId: UUID) =
AvailableFeature(
schoolId = schoolId,
mealService = mealService,
noticeService = noticeService,
pointService = pointService,
studyRoomService = studyRoomService,
remainService = remainService
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ data class School(

val contractStartedAt: LocalDate,

val contractEndedAt: LocalDate?
val contractEndedAt: LocalDate? = null

) {
companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package team.aliens.dms.domain.school.service

import team.aliens.dms.domain.school.model.AvailableFeature
import team.aliens.dms.domain.school.model.School

interface CommandSchoolService {

fun saveSchool(school: School): School

fun saveAvailableFeature(availableFeature: AvailableFeature): AvailableFeature
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package team.aliens.dms.domain.school.service

import team.aliens.dms.common.annotation.Service
import team.aliens.dms.domain.school.model.AvailableFeature
import team.aliens.dms.domain.school.model.School
import team.aliens.dms.domain.school.spi.CommandSchoolPort

Expand All @@ -11,4 +12,7 @@ class CommandSchoolServiceImpl(

override fun saveSchool(school: School) =
commandSchoolPort.saveSchool(school)

override fun saveAvailableFeature(availableFeature: AvailableFeature) =
commandSchoolPort.saveAvailableFeature(availableFeature)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package team.aliens.dms.domain.school.spi

import team.aliens.dms.domain.school.model.AvailableFeature
import team.aliens.dms.domain.school.model.School

interface CommandSchoolPort {

fun saveSchool(school: School): School

fun saveAvailableFeature(availableFeature: AvailableFeature): AvailableFeature
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package team.aliens.dms.domain.school.usecase

import team.aliens.dms.common.annotation.UseCase
import team.aliens.dms.common.service.security.SecurityService
import team.aliens.dms.domain.school.dto.CreateSchoolRequest
import team.aliens.dms.domain.school.service.SchoolService

@UseCase
class CreateSchoolUseCase(
private val schoolService: SchoolService,
private val securityService: SecurityService
) {

fun execute(request: CreateSchoolRequest) {
val school = schoolService.saveSchool(
request.toSchool()
)
schoolService.saveAvailableFeature(request.toAvailableFeature(school.id))
securityService.createSchoolSecretBySchoolId(school.id)
}
}
6 changes: 5 additions & 1 deletion dms-infrastructure/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ dependencies {
implementation(Dependencies.JWT)

// aws
implementation(Dependencies.AWS_SES)
implementation(Dependencies.SPRING_AWS)
implementation(Dependencies.AWS_SES)
implementation(Dependencies.AWS_KMS)

// configuration
kapt(Dependencies.CONFIGURATION_PROCESSOR)
Expand All @@ -48,6 +49,9 @@ dependencies {

// logging
implementation(Dependencies.SENTRY)

// redis
implementation(Dependencies.REDIS)
}

kapt {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package team.aliens.dms.global.config

import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.EnableAspectJAutoProxy

@Configuration
@EnableAspectJAutoProxy(exposeProxy = true)
class AspectjConfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package team.aliens.dms.global.config

import com.fasterxml.jackson.databind.ObjectMapper
import java.time.Duration
import org.springframework.cache.CacheManager
import org.springframework.cache.annotation.EnableCaching
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.redis.cache.RedisCacheConfiguration
import org.springframework.data.redis.cache.RedisCacheManager.RedisCacheManagerBuilder
import org.springframework.data.redis.connection.RedisConnectionFactory
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer
import org.springframework.data.redis.serializer.RedisSerializationContext
import org.springframework.data.redis.serializer.StringRedisSerializer


@Configuration
@EnableCaching
class RedisCacheConfig {

@Bean
fun redisCacheManager(
connectionFactory: RedisConnectionFactory,
objectMapper: ObjectMapper,
): CacheManager {

val redisCacheConfiguration = RedisCacheConfiguration
.defaultCacheConfig()
.serializeKeysWith(
RedisSerializationContext.SerializationPair.fromSerializer(StringRedisSerializer())
)
.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(GenericJackson2JsonRedisSerializer())
)
.entryTtl(CACHE_DURATION)

return RedisCacheManagerBuilder
.fromConnectionFactory(connectionFactory)
.cacheDefaults(redisCacheConfiguration)
.build()
}

companion object {
private val CACHE_DURATION = Duration.ofMinutes(30L)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ enum class GlobalErrorCode(
BAD_REQUEST(ErrorStatus.BAD_REQUEST, "Bad Request", 3),
INVALID_FILE(ErrorStatus.BAD_REQUEST, "Invalid File", 4),
BAD_EXCEL_FORMAT(ErrorStatus.BAD_REQUEST, "%s행 등 %s개 행의 데이터 형식이 잘못되었습니다.", 5),
KEY_MANAGEMENT_SERVICE(ErrorStatus.BAD_REQUEST, "Key processing failed", 6),

EXTENSION_MISMATCH(401, "File Extension Mismatch", 1),

Expand Down
Loading