diff --git a/src/main/java/com/yello/server/domain/admin/service/AdminService.java b/src/main/java/com/yello/server/domain/admin/service/AdminService.java index 53ed8c9a..9fa01c79 100644 --- a/src/main/java/com/yello/server/domain/admin/service/AdminService.java +++ b/src/main/java/com/yello/server/domain/admin/service/AdminService.java @@ -111,7 +111,7 @@ public AdminUserDetailResponse findUserDetail(Long adminId, Long userId) { userAdminRepository.getByUser(admin); // logic - final User user = userRepository.getById(userId); + final User user = userRepository.getByIdNotFiltered(userId); return AdminUserDetailResponse.of(user); } diff --git a/src/main/java/com/yello/server/domain/authorization/controller/AuthController.java b/src/main/java/com/yello/server/domain/authorization/controller/AuthController.java index 492aa2f9..be0382bb 100644 --- a/src/main/java/com/yello/server/domain/authorization/controller/AuthController.java +++ b/src/main/java/com/yello/server/domain/authorization/controller/AuthController.java @@ -21,6 +21,7 @@ import com.yello.server.domain.authorization.service.AuthService; import com.yello.server.global.common.annotation.ServiceToken; import com.yello.server.global.common.dto.BaseResponse; +import com.yello.server.infrastructure.slack.annotation.SlackSignUpNotification; import javax.validation.Valid; import javax.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; @@ -52,6 +53,7 @@ public BaseResponse getYelloIdValidation(@RequestParam("yelloId") Strin } @PostMapping("/signup") + @SlackSignUpNotification public BaseResponse postSignUp(@Valid @RequestBody SignUpRequest signUpRequest) { val data = authService.signUp(signUpRequest); return BaseResponse.success(SIGN_UP_SUCCESS, data); diff --git a/src/main/java/com/yello/server/domain/user/repository/UserJpaRepository.java b/src/main/java/com/yello/server/domain/user/repository/UserJpaRepository.java index a2f07c6d..978af680 100644 --- a/src/main/java/com/yello/server/domain/user/repository/UserJpaRepository.java +++ b/src/main/java/com/yello/server/domain/user/repository/UserJpaRepository.java @@ -16,6 +16,10 @@ public interface UserJpaRepository extends JpaRepository { "and u.deletedAt is null") Optional findById(@Param("id") Long id); + @Query("select u from User u " + + "where u.id = :id") + Optional findByIdNotFiltered(@Param("id") Long id); + @Query("select u from User u " + "where u.uuid = :uuid") Optional findByUuid(@Param("uuid") String uuid); diff --git a/src/main/java/com/yello/server/domain/user/repository/UserRepository.java b/src/main/java/com/yello/server/domain/user/repository/UserRepository.java index c44767ca..fbd37458 100644 --- a/src/main/java/com/yello/server/domain/user/repository/UserRepository.java +++ b/src/main/java/com/yello/server/domain/user/repository/UserRepository.java @@ -14,6 +14,8 @@ public interface UserRepository { User getById(Long id); + User getByIdNotFiltered(Long id); + Optional findByUuid(String uuid); Optional findByUuidNotFiltered(String uuid); @@ -64,6 +66,6 @@ List findAllByOtherGroupContainingYelloId(String groupName, String keyword Page findAllByYelloIdContaining(Pageable pageable, String yelloId); Page findAllByNameContaining(Pageable pageable, String name); - + void delete(User user); } diff --git a/src/main/java/com/yello/server/domain/user/repository/UserRepositoryImpl.java b/src/main/java/com/yello/server/domain/user/repository/UserRepositoryImpl.java index b33a3b21..6543183d 100644 --- a/src/main/java/com/yello/server/domain/user/repository/UserRepositoryImpl.java +++ b/src/main/java/com/yello/server/domain/user/repository/UserRepositoryImpl.java @@ -38,6 +38,12 @@ public User getById(Long id) { .orElseThrow(() -> new UserNotFoundException(USERID_NOT_FOUND_USER_EXCEPTION)); } + @Override + public User getByIdNotFiltered(Long id) { + return userJpaRepository.findByIdNotFiltered(id) + .orElseThrow(() -> new UserNotFoundException(USERID_NOT_FOUND_USER_EXCEPTION)); + } + @Override public Optional findByUuid(String uuid) { return userJpaRepository.findByUuid(uuid); diff --git a/src/main/java/com/yello/server/infrastructure/slack/annotation/SlackSignUpNotification.java b/src/main/java/com/yello/server/infrastructure/slack/annotation/SlackSignUpNotification.java new file mode 100644 index 00000000..65623dfb --- /dev/null +++ b/src/main/java/com/yello/server/infrastructure/slack/annotation/SlackSignUpNotification.java @@ -0,0 +1,12 @@ +package com.yello.server.infrastructure.slack.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface SlackSignUpNotification { + +} diff --git a/src/main/java/com/yello/server/infrastructure/slack/aspect/SlackSignUpNotificationAspect.java b/src/main/java/com/yello/server/infrastructure/slack/aspect/SlackSignUpNotificationAspect.java new file mode 100644 index 00000000..03b50b12 --- /dev/null +++ b/src/main/java/com/yello/server/infrastructure/slack/aspect/SlackSignUpNotificationAspect.java @@ -0,0 +1,47 @@ +package com.yello.server.infrastructure.slack.aspect; + +import com.yello.server.infrastructure.slack.factory.SlackWebhookMessageFactory; +import javax.servlet.http.HttpServletRequest; +import net.gpedro.integrations.slack.SlackApi; +import net.gpedro.integrations.slack.SlackMessage; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.task.TaskExecutor; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +@Aspect +@Component +public class SlackSignUpNotificationAspect { + + private final SlackApi slackSignUpApi; + private final SlackWebhookMessageFactory slackWebhookMessageFactory; + private final TaskExecutor taskExecutor; + + public SlackSignUpNotificationAspect( + @Qualifier("slackSignUpApi") SlackApi slackSignUpApi, + SlackWebhookMessageFactory slackWebhookMessageFactory, + TaskExecutor taskExecutor) { + this.slackSignUpApi = slackSignUpApi; + this.slackWebhookMessageFactory = slackWebhookMessageFactory; + this.taskExecutor = taskExecutor; + } + + @Around("@annotation(com.yello.server.infrastructure.slack.annotation.SlackSignUpNotification)") + Object signUpNotification(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()) + .getRequest(); + + SlackMessage slackMessage = slackWebhookMessageFactory.generateSlackSignUpMessage( + request + ); + + Runnable runnable = () -> slackSignUpApi.call(slackMessage); + taskExecutor.execute(runnable); + + return proceedingJoinPoint.proceed(); + } +} diff --git a/src/main/java/com/yello/server/infrastructure/slack/configuration/SlackConfiguration.java b/src/main/java/com/yello/server/infrastructure/slack/configuration/SlackConfiguration.java index 495d7af2..f7f1ae52 100644 --- a/src/main/java/com/yello/server/infrastructure/slack/configuration/SlackConfiguration.java +++ b/src/main/java/com/yello/server/infrastructure/slack/configuration/SlackConfiguration.java @@ -14,6 +14,9 @@ public class SlackConfiguration { @Value("${slack.token.bank}") String slackTokenForPurchase; + @Value("${slack.token.sign-up}") + String slackTokenForSignUp; + @Bean SlackApi slackErrorApi() { return new SlackApi("https://hooks.slack.com/services/" + slackTokenForError); @@ -23,4 +26,9 @@ SlackApi slackErrorApi() { SlackApi slackPurchaseApi() { return new SlackApi("https://hooks.slack.com/services/" + slackTokenForPurchase); } + + @Bean + SlackApi slackSignUpApi() { + return new SlackApi("https://hooks.slack.com/services/" + slackTokenForSignUp); + } } diff --git a/src/main/java/com/yello/server/infrastructure/slack/factory/SlackWebhookMessageFactory.java b/src/main/java/com/yello/server/infrastructure/slack/factory/SlackWebhookMessageFactory.java index b0000cca..95854925 100644 --- a/src/main/java/com/yello/server/infrastructure/slack/factory/SlackWebhookMessageFactory.java +++ b/src/main/java/com/yello/server/infrastructure/slack/factory/SlackWebhookMessageFactory.java @@ -30,6 +30,9 @@ public class SlackWebhookMessageFactory { private static final String PURCHASE_TITLE = "돈이 입금되었습니다."; private static final String PURCHASE_USERNAME = "옐로 뱅크"; + private static final String SIGNUP_TITLE = "신규 유저가 가입하였습니다. "; + private static final String SIGNUP_USERNAME = "옐로 온보딩"; + private final UserRepository userRepository; private final TokenProvider tokenProvider; @@ -84,6 +87,15 @@ public SlackMessage generateSlackPurchaseMessage( .setUsername(PURCHASE_USERNAME); } + public SlackMessage generateSlackSignUpMessage( + HttpServletRequest request + ) throws IOException { + return new SlackMessage() + .setAttachments(generateSlackSignUpAttachment(request)) + .setText(SIGNUP_TITLE) + .setUsername(SIGNUP_USERNAME); + } + private List generateSlackErrorAttachment( HttpServletRequest request, Exception exception @@ -114,6 +126,19 @@ private List generateSlackPurchaseAttachment( return Collections.singletonList(slackAttachment); } + private List generateSlackSignUpAttachment( + HttpServletRequest request + ) throws IOException { + final SlackAttachment slackAttachment = new SlackAttachment() + .setFallback("good") + .setColor("good") + .setTitle(SIGNUP_TITLE) + .setTitleLink(request.getContextPath()) + .setText(SIGNUP_TITLE) + .setFields(generateSlackSimpleFieldList(request)); + return Collections.singletonList(slackAttachment); + } + private List generateSlackFieldList( HttpServletRequest request ) throws IOException { @@ -143,4 +168,13 @@ private List generateSlackFieldList( new SlackField().setTitle("인증/인가 정보 - 유저").setValue(userInfo) ); } + + private List generateSlackSimpleFieldList( + HttpServletRequest request + ) throws IOException { + return Arrays.asList( + new SlackField().setTitle("Request Body") + .setValue(getRequestBody(request)) + ); + } } diff --git a/src/test/java/com/yello/server/domain/user/FakeUserRepository.java b/src/test/java/com/yello/server/domain/user/FakeUserRepository.java index 860dc43f..b4893f49 100644 --- a/src/test/java/com/yello/server/domain/user/FakeUserRepository.java +++ b/src/test/java/com/yello/server/domain/user/FakeUserRepository.java @@ -57,6 +57,15 @@ public Optional findById(Long id) { @Override public User getById(Long id) { + return data.stream() + .filter(user -> user.getDeletedAt() == null) + .filter(user -> user.getId().equals(id)) + .findFirst() + .orElseThrow(() -> new UserNotFoundException(USERID_NOT_FOUND_USER_EXCEPTION)); + } + + @Override + public User getByIdNotFiltered(Long id) { return data.stream() .filter(user -> user.getId().equals(id)) .findFirst()