Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .kotlin/errors/errors-1727090346428.log
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 파일은 뭔가요..?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 모르겠어요..

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
kotlin version: 2.0.20
error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output:
1. Kotlin compile daemon is ready

2 changes: 2 additions & 0 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ dependencies {
implementation(project(":applicant:applicant-jpa-adapter"))
implementation(project(":applicant:applicant-web-adapter"))
implementation(project(":applicant:applicant-s3-adapter"))
implementation(project(":applicant:applicant-redis-adapter"))
implementation(project(":applicant:applicant-smtp-adapter"))

implementation(project(":admission:admission-application"))
implementation(project(":admission:admission-jpa-adapter"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.daegusw.apply.applicant.application.port.`in`.web

interface SmtpUseCase {
suspend fun verify(email: String, code: String): String
suspend fun send(email: String): String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.daegusw.apply.applicant.application.port.out.redis

interface RedisPort {
fun save(key: String, value: String, expiration: Long)
fun delete(key: String)
fun get(key: String): String?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.daegusw.apply.applicant.application.port.out.smtp

interface SmtpPort {
suspend fun send(e: String) : String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.daegusw.apply.applicant.application.service

import com.daegusw.apply.applicant.application.port.`in`.web.SmtpUseCase
import com.daegusw.apply.applicant.application.port.out.redis.RedisPort
import com.daegusw.apply.applicant.application.port.out.smtp.SmtpPort
import org.springframework.stereotype.Service

@Service
class SmtpService(
private val stmpPort: SmtpPort,
private val redisPort: RedisPort,
) : SmtpUseCase {

override suspend fun verify(email: String, code: String): String {
val value = redisPort.get(email)
if((value != null) && value == code){
return "verified"
}
throw RuntimeException("Smtp verification failed")
}

override suspend fun send(email: String): String {
val code = stmpPort.send(email)
redisPort.save(email,code,3L) //3분
return "smtp success"
}

}
4 changes: 4 additions & 0 deletions applicant/applicant-redis-adapter/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-redis")
implementation(project(":applicant:applicant-application"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.daegusw.apply.applicant.redis.adapter

import com.daegusw.apply.applicant.application.port.out.redis.RedisPort
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.stereotype.Component
import java.time.Duration

@Component
class RedisAdapter(
private val redisTemplate: RedisTemplate<String, String>,
) : RedisPort {
override fun save(key: String, value: String, expiration: Long) {
try{
redisTemplate.opsForValue().set(key, value, Duration.ofMinutes(expiration))

}catch(e:Exception){
throw e
}
}

override fun delete(key: String) {
try{
redisTemplate.delete(key)
}catch(e:Exception){
throw e
}
}

override fun get(key: String): String? {
try {
return redisTemplate.opsForValue().get(key)
}catch(e:Exception){
throw e
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.daegusw.apply.applicant.redis.adapter.common

import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.redis.connection.RedisConnectionFactory
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.data.redis.serializer.StringRedisSerializer
import org.springframework.transaction.PlatformTransactionManager
import org.springframework.transaction.TransactionManager


@Configuration
class RedisConfig(
@Value("\${spring.redis.host}")
val host: String,

@Value("\${spring.redis.port}")
val port: Int,
) {

@Bean
fun redisConnectionFactory(): RedisConnectionFactory {
return LettuceConnectionFactory(host, port)
}

@Bean
fun redisTemplate(): RedisTemplate<*, *> {
return RedisTemplate<Any, Any>().apply {
this.setConnectionFactory(redisConnectionFactory())
// 불편한 값 삭제
this.keySerializer = StringRedisSerializer()
this.hashKeySerializer = StringRedisSerializer()
this.valueSerializer = StringRedisSerializer()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
spring:
redis:
host: localhost
port: 6379
7 changes: 7 additions & 0 deletions applicant/applicant-smtp-adapter/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
dependencies {
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("aws.sdk.kotlin:ses:0.16.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
implementation ("org.springframework.boot:spring-boot-starter-mail")
implementation(project(":applicant:applicant-application"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.daegusw.apply.applicant.smtp.adapter

import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.ses.SesClient
import aws.sdk.kotlin.services.ses.model.*
import com.daegusw.apply.applicant.application.port.out.smtp.SmtpPort
import com.daegusw.apply.applicant.smtp.adapter.common.ApplicantStmpProperties
import org.springframework.stereotype.Component
import org.thymeleaf.context.Context
import org.thymeleaf.spring5.SpringTemplateEngine

@Component
class SmtpAdapter(
private val applicantStmpProperties: ApplicantStmpProperties,
private val templateEngine: SpringTemplateEngine,
) : SmtpPort {
override suspend fun send(e: String) : String {
try{
val code = (1..5).map { (0..9).random() }.joinToString("")
val context = Context()
context.setVariable("code", code)

val emailRequest = SendEmailRequest {
destination = Destination {
toAddresses = listOf(e)
}

message = Message {
subject = Content {
data = "인증 번호"
}

body = Body {
html = Content {
data = templateEngine.process("code", context)
}
}
}

source = applicantStmpProperties.sendEmail
}

SesClient {
region = applicantStmpProperties.region

credentialsProvider = StaticCredentialsProvider {
accessKeyId = applicantStmpProperties.accessKey
secretAccessKey = applicantStmpProperties.secretKey
}
}.use {
it.sendEmail(emailRequest)
}
return code
}catch (e:Exception){
throw RuntimeException()
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.daegusw.apply.applicant.smtp.adapter.common

import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.PropertySource
import org.springframework.stereotype.Component

@Component
@PropertySource("classpath:application.yml")
class ApplicantStmpProperties (
@Value("\${cloud.aws.credentials.access-key:access-key}") val accessKey : String,
@Value("\${cloud.aws.credentials.secret-key:secret-key}") val secretKey : String,
@Value("\${cloud.aws.region}") val region : String,
@Value("\${cloud.aws.credentials.send-mail-to}") val sendEmail : String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
spring:
thymeleaf:
prefix: classpath:/templates
suffix: .html
mode: HTML
encoding: UTF-8
check-template-location: true
cache: false
cloud:
aws:
credentials:
access-key: ${aws.credentials.accessKey}
secret-key: ${aws.credentials.secretKey}
send-mail-to: dgswcns@gmail.com
region: ap-northeast-2
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<div style="font-family: 'Apple SD Gothic Neo', 'sans-serif' !important; width: 540px; height: 600px; border-top: 4px solid #2A7AF3; margin: 100px auto; padding: 30px 0; box-sizing: border-box;">
<h1 style="margin: 0; padding: 0 5px; font-size: 28px; font-weight: 400;">
<span style="color: #2A7AF3">IDA 인증번호</span> 안내입니다.
</h1>
<p style="font-size: 16px; line-height: 26px; margin-top: 20px; padding: 0 5px;">
아래 <b style="color: #2A7AF3">인증번호</b>를 <b>3분내로</b> 입력해주세요.
</p>

<div style="color: #FFF; text-decoration: none; text-align: center;">
<p style="display: inline-block; width: 210px; height: 45px; margin: 30px 5px 40px; background: #2A7AF3; line-height: 45px; vertical-align: middle; font-size: 16px;" th:text="${code}"></p>
</div>

<div style="border-top: 1px solid #DDD; padding: 5px;">
<p style="font-size: 13px; line-height: 21px; color: #555;">
아무에게도 이 번호를 공유하지마세요. 회원 정보가 유출되는 문제가 발생 할 수 있습니다.<br/>
</p>
</div>
</div>
</body>
</html>
1 change: 1 addition & 0 deletions applicant/applicant-web-adapter/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ dependencies {

implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.daegusw.apply.applicant.web.adapter.api

import com.daegusw.apply.applicant.application.port.`in`.web.SmtpUseCase
import com.daegusw.apply.applicant.web.adapter.api.request.SmtpRequest
import com.daegusw.apply.applicant.web.adapter.api.response.SmtpResponse
import kotlinx.coroutines.runBlocking
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.*
import javax.validation.Valid
import javax.validation.constraints.NotEmpty

@RestController
@RequestMapping("/applicant/stmp")
class SmtpController(
private val smtpUseCase: SmtpUseCase
) {
@ResponseStatus(HttpStatus.OK)
@GetMapping
fun send(@NotEmpty(message = "email is required")@RequestParam email: String) : SmtpResponse {
return runBlocking {
SmtpResponse(
smtpUseCase.send(email) + "로 전송 완료"
)
}
}

@ResponseStatus(HttpStatus.OK)
@PostMapping
fun verify(@Valid @RequestBody smtpRequest: SmtpRequest) : SmtpResponse {
return runBlocking {
SmtpResponse(
smtpUseCase.verify(smtpRequest.email,smtpRequest.code)
)
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.daegusw.apply.applicant.web.adapter.api.request

import javax.validation.constraints.Email
import javax.validation.constraints.NotEmpty

data class SmtpRequest(
@field:Email(message = "email is required")
val email: String,
@field:NotEmpty(message = "code is required")
val code: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.daegusw.apply.applicant.web.adapter.api.response

data class SmtpResponse(
val message : String,
)
2 changes: 2 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ include("applicant:applicant-domain")
include("applicant:applicant-application")
include("applicant:applicant-jpa-adapter")
include("applicant:applicant-s3-adapter")
include("applicant:applicant-smtp-adapter")
include("applicant:applicant-web-adapter")
include("applicant:applicant-redis-adapter")

include("admission")
include("admission:admission-domain")
Expand Down