From c0452cf704f8e4c6526af02f1674e42ddc802c08 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=ED=95=9C=EA=B4=80=ED=9D=AC?=
Date: Wed, 13 Nov 2024 23:03:07 +0900
Subject: [PATCH 01/24] =?UTF-8?q?refactor(Notification):=20=EC=99=B8?=
=?UTF-8?q?=EB=B6=80=20=EC=95=8C=EB=A6=BC=20=EC=A0=84=EC=86=A1=20=EB=A1=9C?=
=?UTF-8?q?=EC=A7=81=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EA=B5=AC=EC=A1=B0=20?=
=?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EC=8A=AC=EB=9E=99=20=EC=95=8C?=
=?UTF-8?q?=EB=A6=BC=20=EC=A0=84=EC=86=A1=20=EB=A1=9C=EC=A7=81=EA=B3=BC?=
=?UTF-8?q?=EC=9D=98=20=EA=B2=B0=ED=95=A9=EB=8F=84=20=EC=99=84=ED=99=94?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../application/service/MemberBanService.java | 9 +--
.../service/MemberUnbanService.java | 9 +--
.../service/BlacklistIpRegisterService.java | 12 ++--
.../service/BlacklistIpRemoveService.java | 9 +--
.../service/BlacklistIpResetService.java | 10 +--
.../TwoFactorAuthenticationService.java | 21 +++---
.../AbnormalAccessIpRemoveService.java | 7 +-
.../AbnormalAccessIpsClearService.java | 10 +--
.../service/BoardRegisterService.java | 10 +--
.../service/ApplicationApplyService.java | 4 +-
.../service/BookLoanRequestService.java | 13 ++--
.../service/MemberRoleManagementService.java | 7 +-
.../service/MembershipFeeRegisterService.java | 2 +-
.../ExternalAccountLockManagementService.java | 19 +++---
...xternalIpAccessMonitorRegisterService.java | 7 +-
.../CustomBasicAuthenticationFilter.java | 41 ++++++------
.../filter/InvalidEndpointAccessFilter.java | 19 +++---
.../auth/filter/JwtAuthenticationFilter.java | 23 ++++---
.../web}/NotificationSettingController.java | 11 ++--
.../NotificationSettingRepository.java | 9 ++-
.../out/slack/SlackNotificationSender.java | 19 ++++++
.../adapter/out/slack}/SlackService.java | 42 +++++++-----
.../out/slack}/SlackServiceHelper.java | 64 ++++++++++---------
.../mapper/NotificationSettingDtoMapper.java} | 8 +--
.../NotificationSettingUpdateRequestDto.java | 2 +-
.../NotificationSettingResponseDto.java | 2 +-
.../application}/event/NotificationEvent.java | 7 +-
.../event/NotificationListener.java | 27 ++++++++
.../exception/AlertTypeNotFoundException.java | 2 +-
.../port/out/NotificationSender.java | 8 +++
.../service}/NotificationSettingService.java | 21 +++---
.../config/NotificationConfig.java | 21 ++++++
.../domain/AlertType.java | 2 +-
.../domain/AlertTypeConverter.java | 5 +-
.../domain/AlertTypeResolver.java | 4 +-
.../domain/ExecutivesAlertType.java | 2 +-
.../domain/GeneralAlertType.java | 2 +-
.../domain/NotificationSetting.java | 2 +-
.../domain/SecurityAlertType.java | 2 +-
.../slack/listener/NotificationListener.java | 28 --------
.../api/global/config/SecurityConfig.java | 20 +++---
.../handler/GlobalExceptionHandler.java | 11 ++--
42 files changed, 318 insertions(+), 235 deletions(-)
rename src/main/java/page/clab/api/global/common/{slack/api => notificationSetting/adapter/in/web}/NotificationSettingController.java (81%)
rename src/main/java/page/clab/api/global/common/{slack/dao => notificationSetting/adapter/out/persistence}/NotificationSettingRepository.java (52%)
create mode 100644 src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/slack/SlackNotificationSender.java
rename src/main/java/page/clab/api/global/common/{slack/application => notificationSetting/adapter/out/slack}/SlackService.java (65%)
rename src/main/java/page/clab/api/global/common/{slack/application => notificationSetting/adapter/out/slack}/SlackServiceHelper.java (93%)
rename src/main/java/page/clab/api/global/common/{slack/dto/mapper/SlackDtoMapper.java => notificationSetting/application/dto/mapper/NotificationSettingDtoMapper.java} (51%)
rename src/main/java/page/clab/api/global/common/{slack => notificationSetting/application}/dto/request/NotificationSettingUpdateRequestDto.java (87%)
rename src/main/java/page/clab/api/global/common/{slack => notificationSetting/application}/dto/response/NotificationSettingResponseDto.java (67%)
rename src/main/java/page/clab/api/global/common/{slack => notificationSetting/application}/event/NotificationEvent.java (70%)
create mode 100644 src/main/java/page/clab/api/global/common/notificationSetting/application/event/NotificationListener.java
rename src/main/java/page/clab/api/global/common/{slack => notificationSetting/application}/exception/AlertTypeNotFoundException.java (71%)
create mode 100644 src/main/java/page/clab/api/global/common/notificationSetting/application/port/out/NotificationSender.java
rename src/main/java/page/clab/api/global/common/{slack/application => notificationSetting/application/service}/NotificationSettingService.java (75%)
create mode 100644 src/main/java/page/clab/api/global/common/notificationSetting/config/NotificationConfig.java
rename src/main/java/page/clab/api/global/common/{slack => notificationSetting}/domain/AlertType.java (58%)
rename src/main/java/page/clab/api/global/common/{slack => notificationSetting}/domain/AlertTypeConverter.java (88%)
rename src/main/java/page/clab/api/global/common/{slack => notificationSetting}/domain/AlertTypeResolver.java (77%)
rename src/main/java/page/clab/api/global/common/{slack => notificationSetting}/domain/ExecutivesAlertType.java (89%)
rename src/main/java/page/clab/api/global/common/{slack => notificationSetting}/domain/GeneralAlertType.java (86%)
rename src/main/java/page/clab/api/global/common/{slack => notificationSetting}/domain/NotificationSetting.java (94%)
rename src/main/java/page/clab/api/global/common/{slack => notificationSetting}/domain/SecurityAlertType.java (95%)
delete mode 100644 src/main/java/page/clab/api/global/common/slack/listener/NotificationListener.java
diff --git a/src/main/java/page/clab/api/domain/auth/accountLockInfo/application/service/MemberBanService.java b/src/main/java/page/clab/api/domain/auth/accountLockInfo/application/service/MemberBanService.java
index d83793ba0..10cb46af8 100644
--- a/src/main/java/page/clab/api/domain/auth/accountLockInfo/application/service/MemberBanService.java
+++ b/src/main/java/page/clab/api/domain/auth/accountLockInfo/application/service/MemberBanService.java
@@ -11,8 +11,8 @@
import page.clab.api.domain.memberManagement.member.application.dto.shared.MemberBasicInfoDto;
import page.clab.api.external.auth.redisToken.application.port.ExternalManageRedisTokenUseCase;
import page.clab.api.external.memberManagement.member.application.port.ExternalRetrieveMemberUseCase;
-import page.clab.api.global.common.slack.application.SlackService;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
@Service
@RequiredArgsConstructor
@@ -30,7 +30,7 @@ public class MemberBanService implements BanMemberUseCase {
* 해당 멤버의 계정 잠금 정보를 조회하고, 없으면 새로 생성합니다.
* Redis에 저장된 해당 멤버의 인증 토큰을 삭제하며, Slack에 밴 알림을 전송합니다.
*
- * @param request 현재 요청 객체
+ * @param request 현재 요청 객체
* @param memberId 차단할 멤버의 ID
* @return 저장된 계정 잠금 정보의 ID
*/
@@ -58,6 +58,7 @@ private AccountLockInfo createAccountLockInfo(String memberId) {
private void sendSlackBanNotification(HttpServletRequest request, String memberId) {
String memberName = externalRetrieveMemberUseCase.getMemberBasicInfoById(memberId).getMemberName();
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.MEMBER_BANNED, "ID: " + memberId + ", Name: " + memberName);
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.MEMBER_BANNED,
+ "ID: " + memberId + ", Name: " + memberName);
}
}
diff --git a/src/main/java/page/clab/api/domain/auth/accountLockInfo/application/service/MemberUnbanService.java b/src/main/java/page/clab/api/domain/auth/accountLockInfo/application/service/MemberUnbanService.java
index 391628d8e..bed2bc2ae 100644
--- a/src/main/java/page/clab/api/domain/auth/accountLockInfo/application/service/MemberUnbanService.java
+++ b/src/main/java/page/clab/api/domain/auth/accountLockInfo/application/service/MemberUnbanService.java
@@ -10,8 +10,8 @@
import page.clab.api.domain.auth.accountLockInfo.domain.AccountLockInfo;
import page.clab.api.domain.memberManagement.member.application.dto.shared.MemberBasicInfoDto;
import page.clab.api.external.memberManagement.member.application.port.ExternalRetrieveMemberUseCase;
-import page.clab.api.global.common.slack.application.SlackService;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
@Service
@RequiredArgsConstructor
@@ -28,7 +28,7 @@ public class MemberUnbanService implements UnbanMemberUseCase {
* 해당 멤버의 계정 잠금 정보를 조회하고 해제합니다.
* 해제된 정보는 저장되며, Slack에 해제 알림이 전송됩니다.
*
- * @param request 현재 요청 객체
+ * @param request 현재 요청 객체
* @param memberId 해제할 멤버의 ID
* @return 업데이트된 계정 잠금 정보의 ID
*/
@@ -55,6 +55,7 @@ private AccountLockInfo createAccountLockInfo(String memberId) {
private void sendSlackUnbanNotification(HttpServletRequest request, String memberId) {
String memberName = externalRetrieveMemberUseCase.getMemberBasicInfoById(memberId).getMemberName();
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.MEMBER_UNBANNED, "ID: " + memberId + ", Name: " + memberName);
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.MEMBER_UNBANNED,
+ "ID: " + memberId + ", Name: " + memberName);
}
}
diff --git a/src/main/java/page/clab/api/domain/auth/blacklistIp/application/service/BlacklistIpRegisterService.java b/src/main/java/page/clab/api/domain/auth/blacklistIp/application/service/BlacklistIpRegisterService.java
index 6694afdec..896e8c8b5 100644
--- a/src/main/java/page/clab/api/domain/auth/blacklistIp/application/service/BlacklistIpRegisterService.java
+++ b/src/main/java/page/clab/api/domain/auth/blacklistIp/application/service/BlacklistIpRegisterService.java
@@ -10,8 +10,8 @@
import page.clab.api.domain.auth.blacklistIp.application.port.out.RegisterBlacklistIpPort;
import page.clab.api.domain.auth.blacklistIp.application.port.out.RetrieveBlacklistIpPort;
import page.clab.api.domain.auth.blacklistIp.domain.BlacklistIp;
-import page.clab.api.global.common.slack.application.SlackService;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
@Service
@RequiredArgsConstructor
@@ -26,10 +26,9 @@ public class BlacklistIpRegisterService implements RegisterBlacklistIpUseCase {
* 지정된 IP 주소를 블랙리스트에 등록합니다.
*
* 해당 IP 주소가 이미 블랙리스트에 존재하는지 확인하고,
- * 존재하지 않을 경우 새롭게 등록합니다.
- * 새로운 IP가 등록되면 Slack을 통해 보안 알림이 전송됩니다.
+ * 존재하지 않을 경우 새롭게 등록합니다. 새로운 IP가 등록되면 Slack을 통해 보안 알림이 전송됩니다.
*
- * @param request 현재 요청 객체
+ * @param request 현재 요청 객체
* @param requestDto 블랙리스트에 추가할 IP 주소 정보를 담은 DTO
* @return 기존에 존재하거나 새로 추가된 블랙리스트 IP 주소
*/
@@ -42,7 +41,8 @@ public String registerBlacklistIp(HttpServletRequest request, BlacklistIpRequest
.orElseGet(() -> {
BlacklistIp blacklistIp = mapper.fromDto(requestDto);
registerBlacklistIpPort.save(blacklistIp);
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.BLACKLISTED_IP_ADDED, "Added IP: " + ipAddress);
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.BLACKLISTED_IP_ADDED,
+ "Added IP: " + ipAddress);
return ipAddress;
});
}
diff --git a/src/main/java/page/clab/api/domain/auth/blacklistIp/application/service/BlacklistIpRemoveService.java b/src/main/java/page/clab/api/domain/auth/blacklistIp/application/service/BlacklistIpRemoveService.java
index 5de09b640..5d6f9df1d 100644
--- a/src/main/java/page/clab/api/domain/auth/blacklistIp/application/service/BlacklistIpRemoveService.java
+++ b/src/main/java/page/clab/api/domain/auth/blacklistIp/application/service/BlacklistIpRemoveService.java
@@ -8,8 +8,8 @@
import page.clab.api.domain.auth.blacklistIp.application.port.out.RemoveBlacklistIpPort;
import page.clab.api.domain.auth.blacklistIp.application.port.out.RetrieveBlacklistIpPort;
import page.clab.api.domain.auth.blacklistIp.domain.BlacklistIp;
-import page.clab.api.global.common.slack.application.SlackService;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
@Service
@RequiredArgsConstructor
@@ -25,7 +25,7 @@ public class BlacklistIpRemoveService implements RemoveBlacklistIpUseCase {
* 블랙리스트에 등록된 IP 주소 정보를 조회하고 해당 정보를 삭제합니다.
* 삭제가 완료되면 Slack을 통해 보안 알림이 전송됩니다.
*
- * @param request 현재 요청 객체
+ * @param request 현재 요청 객체
* @param ipAddress 제거할 블랙리스트 IP 주소
* @return 삭제된 블랙리스트 IP 주소
*/
@@ -34,7 +34,8 @@ public class BlacklistIpRemoveService implements RemoveBlacklistIpUseCase {
public String removeBlacklistIp(HttpServletRequest request, String ipAddress) {
BlacklistIp blacklistIp = retrieveBlacklistIpPort.getByIpAddress(ipAddress);
removeBlacklistIpPort.delete(blacklistIp);
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.BLACKLISTED_IP_REMOVED, "Deleted IP: " + ipAddress);
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.BLACKLISTED_IP_REMOVED,
+ "Deleted IP: " + ipAddress);
return blacklistIp.getIpAddress();
}
}
diff --git a/src/main/java/page/clab/api/domain/auth/blacklistIp/application/service/BlacklistIpResetService.java b/src/main/java/page/clab/api/domain/auth/blacklistIp/application/service/BlacklistIpResetService.java
index 342a2561f..04078df28 100644
--- a/src/main/java/page/clab/api/domain/auth/blacklistIp/application/service/BlacklistIpResetService.java
+++ b/src/main/java/page/clab/api/domain/auth/blacklistIp/application/service/BlacklistIpResetService.java
@@ -1,6 +1,7 @@
package page.clab.api.domain.auth.blacklistIp.application.service;
import jakarta.servlet.http.HttpServletRequest;
+import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -8,10 +9,8 @@
import page.clab.api.domain.auth.blacklistIp.application.port.out.RemoveBlacklistIpPort;
import page.clab.api.domain.auth.blacklistIp.application.port.out.RetrieveBlacklistIpPort;
import page.clab.api.domain.auth.blacklistIp.domain.BlacklistIp;
-import page.clab.api.global.common.slack.application.SlackService;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
-
-import java.util.List;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
@Service
@RequiredArgsConstructor
@@ -38,7 +37,8 @@ public List resetBlacklistIps(HttpServletRequest request) {
.map(BlacklistIp::getIpAddress)
.toList();
removeBlacklistIpPort.deleteAll();
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.BLACKLISTED_IP_REMOVED, "Deleted IP: ALL");
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.BLACKLISTED_IP_REMOVED,
+ "Deleted IP: ALL");
return blacklistedIps;
}
}
diff --git a/src/main/java/page/clab/api/domain/auth/login/application/service/TwoFactorAuthenticationService.java b/src/main/java/page/clab/api/domain/auth/login/application/service/TwoFactorAuthenticationService.java
index 655a51a06..609423d36 100644
--- a/src/main/java/page/clab/api/domain/auth/login/application/service/TwoFactorAuthenticationService.java
+++ b/src/main/java/page/clab/api/domain/auth/login/application/service/TwoFactorAuthenticationService.java
@@ -1,6 +1,7 @@
package page.clab.api.domain.auth.login.application.service;
import jakarta.servlet.http.HttpServletRequest;
+import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@@ -21,11 +22,9 @@
import page.clab.api.external.auth.redisToken.application.port.ExternalManageRedisTokenUseCase;
import page.clab.api.external.memberManagement.member.application.port.ExternalRetrieveMemberUseCase;
import page.clab.api.global.auth.jwt.JwtTokenProvider;
-import page.clab.api.global.common.slack.application.SlackService;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
import page.clab.api.global.util.HttpReqResUtil;
-import java.util.List;
-
@Service
@RequiredArgsConstructor
@Qualifier("twoFactorAuthenticationService")
@@ -41,7 +40,9 @@ public class TwoFactorAuthenticationService implements ManageLoginUseCase {
@Transactional
@Override
- public LoginResult authenticate(HttpServletRequest request, TwoFactorAuthenticationRequestDto twoFactorAuthenticationRequestDto) throws LoginFailedException, MemberLockedException {
+ public LoginResult authenticate(HttpServletRequest request,
+ TwoFactorAuthenticationRequestDto twoFactorAuthenticationRequestDto)
+ throws LoginFailedException, MemberLockedException {
String memberId = twoFactorAuthenticationRequestDto.getMemberId();
MemberLoginInfoDto loginMember = externalRetrieveMemberUseCase.getMemberLoginInfoById(memberId);
String totp = twoFactorAuthenticationRequestDto.getTotp();
@@ -55,9 +56,11 @@ public LoginResult authenticate(HttpServletRequest request, TwoFactorAuthenticat
return LoginResult.create(header, true);
}
- private void verifyTwoFactorAuthentication(String memberId, String totp, HttpServletRequest request) throws MemberLockedException, LoginFailedException {
+ private void verifyTwoFactorAuthentication(String memberId, String totp, HttpServletRequest request)
+ throws MemberLockedException, LoginFailedException {
if (!manageAuthenticatorUseCase.isAuthenticatorValid(memberId, totp)) {
- externalRegisterAccountAccessLogUseCase.registerAccountAccessLog(request, memberId, AccountAccessResult.FAILURE);
+ externalRegisterAccountAccessLogUseCase.registerAccountAccessLog(request, memberId,
+ AccountAccessResult.FAILURE);
externalManageAccountLockUseCase.handleLoginFailure(request, memberId);
throw new LoginFailedException("잘못된 인증번호입니다.");
}
@@ -67,7 +70,8 @@ private void verifyTwoFactorAuthentication(String memberId, String totp, HttpSer
private TokenInfo generateAndSaveToken(MemberLoginInfoDto memberInfo) {
TokenInfo tokenInfo = jwtTokenProvider.generateToken(memberInfo.getMemberId(), memberInfo.getRole());
String clientIpAddress = HttpReqResUtil.getClientIpAddressIfServletRequestExist();
- externalManageRedisTokenUseCase.saveToken(memberInfo.getMemberId(), memberInfo.getRole(), tokenInfo, clientIpAddress);
+ externalManageRedisTokenUseCase.saveToken(memberInfo.getMemberId(), memberInfo.getRole(), tokenInfo,
+ clientIpAddress);
return tokenInfo;
}
@@ -78,7 +82,8 @@ private void sendAdminLoginNotification(HttpServletRequest request, MemberLoginI
}
@Override
- public LoginResult login(HttpServletRequest request, LoginRequestDto requestDto) throws LoginFailedException, MemberLockedException {
+ public LoginResult login(HttpServletRequest request, LoginRequestDto requestDto)
+ throws LoginFailedException, MemberLockedException {
throw new UnsupportedOperationException("Method not implemented");
}
diff --git a/src/main/java/page/clab/api/domain/auth/redisIpAccessMonitor/application/service/AbnormalAccessIpRemoveService.java b/src/main/java/page/clab/api/domain/auth/redisIpAccessMonitor/application/service/AbnormalAccessIpRemoveService.java
index 7789853cb..8dfa0565d 100644
--- a/src/main/java/page/clab/api/domain/auth/redisIpAccessMonitor/application/service/AbnormalAccessIpRemoveService.java
+++ b/src/main/java/page/clab/api/domain/auth/redisIpAccessMonitor/application/service/AbnormalAccessIpRemoveService.java
@@ -6,8 +6,8 @@
import org.springframework.transaction.annotation.Transactional;
import page.clab.api.domain.auth.redisIpAccessMonitor.application.port.in.RemoveAbnormalAccessIpUseCase;
import page.clab.api.domain.auth.redisIpAccessMonitor.application.port.out.RemoveIpAccessMonitorPort;
-import page.clab.api.global.common.slack.application.SlackService;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
@Service
@RequiredArgsConstructor
@@ -20,7 +20,8 @@ public class AbnormalAccessIpRemoveService implements RemoveAbnormalAccessIpUseC
@Transactional
public String removeAbnormalAccessIp(HttpServletRequest request, String ipAddress) {
removeIpAccessMonitorPort.deleteById(ipAddress);
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.ABNORMAL_ACCESS_IP_DELETED, "Deleted IP: " + ipAddress);
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.ABNORMAL_ACCESS_IP_DELETED,
+ "Deleted IP: " + ipAddress);
return ipAddress;
}
}
diff --git a/src/main/java/page/clab/api/domain/auth/redisIpAccessMonitor/application/service/AbnormalAccessIpsClearService.java b/src/main/java/page/clab/api/domain/auth/redisIpAccessMonitor/application/service/AbnormalAccessIpsClearService.java
index 7a5c7dbcb..2127cb788 100644
--- a/src/main/java/page/clab/api/domain/auth/redisIpAccessMonitor/application/service/AbnormalAccessIpsClearService.java
+++ b/src/main/java/page/clab/api/domain/auth/redisIpAccessMonitor/application/service/AbnormalAccessIpsClearService.java
@@ -1,6 +1,7 @@
package page.clab.api.domain.auth.redisIpAccessMonitor.application.service;
import jakarta.servlet.http.HttpServletRequest;
+import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -8,10 +9,8 @@
import page.clab.api.domain.auth.redisIpAccessMonitor.application.port.out.ClearIpAccessMonitorPort;
import page.clab.api.domain.auth.redisIpAccessMonitor.application.port.out.RetrieveIpAccessMonitorPort;
import page.clab.api.domain.auth.redisIpAccessMonitor.domain.RedisIpAccessMonitor;
-import page.clab.api.global.common.slack.application.SlackService;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
-
-import java.util.List;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
@Service
@RequiredArgsConstructor
@@ -26,7 +25,8 @@ public class AbnormalAccessIpsClearService implements ClearAbnormalAccessIpsUseC
public List clearAbnormalAccessIps(HttpServletRequest request) {
List ipAccessMonitors = retrieveIpAccessMonitorPort.findAll();
clearIpAccessMonitorPort.deleteAll();
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.ABNORMAL_ACCESS_IP_DELETED, "Deleted IP: ALL");
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.ABNORMAL_ACCESS_IP_DELETED,
+ "Deleted IP: ALL");
return ipAccessMonitors;
}
}
diff --git a/src/main/java/page/clab/api/domain/community/board/application/service/BoardRegisterService.java b/src/main/java/page/clab/api/domain/community/board/application/service/BoardRegisterService.java
index f2e487749..0936df52e 100644
--- a/src/main/java/page/clab/api/domain/community/board/application/service/BoardRegisterService.java
+++ b/src/main/java/page/clab/api/domain/community/board/application/service/BoardRegisterService.java
@@ -1,5 +1,6 @@
package page.clab.api.domain.community.board.application.service;
+import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -8,17 +9,15 @@
import page.clab.api.domain.community.board.application.port.in.RegisterBoardUseCase;
import page.clab.api.domain.community.board.application.port.out.RegisterBoardPort;
import page.clab.api.domain.community.board.domain.Board;
-import page.clab.api.global.common.slack.domain.SlackBoardInfo;
import page.clab.api.domain.memberManagement.member.application.dto.shared.MemberDetailedInfoDto;
import page.clab.api.external.memberManagement.member.application.port.ExternalRetrieveMemberUseCase;
import page.clab.api.external.memberManagement.notification.application.port.ExternalSendNotificationUseCase;
import page.clab.api.global.common.file.application.UploadedFileService;
import page.clab.api.global.common.file.domain.UploadedFile;
-import page.clab.api.global.common.slack.application.SlackService;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
+import page.clab.api.global.common.slack.domain.SlackBoardInfo;
import page.clab.api.global.exception.PermissionDeniedException;
-import java.util.List;
-
@Service
@RequiredArgsConstructor
public class BoardRegisterService implements RegisterBoardUseCase {
@@ -48,7 +47,8 @@ public String registerBoard(BoardRequestDto requestDto) throws PermissionDeniedE
Board board = mapper.fromDto(requestDto, currentMemberInfo.getMemberId(), uploadedFiles);
board.validateAccessPermissionForCreation(currentMemberInfo);
if (board.shouldNotifyForNewBoard(currentMemberInfo)) {
- externalSendNotificationUseCase.sendNotificationToMember(currentMemberInfo.getMemberId(), "[" + board.getTitle() + "] 새로운 공지사항이 등록되었습니다.");
+ externalSendNotificationUseCase.sendNotificationToMember(currentMemberInfo.getMemberId(),
+ "[" + board.getTitle() + "] 새로운 공지사항이 등록되었습니다.");
}
SlackBoardInfo boardInfo = SlackBoardInfo.create(board, currentMemberInfo);
slackService.sendNewBoardNotification(boardInfo);
diff --git a/src/main/java/page/clab/api/domain/hiring/application/application/service/ApplicationApplyService.java b/src/main/java/page/clab/api/domain/hiring/application/application/service/ApplicationApplyService.java
index 11c69305c..4aa29bf59 100644
--- a/src/main/java/page/clab/api/domain/hiring/application/application/service/ApplicationApplyService.java
+++ b/src/main/java/page/clab/api/domain/hiring/application/application/service/ApplicationApplyService.java
@@ -10,7 +10,7 @@
import page.clab.api.domain.hiring.application.domain.Application;
import page.clab.api.external.hiring.application.application.port.ExternalRetrieveRecruitmentUseCase;
import page.clab.api.external.memberManagement.notification.application.port.ExternalSendNotificationUseCase;
-import page.clab.api.global.common.slack.application.SlackService;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
@Service
@RequiredArgsConstructor
@@ -21,7 +21,7 @@ public class ApplicationApplyService implements ApplyForApplicationUseCase {
private final ExternalSendNotificationUseCase externalSendNotificationUseCase;
private final SlackService slackService;
private final ApplicationDtoMapper mapper;
-
+
@Transactional
@Override
public String applyForClub(ApplicationRequestDto requestDto) {
diff --git a/src/main/java/page/clab/api/domain/library/bookLoanRecord/application/service/BookLoanRequestService.java b/src/main/java/page/clab/api/domain/library/bookLoanRecord/application/service/BookLoanRequestService.java
index 1e759332e..7345ac8da 100644
--- a/src/main/java/page/clab/api/domain/library/bookLoanRecord/application/service/BookLoanRequestService.java
+++ b/src/main/java/page/clab/api/domain/library/bookLoanRecord/application/service/BookLoanRequestService.java
@@ -17,7 +17,7 @@
import page.clab.api.external.library.book.application.port.ExternalRetrieveBookUseCase;
import page.clab.api.external.memberManagement.member.application.port.ExternalRetrieveMemberUseCase;
import page.clab.api.external.memberManagement.notification.application.port.ExternalSendNotificationUseCase;
-import page.clab.api.global.common.slack.application.SlackService;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
import page.clab.api.global.common.slack.domain.SlackBookLoanRecordInfo;
import page.clab.api.global.exception.CustomOptimisticLockingFailureException;
@@ -36,15 +36,13 @@ public class BookLoanRequestService implements RequestBookLoanUseCase {
* 도서 대출 신청을 처리합니다.
*
* 현재 로그인한 멤버의 대출 상태와 한도를 검증한 후,
- * 도서의 대출 신청이 이미 존재하는지 확인합니다.
- * 대출 신청이 성공적으로 완료되면 멤버와 Slack에 알림을 전송하고,
- * 대출 기록을 저장한 후 그 ID를 반환합니다.
+ * 도서의 대출 신청이 이미 존재하는지 확인합니다. 대출 신청이 성공적으로 완료되면 멤버와 Slack에 알림을 전송하고, 대출 기록을 저장한 후 그 ID를 반환합니다.
*
* @param requestDto 도서 대출 신청 요청 정보 DTO
* @return 저장된 대출 기록의 ID
* @throws CustomOptimisticLockingFailureException 동시에 다른 사용자가 대출을 신청하여 충돌이 발생한 경우 예외 발생
- * @throws MaxBorrowLimitExceededException 대출 한도를 초과한 경우 예외 발생
- * @throws BookAlreadyAppliedForLoanException 이미 신청된 도서일 경우 예외 발생
+ * @throws MaxBorrowLimitExceededException 대출 한도를 초과한 경우 예외 발생
+ * @throws BookAlreadyAppliedForLoanException 이미 신청된 도서일 경우 예외 발생
*/
@Transactional
@Override
@@ -60,7 +58,8 @@ public Long requestBookLoan(BookLoanRecordRequestDto requestDto) throws CustomOp
BookLoanRecord bookLoanRecord = BookLoanRecord.create(book.getId(), borrowerInfo);
- externalSendNotificationUseCase.sendNotificationToMember(borrowerInfo.getMemberId(), "[" + book.getTitle() + "] 도서 대출 신청이 완료되었습니다.");
+ externalSendNotificationUseCase.sendNotificationToMember(borrowerInfo.getMemberId(),
+ "[" + book.getTitle() + "] 도서 대출 신청이 완료되었습니다.");
SlackBookLoanRecordInfo bookLoanRecordInfo = SlackBookLoanRecordInfo.create(book, borrowerInfo);
slackService.sendNewBookLoanRequestNotification(bookLoanRecordInfo);
diff --git a/src/main/java/page/clab/api/domain/memberManagement/member/application/service/MemberRoleManagementService.java b/src/main/java/page/clab/api/domain/memberManagement/member/application/service/MemberRoleManagementService.java
index db2ced3c0..8d656dda3 100644
--- a/src/main/java/page/clab/api/domain/memberManagement/member/application/service/MemberRoleManagementService.java
+++ b/src/main/java/page/clab/api/domain/memberManagement/member/application/service/MemberRoleManagementService.java
@@ -11,8 +11,8 @@
import page.clab.api.domain.memberManagement.member.application.port.out.UpdateMemberPort;
import page.clab.api.domain.memberManagement.member.domain.Member;
import page.clab.api.domain.memberManagement.member.domain.Role;
-import page.clab.api.global.common.slack.application.SlackService;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
@Service
@RequiredArgsConstructor
@@ -24,7 +24,8 @@ public class MemberRoleManagementService implements ManageMemberRoleUseCase {
@Transactional
@Override
- public String changeMemberRole(HttpServletRequest httpServletRequest, String memberId, ChangeMemberRoleRequest request) {
+ public String changeMemberRole(HttpServletRequest httpServletRequest, String memberId,
+ ChangeMemberRoleRequest request) {
Member member = retrieveMemberPort.getById(memberId);
Role oldRole = member.getRole();
diff --git a/src/main/java/page/clab/api/domain/members/membershipFee/application/service/MembershipFeeRegisterService.java b/src/main/java/page/clab/api/domain/members/membershipFee/application/service/MembershipFeeRegisterService.java
index 3d50a19e3..62f3723ff 100644
--- a/src/main/java/page/clab/api/domain/members/membershipFee/application/service/MembershipFeeRegisterService.java
+++ b/src/main/java/page/clab/api/domain/members/membershipFee/application/service/MembershipFeeRegisterService.java
@@ -11,7 +11,7 @@
import page.clab.api.domain.members.membershipFee.domain.MembershipFee;
import page.clab.api.external.memberManagement.member.application.port.ExternalRetrieveMemberUseCase;
import page.clab.api.external.memberManagement.notification.application.port.ExternalSendNotificationUseCase;
-import page.clab.api.global.common.slack.application.SlackService;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
import page.clab.api.global.common.slack.domain.SlackMembershipFeeInfo;
@Service
diff --git a/src/main/java/page/clab/api/external/auth/accountLockInfo/port/ExternalAccountLockManagementService.java b/src/main/java/page/clab/api/external/auth/accountLockInfo/port/ExternalAccountLockManagementService.java
index 4a9eb6dde..428ce931b 100644
--- a/src/main/java/page/clab/api/external/auth/accountLockInfo/port/ExternalAccountLockManagementService.java
+++ b/src/main/java/page/clab/api/external/auth/accountLockInfo/port/ExternalAccountLockManagementService.java
@@ -13,8 +13,8 @@
import page.clab.api.domain.memberManagement.member.application.dto.shared.MemberDetailedInfoDto;
import page.clab.api.external.auth.accountLockInfo.application.ExternalManageAccountLockUseCase;
import page.clab.api.external.memberManagement.member.application.port.ExternalRetrieveMemberUseCase;
-import page.clab.api.global.common.slack.application.SlackService;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
@Service
@RequiredArgsConstructor
@@ -39,7 +39,7 @@ public class ExternalAccountLockManagementService implements ExternalManageAccou
*
* @param memberId 잠금 해제하려는 멤버의 ID
* @throws MemberLockedException 계정이 현재 잠겨 있을 경우 예외 발생
- * @throws LoginFailedException 멤버가 존재하지 않을 경우 예외 발생
+ * @throws LoginFailedException 멤버가 존재하지 않을 경우 예외 발생
*/
@Transactional
@Override
@@ -55,17 +55,17 @@ public void handleAccountLockInfo(String memberId) throws MemberLockedException,
* 로그인 실패를 처리하고 계정 잠금을 관리합니다.
*
* 로그인 실패 시 멤버의 존재 여부와 계정 잠금 상태를 확인합니다.
- * 로그인 실패 횟수를 증가시키며, 설정된 최대 실패 횟수에 도달하면 계정을 잠그고
- * Slack에 보안 알림을 전송합니다.
+ * 로그인 실패 횟수를 증가시키며, 설정된 최대 실패 횟수에 도달하면 계정을 잠그고 Slack에 보안 알림을 전송합니다.
*
- * @param request 현재 HTTP 요청 객체
+ * @param request 현재 HTTP 요청 객체
* @param memberId 로그인 실패를 기록할 멤버의 ID
* @throws MemberLockedException 계정이 현재 잠겨 있을 경우 예외 발생
- * @throws LoginFailedException 멤버가 존재하지 않을 경우 예외 발생
+ * @throws LoginFailedException 멤버가 존재하지 않을 경우 예외 발생
*/
@Transactional
@Override
- public void handleLoginFailure(HttpServletRequest request, String memberId) throws MemberLockedException, LoginFailedException {
+ public void handleLoginFailure(HttpServletRequest request, String memberId)
+ throws MemberLockedException, LoginFailedException {
ensureMemberExists(memberId);
AccountLockInfo accountLockInfo = ensureAccountLockInfo(memberId);
validateAccountLockStatus(accountLockInfo);
@@ -99,7 +99,8 @@ private void sendSlackLoginFailureNotification(HttpServletRequest request, Strin
String memberName = memberInfo.getMemberName();
if (memberInfo.isAdminRole()) {
request.setAttribute("member", memberId + " " + memberName);
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.REPEATED_LOGIN_FAILURES, "로그인 실패 횟수 초과로 계정이 잠겼습니다.");
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.REPEATED_LOGIN_FAILURES,
+ "로그인 실패 횟수 초과로 계정이 잠겼습니다.");
}
}
}
diff --git a/src/main/java/page/clab/api/external/auth/redisIpAccessMonitor/application/service/ExternalIpAccessMonitorRegisterService.java b/src/main/java/page/clab/api/external/auth/redisIpAccessMonitor/application/service/ExternalIpAccessMonitorRegisterService.java
index a600c8b3d..e6a63f21e 100644
--- a/src/main/java/page/clab/api/external/auth/redisIpAccessMonitor/application/service/ExternalIpAccessMonitorRegisterService.java
+++ b/src/main/java/page/clab/api/external/auth/redisIpAccessMonitor/application/service/ExternalIpAccessMonitorRegisterService.java
@@ -10,8 +10,8 @@
import page.clab.api.domain.auth.redisIpAccessMonitor.application.port.out.RetrieveIpAccessMonitorPort;
import page.clab.api.domain.auth.redisIpAccessMonitor.domain.RedisIpAccessMonitor;
import page.clab.api.external.auth.redisIpAccessMonitor.application.port.ExternalRegisterIpAccessMonitorUseCase;
-import page.clab.api.global.common.slack.application.SlackService;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
@Service
@RequiredArgsConstructor
@@ -29,7 +29,8 @@ public class ExternalIpAccessMonitorRegisterService implements ExternalRegisterI
public void registerIpAccessMonitor(HttpServletRequest request, String ipAddress) {
RedisIpAccessMonitor redisIpAccessMonitor = getOrCreateRedisIpAccessMonitor(ipAddress);
if (redisIpAccessMonitor.isBlocked()) {
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.ABNORMAL_ACCESS_IP_BLOCKED, "Blocked IP: " + ipAddress);
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.ABNORMAL_ACCESS_IP_BLOCKED,
+ "Blocked IP: " + ipAddress);
}
registerIpAccessMonitorPort.save(redisIpAccessMonitor);
}
diff --git a/src/main/java/page/clab/api/global/auth/filter/CustomBasicAuthenticationFilter.java b/src/main/java/page/clab/api/global/auth/filter/CustomBasicAuthenticationFilter.java
index 954d80f94..100c32390 100644
--- a/src/main/java/page/clab/api/global/auth/filter/CustomBasicAuthenticationFilter.java
+++ b/src/main/java/page/clab/api/global/auth/filter/CustomBasicAuthenticationFilter.java
@@ -4,6 +4,8 @@
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Base64;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.security.authentication.AuthenticationManager;
@@ -15,21 +17,17 @@
import page.clab.api.external.auth.blacklistIp.application.port.ExternalRetrieveBlacklistIpUseCase;
import page.clab.api.external.auth.redisIpAccessMonitor.application.port.ExternalCheckIpBlockedUseCase;
import page.clab.api.global.auth.util.IpWhitelistValidator;
-import page.clab.api.global.common.slack.application.SlackService;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
import page.clab.api.global.util.HttpReqResUtil;
import page.clab.api.global.util.ResponseUtil;
import page.clab.api.global.util.WhitelistPathMatcher;
-import java.io.IOException;
-import java.util.Base64;
-
/**
* {@code CustomBasicAuthenticationFilter}는 기본 인증 필터를 확장하여 추가적인 보안 기능을 제공합니다.
*
* IP 주소 기반 접근 제한, 화이트리스트 경로 검증, 사용자 인증 정보를 바탕으로
- * Slack 보안 알림을 전송하는 기능을 포함합니다. 또한 Swagger 또는 Actuator에 대한
- * 접근이 성공하거나 실패할 경우 이를 Slack에 알립니다.
+ * Slack 보안 알림을 전송하는 기능을 포함합니다. 또한 Swagger 또는 Actuator에 대한 접근이 성공하거나 실패할 경우 이를 Slack에 알립니다.
*
* 이 필터는 다음과 같은 추가 검증을 수행합니다:
*
@@ -65,6 +63,13 @@ public CustomBasicAuthenticationFilter(
this.slackService = slackService;
}
+ @NotNull
+ private static String[] decodeCredentials(String authorizationHeader) {
+ String base64Credentials = authorizationHeader.substring("Basic ".length());
+ String credentials = new String(Base64.getDecoder().decode(base64Credentials));
+ return credentials.split(":", 2);
+ }
+
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
@@ -82,7 +87,8 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
super.doFilterInternal(request, response, chain);
}
- private boolean authenticateUserCredentials(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ private boolean authenticateUserCredentials(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
String authorizationHeader = request.getHeader("Authorization");
if (authorizationHeader == null || !authorizationHeader.startsWith("Basic ")) {
response.setHeader("WWW-Authenticate", "Basic realm=\"Please enter your username and password\"");
@@ -122,28 +128,25 @@ private boolean verifyIpAddressAccess(HttpServletResponse response) throws IOExc
return true;
}
- @NotNull
- private static String[] decodeCredentials(String authorizationHeader) {
- String base64Credentials = authorizationHeader.substring("Basic ".length());
- String credentials = new String(Base64.getDecoder().decode(base64Credentials));
- return credentials.split(":", 2);
- }
-
private void sendAuthenticationSuccessAlertSlackMessage(HttpServletRequest request) {
String path = request.getRequestURI();
if (WhitelistPathMatcher.isSwaggerIndexEndpoint(path)) {
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.API_DOCS_ACCESS,"API 문서에 대한 접근이 허가되었습니다.");
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.API_DOCS_ACCESS,
+ "API 문서에 대한 접근이 허가되었습니다.");
} else if (WhitelistPathMatcher.isActuatorRequest(path)) {
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.ACTUATOR_ACCESS,"Actuator에 대한 접근이 허가되었습니다.");
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.ACTUATOR_ACCESS,
+ "Actuator에 대한 접근이 허가되었습니다.");
}
}
private void sendAuthenticationFailureAlertSlackMessage(HttpServletRequest request) {
String path = request.getRequestURI();
if (WhitelistPathMatcher.isSwaggerIndexEndpoint(path)) {
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.API_DOCS_ACCESS,"API 문서에 대한 접근이 거부되었습니다.");
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.API_DOCS_ACCESS,
+ "API 문서에 대한 접근이 거부되었습니다.");
} else if (WhitelistPathMatcher.isActuatorRequest(path)) {
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.ACTUATOR_ACCESS,"Actuator에 대한 접근이 거부되었습니다.");
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.ACTUATOR_ACCESS,
+ "Actuator에 대한 접근이 거부되었습니다.");
}
}
}
diff --git a/src/main/java/page/clab/api/global/auth/filter/InvalidEndpointAccessFilter.java b/src/main/java/page/clab/api/global/auth/filter/InvalidEndpointAccessFilter.java
index b8314f9bf..4291b37ff 100644
--- a/src/main/java/page/clab/api/global/auth/filter/InvalidEndpointAccessFilter.java
+++ b/src/main/java/page/clab/api/global/auth/filter/InvalidEndpointAccessFilter.java
@@ -6,6 +6,7 @@
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
@@ -14,17 +15,14 @@
import page.clab.api.domain.auth.blacklistIp.domain.BlacklistIp;
import page.clab.api.external.auth.blacklistIp.application.port.ExternalRegisterBlacklistIpUseCase;
import page.clab.api.external.auth.blacklistIp.application.port.ExternalRetrieveBlacklistIpUseCase;
-import page.clab.api.global.common.slack.application.SlackService;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
import page.clab.api.global.util.HttpReqResUtil;
import page.clab.api.global.util.ResponseUtil;
import page.clab.api.global.util.SecurityPatternChecker;
-import java.io.IOException;
-
/**
- * {@code InvalidEndpointAccessFilter}는 서버 내부 파일 및 디렉토리에 대한 비정상적인 접근을 차단하고
- * 보안 경고를 전송하는 필터입니다.
+ * {@code InvalidEndpointAccessFilter}는 서버 내부 파일 및 디렉토리에 대한 비정상적인 접근을 차단하고 보안 경고를 전송하는 필터입니다.
*
* 특정 패턴을 통해 비정상적인 접근 시도를 탐지하며, 비정상적인 경로로 접근을 시도한 IP를
* 블랙리스트에 등록하고, Slack을 통해 보안 경고 메시지를 전송합니다.
@@ -50,7 +48,8 @@ public class InvalidEndpointAccessFilter extends GenericFilterBean {
private final ExternalRetrieveBlacklistIpUseCase externalRetrieveBlacklistIpUseCase;
@Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String path = httpRequest.getRequestURI();
boolean isUploadedFileAccess = path.startsWith(fileURL);
@@ -75,7 +74,8 @@ private void handleSuspiciousAccess(HttpServletRequest request, HttpServletRespo
private void logSuspiciousAccess(HttpServletRequest request, String clientIpAddress) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- String id = (authentication == null || authentication.getName() == null) ? "anonymous" : authentication.getName();
+ String id =
+ (authentication == null || authentication.getName() == null) ? "anonymous" : authentication.getName();
String requestUrl = request.getRequestURI();
String httpMethod = request.getMethod();
int statusCode = HttpServletResponse.SC_FORBIDDEN;
@@ -98,6 +98,7 @@ private void sendSecurityAlerts(HttpServletRequest request, String clientIpAddre
String blacklistAddedMessage = "Added IP: " + clientIpAddress;
slackService.sendSecurityAlertNotification(request, SecurityAlertType.ABNORMAL_ACCESS, abnormalAccessMessage);
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.BLACKLISTED_IP_ADDED, blacklistAddedMessage);
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.BLACKLISTED_IP_ADDED,
+ blacklistAddedMessage);
}
}
diff --git a/src/main/java/page/clab/api/global/auth/filter/JwtAuthenticationFilter.java b/src/main/java/page/clab/api/global/auth/filter/JwtAuthenticationFilter.java
index 12bda3af8..4a61d3682 100644
--- a/src/main/java/page/clab/api/global/auth/filter/JwtAuthenticationFilter.java
+++ b/src/main/java/page/clab/api/global/auth/filter/JwtAuthenticationFilter.java
@@ -6,6 +6,7 @@
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
@@ -16,14 +17,12 @@
import page.clab.api.external.auth.redisIpAccessMonitor.application.port.ExternalCheckIpBlockedUseCase;
import page.clab.api.external.auth.redisToken.application.port.ExternalManageRedisTokenUseCase;
import page.clab.api.global.auth.jwt.JwtTokenProvider;
-import page.clab.api.global.common.slack.application.SlackService;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
import page.clab.api.global.util.HttpReqResUtil;
import page.clab.api.global.util.ResponseUtil;
import page.clab.api.global.util.WhitelistPathMatcher;
-import java.io.IOException;
-
/**
* {@code JwtAuthenticationFilter}는 JWT 토큰을 검증하고, IP 주소 기반 접근 제한을 수행하는 필터입니다.
*
@@ -52,7 +51,8 @@ public class JwtAuthenticationFilter extends GenericFilterBean {
private final ExternalRetrieveBlacklistIpUseCase externalRetrieveBlacklistIpUseCase;
@Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
String path = httpServletRequest.getRequestURI();
@@ -71,7 +71,8 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
}
private boolean verifyIpAddressAccess(HttpServletResponse response, String clientIpAddress) throws IOException {
- if (externalRetrieveBlacklistIpUseCase.existsByIpAddress(clientIpAddress) || externalCheckIpBlockedUseCase.isIpBlocked(clientIpAddress)) {
+ if (externalRetrieveBlacklistIpUseCase.existsByIpAddress(clientIpAddress)
+ || externalCheckIpBlockedUseCase.isIpBlocked(clientIpAddress)) {
log.info("[{}] : 서비스 이용이 제한된 IP입니다.", clientIpAddress);
ResponseUtil.sendErrorResponse(response, HttpServletResponse.SC_UNAUTHORIZED);
return false;
@@ -79,12 +80,15 @@ private boolean verifyIpAddressAccess(HttpServletResponse response, String clien
return true;
}
- private boolean authenticateToken(HttpServletRequest request, HttpServletResponse response, String clientIpAddress) throws IOException {
+ private boolean authenticateToken(HttpServletRequest request, HttpServletResponse response, String clientIpAddress)
+ throws IOException {
String token = jwtTokenProvider.resolveToken(request);
// 토큰이 존재하고 유효한 경우
if (token != null && jwtTokenProvider.validateToken(token)) {
- RedisToken redisToken = jwtTokenProvider.isRefreshToken(token) ? externalManageRedisTokenUseCase.findByRefreshToken(token) : externalManageRedisTokenUseCase.findByAccessToken(token);
+ RedisToken redisToken =
+ jwtTokenProvider.isRefreshToken(token) ? externalManageRedisTokenUseCase.findByRefreshToken(token)
+ : externalManageRedisTokenUseCase.findByAccessToken(token);
if (redisToken == null) {
log.warn("존재하지 않는 토큰입니다.");
ResponseUtil.sendErrorResponse(response, HttpServletResponse.SC_UNAUTHORIZED);
@@ -108,7 +112,8 @@ private boolean authenticateToken(HttpServletRequest request, HttpServletRespons
private void sendSecurityAlertSlackMessage(HttpServletRequest request, RedisToken redisToken) {
if (redisToken.isAdminToken()) {
request.setAttribute("member", redisToken.getId());
- slackService.sendSecurityAlertNotification(request, SecurityAlertType.DUPLICATE_LOGIN, "토큰 발급 IP와 다른 IP에서 접속하여 토큰을 삭제하였습니다.");
+ slackService.sendSecurityAlertNotification(request, SecurityAlertType.DUPLICATE_LOGIN,
+ "토큰 발급 IP와 다른 IP에서 접속하여 토큰을 삭제하였습니다.");
}
}
}
diff --git a/src/main/java/page/clab/api/global/common/slack/api/NotificationSettingController.java b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/in/web/NotificationSettingController.java
similarity index 81%
rename from src/main/java/page/clab/api/global/common/slack/api/NotificationSettingController.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/adapter/in/web/NotificationSettingController.java
index f242289d1..b20aec49c 100644
--- a/src/main/java/page/clab/api/global/common/slack/api/NotificationSettingController.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/in/web/NotificationSettingController.java
@@ -1,8 +1,9 @@
-package page.clab.api.global.common.slack.api;
+package page.clab.api.global.common.notificationSetting.adapter.in.web;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
+import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
@@ -11,11 +12,9 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import page.clab.api.global.common.dto.ApiResponse;
-import page.clab.api.global.common.slack.application.NotificationSettingService;
-import page.clab.api.global.common.slack.dto.request.NotificationSettingUpdateRequestDto;
-import page.clab.api.global.common.slack.dto.response.NotificationSettingResponseDto;
-
-import java.util.List;
+import page.clab.api.global.common.notificationSetting.application.dto.request.NotificationSettingUpdateRequestDto;
+import page.clab.api.global.common.notificationSetting.application.dto.response.NotificationSettingResponseDto;
+import page.clab.api.global.common.notificationSetting.application.service.NotificationSettingService;
@RestController
@RequestMapping("/api/v1/notification-settings")
diff --git a/src/main/java/page/clab/api/global/common/slack/dao/NotificationSettingRepository.java b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/persistence/NotificationSettingRepository.java
similarity index 52%
rename from src/main/java/page/clab/api/global/common/slack/dao/NotificationSettingRepository.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/persistence/NotificationSettingRepository.java
index e4cab3c38..4be9efb7b 100644
--- a/src/main/java/page/clab/api/global/common/slack/dao/NotificationSettingRepository.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/persistence/NotificationSettingRepository.java
@@ -1,10 +1,9 @@
-package page.clab.api.global.common.slack.dao;
-
-import org.springframework.data.jpa.repository.JpaRepository;
-import page.clab.api.global.common.slack.domain.AlertType;
-import page.clab.api.global.common.slack.domain.NotificationSetting;
+package page.clab.api.global.common.notificationSetting.adapter.out.persistence;
import java.util.Optional;
+import org.springframework.data.jpa.repository.JpaRepository;
+import page.clab.api.global.common.notificationSetting.domain.AlertType;
+import page.clab.api.global.common.notificationSetting.domain.NotificationSetting;
public interface NotificationSettingRepository extends JpaRepository {
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/slack/SlackNotificationSender.java b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/slack/SlackNotificationSender.java
new file mode 100644
index 000000000..c7a5ff764
--- /dev/null
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/slack/SlackNotificationSender.java
@@ -0,0 +1,19 @@
+package page.clab.api.global.common.notificationSetting.adapter.out.slack;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import page.clab.api.global.common.notificationSetting.application.event.NotificationEvent;
+import page.clab.api.global.common.notificationSetting.application.port.out.NotificationSender;
+
+@Component
+@RequiredArgsConstructor
+public class SlackNotificationSender implements NotificationSender {
+
+ private final SlackServiceHelper slackServiceHelper;
+
+ @Override
+ public void sendNotification(NotificationEvent event) {
+ slackServiceHelper.sendSlackMessage(event.getWebhookUrl(), event.getAlertType(), event.getRequest(),
+ event.getAdditionalData());
+ }
+}
diff --git a/src/main/java/page/clab/api/global/common/slack/application/SlackService.java b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/slack/SlackService.java
similarity index 65%
rename from src/main/java/page/clab/api/global/common/slack/application/SlackService.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/slack/SlackService.java
index dca15b3a9..8168a5a6c 100644
--- a/src/main/java/page/clab/api/global/common/slack/application/SlackService.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/slack/SlackService.java
@@ -1,4 +1,4 @@
-package page.clab.api.global.common.slack.application;
+package page.clab.api.global.common.notificationSetting.adapter.out.slack;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.context.ApplicationEventPublisher;
@@ -7,13 +7,13 @@
import org.springframework.stereotype.Service;
import page.clab.api.domain.hiring.application.application.dto.request.ApplicationRequestDto;
import page.clab.api.domain.memberManagement.member.application.dto.shared.MemberLoginInfoDto;
-import page.clab.api.global.common.slack.domain.ExecutivesAlertType;
-import page.clab.api.global.common.slack.domain.GeneralAlertType;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
+import page.clab.api.global.common.notificationSetting.application.event.NotificationEvent;
+import page.clab.api.global.common.notificationSetting.domain.ExecutivesAlertType;
+import page.clab.api.global.common.notificationSetting.domain.GeneralAlertType;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
import page.clab.api.global.common.slack.domain.SlackBoardInfo;
import page.clab.api.global.common.slack.domain.SlackBookLoanRecordInfo;
import page.clab.api.global.common.slack.domain.SlackMembershipFeeInfo;
-import page.clab.api.global.common.slack.event.NotificationEvent;
import page.clab.api.global.config.SlackConfig;
/**
@@ -21,7 +21,7 @@
*
* 이 서비스는 `NotificationEvent`를 통해 Slack 알림을 발송하며,
* 서버 시작, 서버 오류, 보안 경고, 관리자 로그인 등의 알림 유형을 제공합니다.
- *
+ *
* 주요 기능:
*
* - {@link #sendServerErrorNotification(HttpServletRequest, Exception)} - 서버 오류 발생 시 Slack으로 알림을 전송합니다.
@@ -48,35 +48,47 @@ public SlackService(ApplicationEventPublisher eventPublisher, SlackConfig slackC
}
public void sendServerErrorNotification(HttpServletRequest request, Exception e) {
- eventPublisher.publishEvent(new NotificationEvent(this, coreTeamWebhookUrl, GeneralAlertType.SERVER_ERROR, request, e));
+ eventPublisher.publishEvent(
+ new NotificationEvent(this, coreTeamWebhookUrl, GeneralAlertType.SERVER_ERROR, request, e));
}
- public void sendSecurityAlertNotification(HttpServletRequest request, SecurityAlertType alertType, String additionalMessage) {
- eventPublisher.publishEvent(new NotificationEvent(this, coreTeamWebhookUrl, alertType, request, additionalMessage));
+ public void sendSecurityAlertNotification(HttpServletRequest request, SecurityAlertType alertType,
+ String additionalMessage) {
+ eventPublisher.publishEvent(
+ new NotificationEvent(this, coreTeamWebhookUrl, alertType, request, additionalMessage));
}
public void sendAdminLoginNotification(HttpServletRequest request, MemberLoginInfoDto loginMember) {
- eventPublisher.publishEvent(new NotificationEvent(this, coreTeamWebhookUrl, GeneralAlertType.ADMIN_LOGIN, request, loginMember));
+ eventPublisher.publishEvent(
+ new NotificationEvent(this, coreTeamWebhookUrl, GeneralAlertType.ADMIN_LOGIN, request, loginMember));
}
public void sendNewApplicationNotification(ApplicationRequestDto applicationRequestDto) {
- eventPublisher.publishEvent(new NotificationEvent(this, executivesWebhookUrl, ExecutivesAlertType.NEW_APPLICATION, null, applicationRequestDto));
+ eventPublisher.publishEvent(
+ new NotificationEvent(this, executivesWebhookUrl, ExecutivesAlertType.NEW_APPLICATION, null,
+ applicationRequestDto));
}
public void sendNewBoardNotification(SlackBoardInfo board) {
- eventPublisher.publishEvent(new NotificationEvent(this, executivesWebhookUrl, ExecutivesAlertType.NEW_BOARD, null, board));
+ eventPublisher.publishEvent(
+ new NotificationEvent(this, executivesWebhookUrl, ExecutivesAlertType.NEW_BOARD, null, board));
}
public void sendNewMembershipFeeNotification(SlackMembershipFeeInfo membershipFee) {
- eventPublisher.publishEvent(new NotificationEvent(this, executivesWebhookUrl, ExecutivesAlertType.NEW_MEMBERSHIP_FEE, null, membershipFee));
+ eventPublisher.publishEvent(
+ new NotificationEvent(this, executivesWebhookUrl, ExecutivesAlertType.NEW_MEMBERSHIP_FEE, null,
+ membershipFee));
}
public void sendNewBookLoanRequestNotification(SlackBookLoanRecordInfo bookLoanRecord) {
- eventPublisher.publishEvent(new NotificationEvent(this, executivesWebhookUrl, ExecutivesAlertType.NEW_BOOK_LOAN_REQUEST, null, bookLoanRecord));
+ eventPublisher.publishEvent(
+ new NotificationEvent(this, executivesWebhookUrl, ExecutivesAlertType.NEW_BOOK_LOAN_REQUEST, null,
+ bookLoanRecord));
}
@EventListener(ContextRefreshedEvent.class)
public void sendServerStartNotification() {
- eventPublisher.publishEvent(new NotificationEvent(this, coreTeamWebhookUrl, GeneralAlertType.SERVER_START, null, null));
+ eventPublisher.publishEvent(
+ new NotificationEvent(this, coreTeamWebhookUrl, GeneralAlertType.SERVER_START, null, null));
}
}
diff --git a/src/main/java/page/clab/api/global/common/slack/application/SlackServiceHelper.java b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/slack/SlackServiceHelper.java
similarity index 93%
rename from src/main/java/page/clab/api/global/common/slack/application/SlackServiceHelper.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/slack/SlackServiceHelper.java
index a3b2c3edf..a2f288bd1 100644
--- a/src/main/java/page/clab/api/global/common/slack/application/SlackServiceHelper.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/slack/SlackServiceHelper.java
@@ -1,19 +1,32 @@
-package page.clab.api.global.common.slack.application;
+package page.clab.api.global.common.notificationSetting.adapter.out.slack;
-import com.slack.api.Slack;
-import com.slack.api.model.Attachment;
import static com.slack.api.model.block.Blocks.actions;
import static com.slack.api.model.block.Blocks.section;
-import com.slack.api.model.block.LayoutBlock;
import static com.slack.api.model.block.composition.BlockCompositions.markdownText;
import static com.slack.api.model.block.composition.BlockCompositions.plainText;
import static com.slack.api.model.block.element.BlockElements.asElements;
import static com.slack.api.model.block.element.BlockElements.button;
+
+import com.slack.api.Slack;
+import com.slack.api.model.Attachment;
+import com.slack.api.model.block.LayoutBlock;
import com.slack.api.webhook.Payload;
import com.slack.api.webhook.WebhookResponse;
import io.ipinfo.api.model.IPResponse;
import io.ipinfo.spring.strategies.attribute.AttributeStrategy;
import jakarta.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.MemoryUsage;
+import java.lang.management.OperatingSystemMXBean;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.core.env.Environment;
@@ -22,29 +35,16 @@
import org.springframework.stereotype.Component;
import page.clab.api.domain.hiring.application.application.dto.request.ApplicationRequestDto;
import page.clab.api.domain.memberManagement.member.application.dto.shared.MemberLoginInfoDto;
-import page.clab.api.global.common.slack.domain.AlertType;
-import page.clab.api.global.common.slack.domain.ExecutivesAlertType;
-import page.clab.api.global.common.slack.domain.GeneralAlertType;
-import page.clab.api.global.common.slack.domain.SecurityAlertType;
+import page.clab.api.global.common.notificationSetting.domain.AlertType;
+import page.clab.api.global.common.notificationSetting.domain.ExecutivesAlertType;
+import page.clab.api.global.common.notificationSetting.domain.GeneralAlertType;
+import page.clab.api.global.common.notificationSetting.domain.SecurityAlertType;
import page.clab.api.global.common.slack.domain.SlackBoardInfo;
import page.clab.api.global.common.slack.domain.SlackBookLoanRecordInfo;
import page.clab.api.global.common.slack.domain.SlackMembershipFeeInfo;
import page.clab.api.global.config.SlackConfig;
import page.clab.api.global.util.HttpReqResUtil;
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.lang.management.MemoryMXBean;
-import java.lang.management.MemoryUsage;
-import java.lang.management.OperatingSystemMXBean;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
-import java.util.stream.Collectors;
-
/**
* {@code SlackServiceHelper}는 다양한 알림 유형에 따라 Slack 메시지를 구성하고 전송하는 클래스입니다.
*
@@ -90,13 +90,14 @@ public SlackServiceHelper(SlackConfig slackConfig, Environment environment, Attr
* 주어진 webhookUrl과 alertType, HttpServletRequest 및 추가 데이터(additionalData)를 사용하여 알림 메시지를
* 비동기적으로 Slack에 전송합니다.
*
- * @param webhookUrl 메시지를 보낼 Slack 웹훅 URL
- * @param alertType 알림 유형을 나타내는 {@link AlertType}
- * @param request HttpServletRequest 객체, 클라이언트 요청 정보
+ * @param webhookUrl 메시지를 보낼 Slack 웹훅 URL
+ * @param alertType 알림 유형을 나타내는 {@link AlertType}
+ * @param request HttpServletRequest 객체, 클라이언트 요청 정보
* @param additionalData 추가 데이터
* @return 메시지 전송 성공 여부를 나타내는 CompletableFuture
*/
- public CompletableFuture sendSlackMessage(String webhookUrl, AlertType alertType, HttpServletRequest request, Object additionalData) {
+ public CompletableFuture sendSlackMessage(String webhookUrl, AlertType alertType,
+ HttpServletRequest request, Object additionalData) {
List blocks = createBlocks(alertType, request, additionalData);
return CompletableFuture.supplyAsync(() -> {
Payload payload = Payload.builder()
@@ -127,8 +128,8 @@ public CompletableFuture sendSlackMessage(String webhookUrl, AlertType
*
* AlertType에 따라 보안 경고, 일반 알림, 운영진 알림 등 다양한 형식의 메시지를 생성합니다.
*
- * @param alertType 알림 유형
- * @param request HttpServletRequest 객체
+ * @param alertType 알림 유형
+ * @param request HttpServletRequest 객체
* @param additionalData 추가 데이터
* @return 생성된 LayoutBlock 목록
*/
@@ -204,7 +205,8 @@ private List createErrorBlocks(HttpServletRequest request, Exceptio
);
}
- private List createSecurityAlertBlocks(HttpServletRequest request, AlertType alertType, String additionalMessage) {
+ private List createSecurityAlertBlocks(HttpServletRequest request, AlertType alertType,
+ String additionalMessage) {
String clientIpAddress = HttpReqResUtil.getClientIpAddressIfServletRequestExist();
String requestUrl = request.getRequestURI();
String queryString = request.getQueryString();
@@ -220,7 +222,8 @@ private List createSecurityAlertBlocks(HttpServletRequest request,
markdownText("*Location:*\n" + location),
markdownText("*Endpoint:*\n" + fullUrl)
))),
- section(section -> section.text(markdownText("*Details:*\n" + alertType.getDefaultMessage() + "\n" + additionalMessage)))
+ section(section -> section.text(
+ markdownText("*Details:*\n" + alertType.getDefaultMessage() + "\n" + additionalMessage)))
);
}
@@ -229,7 +232,8 @@ private List createAdminLoginBlocks(HttpServletRequest request, Mem
String location = getLocation(request);
return Arrays.asList(
- section(section -> section.text(markdownText(String.format(":mechanic: *%s Login*", loginMember.getRole().getDescription())))),
+ section(section -> section.text(
+ markdownText(String.format(":mechanic: *%s Login*", loginMember.getRole().getDescription())))),
section(section -> section.fields(Arrays.asList(
markdownText("*User:*\n" + loginMember.getMemberId() + " " + loginMember.getMemberName()),
markdownText("*IP Address:*\n" + clientIpAddress),
diff --git a/src/main/java/page/clab/api/global/common/slack/dto/mapper/SlackDtoMapper.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/dto/mapper/NotificationSettingDtoMapper.java
similarity index 51%
rename from src/main/java/page/clab/api/global/common/slack/dto/mapper/SlackDtoMapper.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/application/dto/mapper/NotificationSettingDtoMapper.java
index f2b75b6a3..4b092100a 100644
--- a/src/main/java/page/clab/api/global/common/slack/dto/mapper/SlackDtoMapper.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/dto/mapper/NotificationSettingDtoMapper.java
@@ -1,11 +1,11 @@
-package page.clab.api.global.common.slack.dto.mapper;
+package page.clab.api.global.common.notificationSetting.application.dto.mapper;
import org.springframework.stereotype.Component;
-import page.clab.api.global.common.slack.domain.NotificationSetting;
-import page.clab.api.global.common.slack.dto.response.NotificationSettingResponseDto;
+import page.clab.api.global.common.notificationSetting.application.dto.response.NotificationSettingResponseDto;
+import page.clab.api.global.common.notificationSetting.domain.NotificationSetting;
@Component
-public class SlackDtoMapper {
+public class NotificationSettingDtoMapper {
public NotificationSettingResponseDto toDto(NotificationSetting setting) {
return NotificationSettingResponseDto.builder()
diff --git a/src/main/java/page/clab/api/global/common/slack/dto/request/NotificationSettingUpdateRequestDto.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/dto/request/NotificationSettingUpdateRequestDto.java
similarity index 87%
rename from src/main/java/page/clab/api/global/common/slack/dto/request/NotificationSettingUpdateRequestDto.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/application/dto/request/NotificationSettingUpdateRequestDto.java
index fcd941924..b0db80a2e 100644
--- a/src/main/java/page/clab/api/global/common/slack/dto/request/NotificationSettingUpdateRequestDto.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/dto/request/NotificationSettingUpdateRequestDto.java
@@ -1,4 +1,4 @@
-package page.clab.api.global.common.slack.dto.request;
+package page.clab.api.global.common.notificationSetting.application.dto.request;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
diff --git a/src/main/java/page/clab/api/global/common/slack/dto/response/NotificationSettingResponseDto.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/dto/response/NotificationSettingResponseDto.java
similarity index 67%
rename from src/main/java/page/clab/api/global/common/slack/dto/response/NotificationSettingResponseDto.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/application/dto/response/NotificationSettingResponseDto.java
index ffbbd87b9..8eeaf2256 100644
--- a/src/main/java/page/clab/api/global/common/slack/dto/response/NotificationSettingResponseDto.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/dto/response/NotificationSettingResponseDto.java
@@ -1,4 +1,4 @@
-package page.clab.api.global.common.slack.dto.response;
+package page.clab.api.global.common.notificationSetting.application.dto.response;
import lombok.Builder;
import lombok.Getter;
diff --git a/src/main/java/page/clab/api/global/common/slack/event/NotificationEvent.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/event/NotificationEvent.java
similarity index 70%
rename from src/main/java/page/clab/api/global/common/slack/event/NotificationEvent.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/application/event/NotificationEvent.java
index 59bfb5158..0d107d760 100644
--- a/src/main/java/page/clab/api/global/common/slack/event/NotificationEvent.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/event/NotificationEvent.java
@@ -1,9 +1,9 @@
-package page.clab.api.global.common.slack.event;
+package page.clab.api.global.common.notificationSetting.application.event;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Getter;
import org.springframework.context.ApplicationEvent;
-import page.clab.api.global.common.slack.domain.AlertType;
+import page.clab.api.global.common.notificationSetting.domain.AlertType;
@Getter
public class NotificationEvent extends ApplicationEvent {
@@ -13,7 +13,8 @@ public class NotificationEvent extends ApplicationEvent {
private final HttpServletRequest request;
private final Object additionalData;
- public NotificationEvent(Object source, String webhookUrl, AlertType alertType, HttpServletRequest request, Object additionalData) {
+ public NotificationEvent(Object source, String webhookUrl, AlertType alertType, HttpServletRequest request,
+ Object additionalData) {
super(source);
this.webhookUrl = webhookUrl;
this.alertType = alertType;
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/application/event/NotificationListener.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/event/NotificationListener.java
new file mode 100644
index 000000000..51c764a21
--- /dev/null
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/event/NotificationListener.java
@@ -0,0 +1,27 @@
+package page.clab.api.global.common.notificationSetting.application.event;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Component;
+import page.clab.api.global.common.notificationSetting.application.port.out.NotificationSender;
+import page.clab.api.global.common.notificationSetting.application.service.NotificationSettingService;
+import page.clab.api.global.common.notificationSetting.domain.AlertType;
+import page.clab.api.global.common.notificationSetting.domain.NotificationSetting;
+
+@Component
+@RequiredArgsConstructor
+public class NotificationListener {
+
+ private final NotificationSettingService settingService;
+ private final NotificationSender notificationSender;
+
+ @EventListener
+ public void handleNotificationEvent(NotificationEvent event) {
+ AlertType alertType = event.getAlertType();
+ NotificationSetting setting = settingService.getOrCreateDefaultSetting(alertType);
+
+ if (setting.isEnabled()) {
+ notificationSender.sendNotification(event);
+ }
+ }
+}
diff --git a/src/main/java/page/clab/api/global/common/slack/exception/AlertTypeNotFoundException.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/exception/AlertTypeNotFoundException.java
similarity index 71%
rename from src/main/java/page/clab/api/global/common/slack/exception/AlertTypeNotFoundException.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/application/exception/AlertTypeNotFoundException.java
index c52c39796..94de58360 100644
--- a/src/main/java/page/clab/api/global/common/slack/exception/AlertTypeNotFoundException.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/exception/AlertTypeNotFoundException.java
@@ -1,4 +1,4 @@
-package page.clab.api.global.common.slack.exception;
+package page.clab.api.global.common.notificationSetting.application.exception;
public class AlertTypeNotFoundException extends RuntimeException {
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/application/port/out/NotificationSender.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/port/out/NotificationSender.java
new file mode 100644
index 000000000..c06f60811
--- /dev/null
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/port/out/NotificationSender.java
@@ -0,0 +1,8 @@
+package page.clab.api.global.common.notificationSetting.application.port.out;
+
+import page.clab.api.global.common.notificationSetting.application.event.NotificationEvent;
+
+public interface NotificationSender {
+
+ void sendNotification(NotificationEvent event);
+}
diff --git a/src/main/java/page/clab/api/global/common/slack/application/NotificationSettingService.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/service/NotificationSettingService.java
similarity index 75%
rename from src/main/java/page/clab/api/global/common/slack/application/NotificationSettingService.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/application/service/NotificationSettingService.java
index 4ce06b79b..98a69ecda 100644
--- a/src/main/java/page/clab/api/global/common/slack/application/NotificationSettingService.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/service/NotificationSettingService.java
@@ -1,23 +1,22 @@
-package page.clab.api.global.common.slack.application;
+package page.clab.api.global.common.notificationSetting.application.service;
+import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import page.clab.api.global.common.slack.dao.NotificationSettingRepository;
-import page.clab.api.global.common.slack.domain.AlertType;
-import page.clab.api.global.common.slack.domain.AlertTypeResolver;
-import page.clab.api.global.common.slack.domain.NotificationSetting;
-import page.clab.api.global.common.slack.dto.mapper.SlackDtoMapper;
-import page.clab.api.global.common.slack.dto.response.NotificationSettingResponseDto;
-
-import java.util.List;
+import page.clab.api.global.common.notificationSetting.adapter.out.persistence.NotificationSettingRepository;
+import page.clab.api.global.common.notificationSetting.application.dto.mapper.NotificationSettingDtoMapper;
+import page.clab.api.global.common.notificationSetting.application.dto.response.NotificationSettingResponseDto;
+import page.clab.api.global.common.notificationSetting.domain.AlertType;
+import page.clab.api.global.common.notificationSetting.domain.AlertTypeResolver;
+import page.clab.api.global.common.notificationSetting.domain.NotificationSetting;
/**
* {@code NotificationSettingService}는 알림 설정을 조회 및 업데이트하는 서비스입니다.
*
* 이 서비스는 알림 유형에 따라 활성화 또는 비활성화할 수 있는 설정 기능을 제공하며,
* 기본 알림 설정을 생성하거나 조회할 수 있습니다.
- *
+ *
* 주요 기능:
*
* - {@link #getNotificationSettings()} - 모든 알림 설정을 조회합니다.
@@ -31,7 +30,7 @@ public class NotificationSettingService {
private final AlertTypeResolver alertTypeResolver;
private final NotificationSettingRepository settingRepository;
- private final SlackDtoMapper mapper;
+ private final NotificationSettingDtoMapper mapper;
@Transactional(readOnly = true)
public List getNotificationSettings() {
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/config/NotificationConfig.java b/src/main/java/page/clab/api/global/common/notificationSetting/config/NotificationConfig.java
new file mode 100644
index 000000000..ddbfa22fc
--- /dev/null
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/config/NotificationConfig.java
@@ -0,0 +1,21 @@
+package page.clab.api.global.common.notificationSetting.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackNotificationSender;
+import page.clab.api.global.common.notificationSetting.application.port.out.NotificationSender;
+
+@Configuration
+public class NotificationConfig {
+
+ private final SlackNotificationSender slackNotificationSender;
+
+ public NotificationConfig(SlackNotificationSender slackNotificationSender) {
+ this.slackNotificationSender = slackNotificationSender;
+ }
+
+ @Bean
+ public NotificationSender notificationSender() {
+ return slackNotificationSender;
+ }
+}
diff --git a/src/main/java/page/clab/api/global/common/slack/domain/AlertType.java b/src/main/java/page/clab/api/global/common/notificationSetting/domain/AlertType.java
similarity index 58%
rename from src/main/java/page/clab/api/global/common/slack/domain/AlertType.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/domain/AlertType.java
index 99c52fd8f..34eac0469 100644
--- a/src/main/java/page/clab/api/global/common/slack/domain/AlertType.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/domain/AlertType.java
@@ -1,4 +1,4 @@
-package page.clab.api.global.common.slack.domain;
+package page.clab.api.global.common.notificationSetting.domain;
public interface AlertType {
diff --git a/src/main/java/page/clab/api/global/common/slack/domain/AlertTypeConverter.java b/src/main/java/page/clab/api/global/common/notificationSetting/domain/AlertTypeConverter.java
similarity index 88%
rename from src/main/java/page/clab/api/global/common/slack/domain/AlertTypeConverter.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/domain/AlertTypeConverter.java
index 1755b529b..dfa397238 100644
--- a/src/main/java/page/clab/api/global/common/slack/domain/AlertTypeConverter.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/domain/AlertTypeConverter.java
@@ -1,11 +1,10 @@
-package page.clab.api.global.common.slack.domain;
+package page.clab.api.global.common.notificationSetting.domain;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
-import page.clab.api.global.common.slack.exception.AlertTypeNotFoundException;
-
import java.util.HashMap;
import java.util.Map;
+import page.clab.api.global.common.notificationSetting.application.exception.AlertTypeNotFoundException;
@Converter(autoApply = true)
public class AlertTypeConverter implements AttributeConverter {
diff --git a/src/main/java/page/clab/api/global/common/slack/domain/AlertTypeResolver.java b/src/main/java/page/clab/api/global/common/notificationSetting/domain/AlertTypeResolver.java
similarity index 77%
rename from src/main/java/page/clab/api/global/common/slack/domain/AlertTypeResolver.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/domain/AlertTypeResolver.java
index f2d580962..7fe3cc2dd 100644
--- a/src/main/java/page/clab/api/global/common/slack/domain/AlertTypeResolver.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/domain/AlertTypeResolver.java
@@ -1,7 +1,7 @@
-package page.clab.api.global.common.slack.domain;
+package page.clab.api.global.common.notificationSetting.domain;
import org.springframework.stereotype.Service;
-import page.clab.api.global.common.slack.exception.AlertTypeNotFoundException;
+import page.clab.api.global.common.notificationSetting.application.exception.AlertTypeNotFoundException;
@Service
public class AlertTypeResolver {
diff --git a/src/main/java/page/clab/api/global/common/slack/domain/ExecutivesAlertType.java b/src/main/java/page/clab/api/global/common/notificationSetting/domain/ExecutivesAlertType.java
similarity index 89%
rename from src/main/java/page/clab/api/global/common/slack/domain/ExecutivesAlertType.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/domain/ExecutivesAlertType.java
index 703b2974f..49e4365c4 100644
--- a/src/main/java/page/clab/api/global/common/slack/domain/ExecutivesAlertType.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/domain/ExecutivesAlertType.java
@@ -1,4 +1,4 @@
-package page.clab.api.global.common.slack.domain;
+package page.clab.api.global.common.notificationSetting.domain;
import lombok.AllArgsConstructor;
import lombok.Getter;
diff --git a/src/main/java/page/clab/api/global/common/slack/domain/GeneralAlertType.java b/src/main/java/page/clab/api/global/common/notificationSetting/domain/GeneralAlertType.java
similarity index 86%
rename from src/main/java/page/clab/api/global/common/slack/domain/GeneralAlertType.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/domain/GeneralAlertType.java
index 4b564bde7..3b78b146d 100644
--- a/src/main/java/page/clab/api/global/common/slack/domain/GeneralAlertType.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/domain/GeneralAlertType.java
@@ -1,4 +1,4 @@
-package page.clab.api.global.common.slack.domain;
+package page.clab.api.global.common.notificationSetting.domain;
import lombok.AllArgsConstructor;
import lombok.Getter;
diff --git a/src/main/java/page/clab/api/global/common/slack/domain/NotificationSetting.java b/src/main/java/page/clab/api/global/common/notificationSetting/domain/NotificationSetting.java
similarity index 94%
rename from src/main/java/page/clab/api/global/common/slack/domain/NotificationSetting.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/domain/NotificationSetting.java
index c352008a2..d9bd8f47f 100644
--- a/src/main/java/page/clab/api/global/common/slack/domain/NotificationSetting.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/domain/NotificationSetting.java
@@ -1,4 +1,4 @@
-package page.clab.api.global.common.slack.domain;
+package page.clab.api.global.common.notificationSetting.domain;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
diff --git a/src/main/java/page/clab/api/global/common/slack/domain/SecurityAlertType.java b/src/main/java/page/clab/api/global/common/notificationSetting/domain/SecurityAlertType.java
similarity index 95%
rename from src/main/java/page/clab/api/global/common/slack/domain/SecurityAlertType.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/domain/SecurityAlertType.java
index 4aa4d1b59..a8b1f6c7c 100644
--- a/src/main/java/page/clab/api/global/common/slack/domain/SecurityAlertType.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/domain/SecurityAlertType.java
@@ -1,4 +1,4 @@
-package page.clab.api.global.common.slack.domain;
+package page.clab.api.global.common.notificationSetting.domain;
import lombok.AllArgsConstructor;
import lombok.Getter;
diff --git a/src/main/java/page/clab/api/global/common/slack/listener/NotificationListener.java b/src/main/java/page/clab/api/global/common/slack/listener/NotificationListener.java
deleted file mode 100644
index e8463a03a..000000000
--- a/src/main/java/page/clab/api/global/common/slack/listener/NotificationListener.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package page.clab.api.global.common.slack.listener;
-
-import lombok.RequiredArgsConstructor;
-import org.springframework.context.event.EventListener;
-import org.springframework.stereotype.Component;
-import page.clab.api.global.common.slack.application.NotificationSettingService;
-import page.clab.api.global.common.slack.application.SlackServiceHelper;
-import page.clab.api.global.common.slack.domain.AlertType;
-import page.clab.api.global.common.slack.domain.NotificationSetting;
-import page.clab.api.global.common.slack.event.NotificationEvent;
-
-@Component
-@RequiredArgsConstructor
-public class NotificationListener {
-
- private final NotificationSettingService settingService;
- private final SlackServiceHelper slackServiceHelper;
-
- @EventListener
- public void handleNotificationEvent(NotificationEvent event) {
- AlertType alertType = event.getAlertType();
- NotificationSetting setting = settingService.getOrCreateDefaultSetting(alertType);
-
- if (setting.isEnabled()) {
- slackServiceHelper.sendSlackMessage(event.getWebhookUrl(), alertType, event.getRequest(), event.getAdditionalData());
- }
- }
-}
diff --git a/src/main/java/page/clab/api/global/config/SecurityConfig.java b/src/main/java/page/clab/api/global/config/SecurityConfig.java
index 0002f24be..5eee6a35d 100644
--- a/src/main/java/page/clab/api/global/config/SecurityConfig.java
+++ b/src/main/java/page/clab/api/global/config/SecurityConfig.java
@@ -2,6 +2,7 @@
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
@@ -34,14 +35,12 @@
import page.clab.api.global.auth.jwt.JwtTokenProvider;
import page.clab.api.global.auth.util.IpWhitelistValidator;
import page.clab.api.global.common.file.application.FileService;
-import page.clab.api.global.common.slack.application.SlackService;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
import page.clab.api.global.filter.IPinfoSpringFilter;
import page.clab.api.global.util.ApiLogger;
import page.clab.api.global.util.HttpReqResUtil;
import page.clab.api.global.util.ResponseUtil;
-import java.io.IOException;
-
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@@ -92,15 +91,18 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
UsernamePasswordAuthenticationFilter.class
)
.addFilterBefore(
- new InvalidEndpointAccessFilter(slackService, fileURL, externalRegisterBlacklistIpUseCase, externalRetrieveBlacklistIpUseCase),
+ new InvalidEndpointAccessFilter(slackService, fileURL, externalRegisterBlacklistIpUseCase,
+ externalRetrieveBlacklistIpUseCase),
UsernamePasswordAuthenticationFilter.class
)
.addFilterBefore(
- new CustomBasicAuthenticationFilter(authenticationManager, ipWhitelistValidator, slackService, externalCheckIpBlockedUseCase, externalRetrieveBlacklistIpUseCase),
+ new CustomBasicAuthenticationFilter(authenticationManager, ipWhitelistValidator, slackService,
+ externalCheckIpBlockedUseCase, externalRetrieveBlacklistIpUseCase),
UsernamePasswordAuthenticationFilter.class
)
.addFilterBefore(
- new JwtAuthenticationFilter(slackService, jwtTokenProvider, externalManageRedisTokenUseCase, externalCheckIpBlockedUseCase, externalRetrieveBlacklistIpUseCase),
+ new JwtAuthenticationFilter(slackService, jwtTokenProvider, externalManageRedisTokenUseCase,
+ externalCheckIpBlockedUseCase, externalRetrieveBlacklistIpUseCase),
UsernamePasswordAuthenticationFilter.class
)
// .addFilterBefore(
@@ -120,11 +122,13 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.requestMatchers(SecurityConstants.PERMIT_ALL).permitAll()
.requestMatchers(HttpMethod.GET, SecurityConstants.PERMIT_ALL_API_ENDPOINTS_GET).permitAll()
.requestMatchers(HttpMethod.POST, SecurityConstants.PERMIT_ALL_API_ENDPOINTS_POST).permitAll()
- .requestMatchers(whitelistPatternsProperties.getWhitelistPatterns()).hasRole(whitelistAccountProperties.getRole())
+ .requestMatchers(whitelistPatternsProperties.getWhitelistPatterns())
+ .hasRole(whitelistAccountProperties.getRole())
.anyRequest().authenticated();
}
- private void handleException(HttpServletRequest request, HttpServletResponse response, Exception exception) throws IOException {
+ private void handleException(HttpServletRequest request, HttpServletResponse response, Exception exception)
+ throws IOException {
String clientIpAddress = HttpReqResUtil.getClientIpAddressIfServletRequestExist();
String message;
int statusCode;
diff --git a/src/main/java/page/clab/api/global/handler/GlobalExceptionHandler.java b/src/main/java/page/clab/api/global/handler/GlobalExceptionHandler.java
index ac27a3774..7c3ee1d64 100644
--- a/src/main/java/page/clab/api/global/handler/GlobalExceptionHandler.java
+++ b/src/main/java/page/clab/api/global/handler/GlobalExceptionHandler.java
@@ -7,6 +7,10 @@
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.ConstraintViolationException;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.NoSuchElementException;
+import java.util.concurrent.CompletionException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.query.sqm.UnknownPathException;
@@ -75,7 +79,7 @@
import page.clab.api.global.common.file.exception.FileUploadFailException;
import page.clab.api.global.common.file.exception.InvalidFileAttributeException;
import page.clab.api.global.common.file.exception.InvalidPathVariableException;
-import page.clab.api.global.common.slack.application.SlackService;
+import page.clab.api.global.common.notificationSetting.adapter.out.slack.SlackService;
import page.clab.api.global.exception.CustomOptimisticLockingFailureException;
import page.clab.api.global.exception.DecryptionException;
import page.clab.api.global.exception.EncryptionException;
@@ -87,11 +91,6 @@
import page.clab.api.global.exception.PermissionDeniedException;
import page.clab.api.global.exception.SortingArgumentException;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.NoSuchElementException;
-import java.util.concurrent.CompletionException;
-
@RestControllerAdvice(basePackages = "page.clab.api")
@RequiredArgsConstructor
@Slf4j
From c7f39d2c1d4f31007c78d94738834ec1f0a98b07 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=ED=95=9C=EA=B4=80=ED=9D=AC?=
Date: Wed, 13 Nov 2024 23:30:49 +0900
Subject: [PATCH 02/24] =?UTF-8?q?refactor(Notification):=20=ED=97=A5?=
=?UTF-8?q?=EC=82=AC=EA=B3=A0=EB=82=A0=20=EC=95=84=ED=82=A4=ED=85=8D?=
=?UTF-8?q?=EC=B2=98=EC=9D=98=20=EA=B5=AC=EC=A1=B0=EC=97=90=20=EB=A7=9E?=
=?UTF-8?q?=EA=B2=8C=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A5=BC=20=EB=B6=84?=
=?UTF-8?q?=EB=A6=AC=ED=95=98=EA=B3=A0=20=EC=B6=94=EC=83=81=ED=99=94?=
=?UTF-8?q?=ED=95=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...NotificationSettingRetrieveController.java | 30 ++++++++++++++++
... NotificationSettingUpdateController.java} | 19 +++-------
...NotificationSettingPersistenceAdapter.java | 34 ++++++++++++++++++
.../event/NotificationListener.java | 6 ++--
.../RetrieveNotificationSettingUseCase.java | 9 +++++
.../in/UpdateNotificationSettingUseCase.java | 11 ++++++
.../out/RetrieveNotificationSettingPort.java | 13 +++++++
.../out/UpdateNotificationSettingPort.java | 8 +++++
.../RetrieveNotificationSettingService.java | 36 +++++++++++++++++++
... => UpdateNotificationSettingService.java} | 34 +++++++-----------
10 files changed, 161 insertions(+), 39 deletions(-)
create mode 100644 src/main/java/page/clab/api/global/common/notificationSetting/adapter/in/web/NotificationSettingRetrieveController.java
rename src/main/java/page/clab/api/global/common/notificationSetting/adapter/in/web/{NotificationSettingController.java => NotificationSettingUpdateController.java} (58%)
create mode 100644 src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/persistence/NotificationSettingPersistenceAdapter.java
create mode 100644 src/main/java/page/clab/api/global/common/notificationSetting/application/port/in/RetrieveNotificationSettingUseCase.java
create mode 100644 src/main/java/page/clab/api/global/common/notificationSetting/application/port/in/UpdateNotificationSettingUseCase.java
create mode 100644 src/main/java/page/clab/api/global/common/notificationSetting/application/port/out/RetrieveNotificationSettingPort.java
create mode 100644 src/main/java/page/clab/api/global/common/notificationSetting/application/port/out/UpdateNotificationSettingPort.java
create mode 100644 src/main/java/page/clab/api/global/common/notificationSetting/application/service/RetrieveNotificationSettingService.java
rename src/main/java/page/clab/api/global/common/notificationSetting/application/service/{NotificationSettingService.java => UpdateNotificationSettingService.java} (59%)
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/adapter/in/web/NotificationSettingRetrieveController.java b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/in/web/NotificationSettingRetrieveController.java
new file mode 100644
index 000000000..673db1696
--- /dev/null
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/in/web/NotificationSettingRetrieveController.java
@@ -0,0 +1,30 @@
+package page.clab.api.global.common.notificationSetting.adapter.in.web;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import page.clab.api.global.common.dto.ApiResponse;
+import page.clab.api.global.common.notificationSetting.application.dto.response.NotificationSettingResponseDto;
+import page.clab.api.global.common.notificationSetting.application.port.in.RetrieveNotificationSettingUseCase;
+
+@RestController
+@RequestMapping("/api/v1/notification-settings")
+@RequiredArgsConstructor
+@Tag(name = "Notification Setting", description = "알림 설정")
+public class NotificationSettingRetrieveController {
+
+ private final RetrieveNotificationSettingUseCase retrieveNotificationSettingUseCase;
+
+ @Operation(summary = "[S] 슬랙 알림 조회", description = "ROLE_SUPER 이상의 권한이 필요함")
+ @PreAuthorize("hasRole('SUPER')")
+ @GetMapping("")
+ public ApiResponse> getNotificationSettings() {
+ List notificationSettings = retrieveNotificationSettingUseCase.retrieveNotificationSettings();
+ return ApiResponse.success(notificationSettings);
+ }
+}
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/adapter/in/web/NotificationSettingController.java b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/in/web/NotificationSettingUpdateController.java
similarity index 58%
rename from src/main/java/page/clab/api/global/common/notificationSetting/adapter/in/web/NotificationSettingController.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/adapter/in/web/NotificationSettingUpdateController.java
index b20aec49c..bbe0b3342 100644
--- a/src/main/java/page/clab/api/global/common/notificationSetting/adapter/in/web/NotificationSettingController.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/in/web/NotificationSettingUpdateController.java
@@ -3,34 +3,23 @@
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
-import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import page.clab.api.global.common.dto.ApiResponse;
import page.clab.api.global.common.notificationSetting.application.dto.request.NotificationSettingUpdateRequestDto;
-import page.clab.api.global.common.notificationSetting.application.dto.response.NotificationSettingResponseDto;
-import page.clab.api.global.common.notificationSetting.application.service.NotificationSettingService;
+import page.clab.api.global.common.notificationSetting.application.port.in.UpdateNotificationSettingUseCase;
@RestController
@RequestMapping("/api/v1/notification-settings")
@RequiredArgsConstructor
@Tag(name = "Notification Setting", description = "알림 설정")
-public class NotificationSettingController {
+public class NotificationSettingUpdateController {
- private final NotificationSettingService notificationSettingService;
-
- @Operation(summary = "[S] 슬랙 알림 조회", description = "ROLE_SUPER 이상의 권한이 필요함")
- @PreAuthorize("hasRole('SUPER')")
- @GetMapping("")
- public ApiResponse> getNotificationSettings() {
- List notificationSettings = notificationSettingService.getNotificationSettings();
- return ApiResponse.success(notificationSettings);
- }
+ private final UpdateNotificationSettingUseCase updateNotificationSettingUseCase;
@Operation(summary = "[S] 슬랙 알림 설정 변경", description = "ROLE_SUPER 이상의 권한이 필요함")
@PreAuthorize("hasRole('SUPER')")
@@ -38,7 +27,7 @@ public ApiResponse> getNotificationSettings
public ApiResponse updateNotificationSetting(
@Valid @RequestBody NotificationSettingUpdateRequestDto requestDto
) {
- notificationSettingService.updateNotificationSetting(requestDto.getAlertType(), requestDto.isEnabled());
+ updateNotificationSettingUseCase.updateNotificationSetting(requestDto.getAlertType(), requestDto.isEnabled());
return ApiResponse.success();
}
}
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/persistence/NotificationSettingPersistenceAdapter.java b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/persistence/NotificationSettingPersistenceAdapter.java
new file mode 100644
index 000000000..4bae839c3
--- /dev/null
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/adapter/out/persistence/NotificationSettingPersistenceAdapter.java
@@ -0,0 +1,34 @@
+package page.clab.api.global.common.notificationSetting.adapter.out.persistence;
+
+import java.util.List;
+import java.util.Optional;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import page.clab.api.global.common.notificationSetting.application.port.out.RetrieveNotificationSettingPort;
+import page.clab.api.global.common.notificationSetting.application.port.out.UpdateNotificationSettingPort;
+import page.clab.api.global.common.notificationSetting.domain.AlertType;
+import page.clab.api.global.common.notificationSetting.domain.NotificationSetting;
+
+@Component
+@RequiredArgsConstructor
+public class NotificationSettingPersistenceAdapter implements
+ RetrieveNotificationSettingPort,
+ UpdateNotificationSettingPort {
+
+ private final NotificationSettingRepository repository;
+
+ @Override
+ public List findAll() {
+ return repository.findAll();
+ }
+
+ @Override
+ public Optional findByAlertType(AlertType alertType) {
+ return repository.findByAlertType(alertType);
+ }
+
+ @Override
+ public NotificationSetting save(NotificationSetting setting) {
+ return repository.save(setting);
+ }
+}
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/application/event/NotificationListener.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/event/NotificationListener.java
index 51c764a21..1f7be114b 100644
--- a/src/main/java/page/clab/api/global/common/notificationSetting/application/event/NotificationListener.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/event/NotificationListener.java
@@ -3,8 +3,8 @@
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
+import page.clab.api.global.common.notificationSetting.application.port.in.UpdateNotificationSettingUseCase;
import page.clab.api.global.common.notificationSetting.application.port.out.NotificationSender;
-import page.clab.api.global.common.notificationSetting.application.service.NotificationSettingService;
import page.clab.api.global.common.notificationSetting.domain.AlertType;
import page.clab.api.global.common.notificationSetting.domain.NotificationSetting;
@@ -12,13 +12,13 @@
@RequiredArgsConstructor
public class NotificationListener {
- private final NotificationSettingService settingService;
+ private final UpdateNotificationSettingUseCase updateNotificationSettingUseCase;
private final NotificationSender notificationSender;
@EventListener
public void handleNotificationEvent(NotificationEvent event) {
AlertType alertType = event.getAlertType();
- NotificationSetting setting = settingService.getOrCreateDefaultSetting(alertType);
+ NotificationSetting setting = updateNotificationSettingUseCase.getOrCreateDefaultSetting(alertType);
if (setting.isEnabled()) {
notificationSender.sendNotification(event);
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/application/port/in/RetrieveNotificationSettingUseCase.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/port/in/RetrieveNotificationSettingUseCase.java
new file mode 100644
index 000000000..33bfde964
--- /dev/null
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/port/in/RetrieveNotificationSettingUseCase.java
@@ -0,0 +1,9 @@
+package page.clab.api.global.common.notificationSetting.application.port.in;
+
+import java.util.List;
+import page.clab.api.global.common.notificationSetting.application.dto.response.NotificationSettingResponseDto;
+
+public interface RetrieveNotificationSettingUseCase {
+
+ List retrieveNotificationSettings();
+}
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/application/port/in/UpdateNotificationSettingUseCase.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/port/in/UpdateNotificationSettingUseCase.java
new file mode 100644
index 000000000..3825f9246
--- /dev/null
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/port/in/UpdateNotificationSettingUseCase.java
@@ -0,0 +1,11 @@
+package page.clab.api.global.common.notificationSetting.application.port.in;
+
+import page.clab.api.global.common.notificationSetting.domain.AlertType;
+import page.clab.api.global.common.notificationSetting.domain.NotificationSetting;
+
+public interface UpdateNotificationSettingUseCase {
+
+ void updateNotificationSetting(String alertTypeName, boolean enabled);
+
+ NotificationSetting getOrCreateDefaultSetting(AlertType alertType);
+}
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/application/port/out/RetrieveNotificationSettingPort.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/port/out/RetrieveNotificationSettingPort.java
new file mode 100644
index 000000000..9b81d12b2
--- /dev/null
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/port/out/RetrieveNotificationSettingPort.java
@@ -0,0 +1,13 @@
+package page.clab.api.global.common.notificationSetting.application.port.out;
+
+import java.util.List;
+import java.util.Optional;
+import page.clab.api.global.common.notificationSetting.domain.AlertType;
+import page.clab.api.global.common.notificationSetting.domain.NotificationSetting;
+
+public interface RetrieveNotificationSettingPort {
+
+ List findAll();
+
+ Optional findByAlertType(AlertType alertType);
+}
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/application/port/out/UpdateNotificationSettingPort.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/port/out/UpdateNotificationSettingPort.java
new file mode 100644
index 000000000..144205601
--- /dev/null
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/port/out/UpdateNotificationSettingPort.java
@@ -0,0 +1,8 @@
+package page.clab.api.global.common.notificationSetting.application.port.out;
+
+import page.clab.api.global.common.notificationSetting.domain.NotificationSetting;
+
+public interface UpdateNotificationSettingPort {
+
+ NotificationSetting save(NotificationSetting setting);
+}
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/application/service/RetrieveNotificationSettingService.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/service/RetrieveNotificationSettingService.java
new file mode 100644
index 000000000..3d4d6bc32
--- /dev/null
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/service/RetrieveNotificationSettingService.java
@@ -0,0 +1,36 @@
+package page.clab.api.global.common.notificationSetting.application.service;
+
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import page.clab.api.global.common.notificationSetting.application.dto.mapper.NotificationSettingDtoMapper;
+import page.clab.api.global.common.notificationSetting.application.dto.response.NotificationSettingResponseDto;
+import page.clab.api.global.common.notificationSetting.application.port.in.RetrieveNotificationSettingUseCase;
+import page.clab.api.global.common.notificationSetting.application.port.out.RetrieveNotificationSettingPort;
+
+/**
+ * {@code RetrieveNotificationSettingService}는 알림 설정을 조회하는 서비스입니다.
+ *
+ * 이 서비스는 알림 설정의 전체 목록을 조회할 수 있는 기능을 제공합니다.
+ *
+ * 주요 기능:
+ *
+ * - {@link #retrieveNotificationSettings()} - 모든 알림 설정을 조회합니다.
+ *
+ */
+@Service
+@RequiredArgsConstructor
+public class RetrieveNotificationSettingService implements RetrieveNotificationSettingUseCase {
+
+ private final RetrieveNotificationSettingPort retrieveNotificationSettingPort;
+ private final NotificationSettingDtoMapper mapper;
+
+ @Transactional(readOnly = true)
+ @Override
+ public List retrieveNotificationSettings() {
+ return retrieveNotificationSettingPort.findAll().stream()
+ .map(mapper::toDto)
+ .toList();
+ }
+}
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/application/service/NotificationSettingService.java b/src/main/java/page/clab/api/global/common/notificationSetting/application/service/UpdateNotificationSettingService.java
similarity index 59%
rename from src/main/java/page/clab/api/global/common/notificationSetting/application/service/NotificationSettingService.java
rename to src/main/java/page/clab/api/global/common/notificationSetting/application/service/UpdateNotificationSettingService.java
index 98a69ecda..c57706d75 100644
--- a/src/main/java/page/clab/api/global/common/notificationSetting/application/service/NotificationSettingService.java
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/application/service/UpdateNotificationSettingService.java
@@ -1,60 +1,52 @@
package page.clab.api.global.common.notificationSetting.application.service;
-import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import page.clab.api.global.common.notificationSetting.adapter.out.persistence.NotificationSettingRepository;
-import page.clab.api.global.common.notificationSetting.application.dto.mapper.NotificationSettingDtoMapper;
-import page.clab.api.global.common.notificationSetting.application.dto.response.NotificationSettingResponseDto;
+import page.clab.api.global.common.notificationSetting.application.port.in.UpdateNotificationSettingUseCase;
+import page.clab.api.global.common.notificationSetting.application.port.out.RetrieveNotificationSettingPort;
+import page.clab.api.global.common.notificationSetting.application.port.out.UpdateNotificationSettingPort;
import page.clab.api.global.common.notificationSetting.domain.AlertType;
import page.clab.api.global.common.notificationSetting.domain.AlertTypeResolver;
import page.clab.api.global.common.notificationSetting.domain.NotificationSetting;
/**
- * {@code NotificationSettingService}는 알림 설정을 조회 및 업데이트하는 서비스입니다.
+ * {@code UpdateNotificationSettingService}는 알림 설정을 업데이트하는 서비스입니다.
*
- * 이 서비스는 알림 유형에 따라 활성화 또는 비활성화할 수 있는 설정 기능을 제공하며,
- * 기본 알림 설정을 생성하거나 조회할 수 있습니다.
+ * 이 서비스는 주어진 알림 유형에 따라 활성화 또는 비활성화할 수 있는 설정을 업데이트할 수 있습니다.
+ * 또한, 기본 알림 설정이 존재하지 않으면 생성하여 제공합니다.
*
* 주요 기능:
*
- * - {@link #getNotificationSettings()} - 모든 알림 설정을 조회합니다.
* - {@link #updateNotificationSetting(String, boolean)} - 주어진 알림 유형에 대해 알림 설정을 업데이트합니다.
* - {@link #getOrCreateDefaultSetting(AlertType)} - 주어진 알림 유형에 대한 기본 알림 설정을 조회하거나, 존재하지 않으면 생성합니다.
*
*/
@Service
@RequiredArgsConstructor
-public class NotificationSettingService {
+public class UpdateNotificationSettingService implements UpdateNotificationSettingUseCase {
private final AlertTypeResolver alertTypeResolver;
- private final NotificationSettingRepository settingRepository;
- private final NotificationSettingDtoMapper mapper;
-
- @Transactional(readOnly = true)
- public List getNotificationSettings() {
- return settingRepository.findAll().stream()
- .map(mapper::toDto)
- .toList();
- }
+ private final RetrieveNotificationSettingPort retrieveNotificationSettingPort;
+ private final UpdateNotificationSettingPort updateNotificationSettingPort;
@Transactional
+ @Override
public void updateNotificationSetting(String alertTypeName, boolean enabled) {
AlertType alertType = alertTypeResolver.resolve(alertTypeName);
NotificationSetting setting = getOrCreateDefaultSetting(alertType);
setting.updateEnabled(enabled);
- settingRepository.save(setting);
+ updateNotificationSettingPort.save(setting);
}
@Transactional
public NotificationSetting getOrCreateDefaultSetting(AlertType alertType) {
- return settingRepository.findByAlertType(alertType)
+ return retrieveNotificationSettingPort.findByAlertType(alertType)
.orElseGet(() -> createAndSaveDefaultSetting(alertType));
}
private NotificationSetting createAndSaveDefaultSetting(AlertType alertType) {
NotificationSetting defaultSetting = NotificationSetting.createDefault(alertType);
- return settingRepository.save(defaultSetting);
+ return updateNotificationSettingPort.save(defaultSetting);
}
}
From f4d5a1966180d17bb4257a1ae35e959629eb1871 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=ED=95=9C=EA=B4=80=ED=9D=AC?=
Date: Thu, 14 Nov 2024 00:33:57 +0900
Subject: [PATCH 03/24] =?UTF-8?q?feat(Dependency):=20=EB=94=94=EC=8A=A4?=
=?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9B=B9=ED=9B=85=20=EC=97=B0=EA=B2=B0?=
=?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20OpenFeign=20=EC=9D=98=EC=A1=B4?=
=?UTF-8?q?=EC=84=B1=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
build.gradle | 13 ++++++++++++-
src/main/java/page/clab/api/ApiApplication.java | 2 ++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index ce60c823a..626c601d6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -23,17 +23,28 @@ java {
}
}
+ext {
+ springCloudVersion = '2023.0.3'
+}
+
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
+dependencyManagement {
+ imports {
+ mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
+ }
+}
+
dependencies {
// Spring Project
implementation 'org.springframework.boot:spring-boot-starter-web' // 웹 MVC
implementation 'org.springframework.boot:spring-boot-starter-validation' // 유효성 검사
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' // 템플릿 엔진
implementation 'org.springframework.boot:spring-boot-starter-webflux' // WebFlux
+ implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' // OpenFeign
// Security
implementation 'org.springframework.boot:spring-boot-starter-security' // Spring Security
@@ -113,7 +124,7 @@ tasks.named('test') {
def querydslDir = layout.buildDirectory.dir("generated/querydsl").get().asFile
sourceSets {
- main.java.srcDirs += [ querydslDir ]
+ main.java.srcDirs += [querydslDir]
}
tasks.withType(JavaCompile).configureEach {
diff --git a/src/main/java/page/clab/api/ApiApplication.java b/src/main/java/page/clab/api/ApiApplication.java
index 9e890f824..32356719d 100644
--- a/src/main/java/page/clab/api/ApiApplication.java
+++ b/src/main/java/page/clab/api/ApiApplication.java
@@ -2,7 +2,9 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+@EnableFeignClients
@SpringBootApplication
public class ApiApplication {
From 448a3ee24ccfa643471dc9ef1e11809ba967dd4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=ED=95=9C=EA=B4=80=ED=9D=AC?=
Date: Thu, 14 Nov 2024 00:37:05 +0900
Subject: [PATCH 04/24] =?UTF-8?q?feat(Notification):=20=EB=94=94=EC=8A=A4?=
=?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=ED=98=95?=
=?UTF-8?q?=EC=8B=9D=20=EC=A0=95=EC=9D=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../domain/DiscordMessage.java | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 src/main/java/page/clab/api/global/common/notificationSetting/domain/DiscordMessage.java
diff --git a/src/main/java/page/clab/api/global/common/notificationSetting/domain/DiscordMessage.java b/src/main/java/page/clab/api/global/common/notificationSetting/domain/DiscordMessage.java
new file mode 100644
index 000000000..36059bcf6
--- /dev/null
+++ b/src/main/java/page/clab/api/global/common/notificationSetting/domain/DiscordMessage.java
@@ -0,0 +1,21 @@
+package page.clab.api.global.common.notificationSetting.domain;
+
+import java.util.List;
+import lombok.Builder;
+import lombok.Getter;
+
+@Getter
+@Builder
+public class DiscordMessage {
+
+ private String content;
+ private List