Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.ject.support.external.email.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.StringUtils;

@ConfigurationProperties(prefix = "email-auth.bypass")
public record EmailAuthBypassProperties(boolean enabled, String email, String code) {

public boolean isEnabledFor(String targetEmail) {
return enabled && StringUtils.hasText(email) && StringUtils.hasText(code)
&& email.equalsIgnoreCase(targetEmail);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ject.support.common.util.CodeGeneratorUtil;
import org.ject.support.external.email.config.EmailAuthBypassProperties;
import org.ject.support.external.email.domain.EmailTemplate;
import org.ject.support.external.email.exception.RateLimitException;
import org.springframework.data.redis.core.RedisTemplate;
Expand All @@ -22,8 +23,15 @@ public class EmailAuthService {

private final SesEmailSendService emailSendService;
private final RedisTemplate<String, String> redisTemplate;
private final EmailAuthBypassProperties emailAuthBypassProperties;

public void sendAuthCode(EmailTemplate sendGroupCode, String toEmail) {
if (sendGroupCode == EmailTemplate.AUTH_CODE && emailAuthBypassProperties.isEnabledFor(toEmail)) {
// 개발 자동화 계정 인증번호 저장
storeAuthCode(toEmail, emailAuthBypassProperties.code());
return;
}

checkRateLimit(sendGroupCode, toEmail);

String authCode = CodeGeneratorUtil.generateDigitCode(AUTH_CODE_LENGTH);
Expand Down
4 changes: 4 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ spring:
name: support
profiles:
active: local

email-auth:
bypass:
enabled: false
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.ject.support.external.email.service;

import org.ject.support.base.UnitTestSupport;
import org.ject.support.external.email.config.EmailAuthBypassProperties;
import org.ject.support.external.email.domain.EmailTemplate;
import org.ject.support.external.email.exception.RateLimitException;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -30,6 +31,9 @@ class EmailAuthServiceTest extends UnitTestSupport {
@Mock
private RedisTemplate<String, String> redisTemplate;

@Mock
private EmailAuthBypassProperties emailAuthBypassProperties;

@Mock
private ValueOperations<String, String> valueOperations;

Expand All @@ -38,6 +42,7 @@ class EmailAuthServiceTest extends UnitTestSupport {
// given
String email = "test@example.com";

given(emailAuthBypassProperties.isEnabledFor(email)).willReturn(false);
given(redisTemplate.hasKey(anyString())).willReturn(false);
given(redisTemplate.opsForValue()).willReturn(valueOperations);

Expand All @@ -51,6 +56,23 @@ class EmailAuthServiceTest extends UnitTestSupport {
verify(emailSendService).sendTemplatedEmail(eq(EmailTemplate.AUTH_CODE), eq(email), any());
}

@Test
void 개발용_인증_이메일은_메일을_발송하지_않고_고정_인증번호를_저장한다() {
// given
String email = "testbot@ject.kr";
given(emailAuthBypassProperties.isEnabledFor(email)).willReturn(true);
given(emailAuthBypassProperties.code()).willReturn("000000");
given(redisTemplate.opsForValue()).willReturn(valueOperations);

// when
emailAuthService.sendAuthCode(EmailTemplate.AUTH_CODE, email);

// then
verify(valueOperations).set(email, "000000", Duration.ofMinutes(5));
verify(emailSendService, never()).sendTemplatedEmail(any(), any(), any());
verify(redisTemplate, never()).hasKey(anyString());
}

@Test
void 인증번호_재설정_시_Rate_Limit이_적용되어_있지_않다면_정상_발송된다() {
// given
Expand Down
Loading