Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Refactor/#82 : Auth Domain 리팩토링 #83

Merged
merged 6 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.project.bumawiki.domain.auth.service.implementation;
package com.project.bumawiki.domain.auth.implementation;

import org.springframework.stereotype.Service;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.project.bumawiki.domain.auth.service.implementation;
package com.project.bumawiki.domain.auth.implementation;

import org.springframework.stereotype.Service;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.project.bumawiki.domain.auth.service.implementation;
package com.project.bumawiki.domain.auth.implementation;

import org.springframework.stereotype.Service;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.project.bumawiki.domain.auth.service.implementation;
package com.project.bumawiki.domain.auth.implementation;

import java.util.Date;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.project.bumawiki.domain.auth.infra;

import java.io.IOException;

import org.springframework.stereotype.Component;

import com.project.bumawiki.global.error.exception.BumawikiException;
import com.project.bumawiki.global.error.exception.ErrorCode;

import leehj050211.bsmOauth.BsmOauth;
import leehj050211.bsmOauth.dto.response.BsmResourceResponse;
import leehj050211.bsmOauth.exceptions.BsmAuthCodeNotFoundException;
import leehj050211.bsmOauth.exceptions.BsmAuthInvalidClientException;
import leehj050211.bsmOauth.exceptions.BsmAuthTokenNotFoundException;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class BsmLoginHandler {
qlido marked this conversation as resolved.
Show resolved Hide resolved
private final BsmOauth bsmOauth;

public BsmResourceResponse getResource(String authId) {
try {
String token = bsmOauth.getToken(authId);
return bsmOauth.getResource(token);
} catch (BsmAuthCodeNotFoundException | BsmAuthTokenNotFoundException | BsmAuthInvalidClientException e) {
throw new BumawikiException(ErrorCode.USER_NOT_LOGIN);
qlido marked this conversation as resolved.
Show resolved Hide resolved
} catch (IOException e) {
throw new BumawikiException(ErrorCode.INTERNAL_SERVER_ERROR);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
import com.project.bumawiki.domain.auth.annotation.AdminOnly;
import com.project.bumawiki.domain.auth.annotation.LoginOrNot;
import com.project.bumawiki.domain.auth.annotation.LoginRequired;
import com.project.bumawiki.domain.auth.service.implementation.AuthReader;
import com.project.bumawiki.domain.auth.service.implementation.AuthUpdater;
import com.project.bumawiki.domain.auth.implementation.AuthReader;
import com.project.bumawiki.domain.auth.implementation.AuthUpdater;
import com.project.bumawiki.domain.auth.util.BearerTokenExtractor;
import com.project.bumawiki.domain.auth.util.JwtParser;
import com.project.bumawiki.domain.user.domain.User;
import com.project.bumawiki.domain.user.domain.authority.Authority;
import com.project.bumawiki.domain.user.domain.repository.UserRepository;
import com.project.bumawiki.domain.user.implementation.UserReader;
import com.project.bumawiki.global.error.exception.BumawikiException;
import com.project.bumawiki.global.error.exception.ErrorCode;

Expand All @@ -30,8 +30,7 @@ public class AuthInterceptor implements HandlerInterceptor {
private final JwtParser jwtParser;
private final AuthUpdater authUpdater;
private final AuthReader authReader;
//TODO UserReader로 변경
private final UserRepository userRepository;
private final UserReader userReader;

private static void shouldUserAdmin(User currentUser) {
if (currentUser.getAuthority() != Authority.ADMIN) {
Expand All @@ -55,7 +54,7 @@ public boolean preHandle(
String jwt = BearerTokenExtractor.extract(bearer);
Long userId = jwtParser.getIdFromJwt(jwt);

User user = userRepository.getById(userId);
User user = userReader.getById(userId);

authUpdater.updateCurrentUser(user);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.project.bumawiki.domain.auth.presentation.dto.LoginReqestDto;
import com.project.bumawiki.domain.auth.presentation.dto.RefreshTokenRequestDto;
import com.project.bumawiki.domain.auth.presentation.dto.TokenResponseDto;
import com.project.bumawiki.domain.auth.service.AccessTokenRefreshService;
import com.project.bumawiki.domain.auth.service.UserSignUpOrUpdateService;
import com.project.bumawiki.domain.auth.service.CommandAuthService;

import lombok.RequiredArgsConstructor;

Expand All @@ -20,16 +21,15 @@
@RestController
@RequestMapping("/api/auth")
public class AuthController {
private final UserSignUpOrUpdateService userSignUpOrUpdateService;
private final AccessTokenRefreshService accessTokenRefreshService;
private final CommandAuthService commandAuthService;

@PostMapping("/oauth/bsm")
public TokenResponseDto userSignup(@RequestHeader("authCode") String authCode) throws IOException {
return TokenResponseDto.from(userSignUpOrUpdateService.execute(authCode));
public TokenResponseDto userSignup(@RequestBody LoginReqestDto loginReqestDto) throws IOException {
return TokenResponseDto.from(commandAuthService.login(loginReqestDto.accessToken()));
}

@PutMapping("/refresh/access")
public TokenResponseDto refreshAccessToken(@RequestHeader("refreshToken") String refreshToken) {
return TokenResponseDto.from(accessTokenRefreshService.execute(refreshToken));
public TokenResponseDto refreshAccessToken(@RequestBody RefreshTokenRequestDto refreshTokenRequestDto) {
return TokenResponseDto.from(commandAuthService.refresh(refreshTokenRequestDto.refreshToken()));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.project.bumawiki.domain.auth.presentation.dto;

public record AccessTokenRequestDto(
public record LoginReqestDto(
String accessToken
) {
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.project.bumawiki.domain.auth.service;

import org.springframework.stereotype.Service;

import com.project.bumawiki.domain.auth.domain.Token;
import com.project.bumawiki.domain.auth.implementation.AuthReader;
import com.project.bumawiki.domain.auth.implementation.AuthValidator;
import com.project.bumawiki.domain.auth.implementation.TokenProvider;
import com.project.bumawiki.domain.auth.infra.BsmLoginHandler;
import com.project.bumawiki.domain.auth.util.BearerTokenExtractor;
import com.project.bumawiki.domain.user.domain.User;
import com.project.bumawiki.domain.user.implementation.UserCreator;
import com.project.bumawiki.domain.user.implementation.UserReader;
import com.project.bumawiki.domain.user.implementation.UserUpdater;

import leehj050211.bsmOauth.dto.response.BsmResourceResponse;
import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class CommandAuthService {
private final AuthValidator authValidator;
private final AuthReader authReader;
private final BsmLoginHandler bsmLoginHandler;
private final TokenProvider tokenProvider;
private final UserReader userReader;
private final UserCreator userCreator;
private final UserUpdater userUpdater;

public Token login(String authId) {
BsmResourceResponse resource = bsmLoginHandler.getResource(authId);
User user = userReader.getByEmail(resource.getEmail());

if (user == null) {
userCreator.create(resource);
} else {
userUpdater.update(user, resource);
}

return tokenProvider.createNewTokens(user);
}

public Token refresh(String bearer) {
String refreshToken = BearerTokenExtractor.extract(bearer);
authValidator.shouldRefreshTokenValid(refreshToken);

Long userId = authReader.getIdFromJwt(refreshToken);
String accessToken = tokenProvider.createAccessToken(userReader.getById(userId));

return new Token(accessToken, refreshToken);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class BearerTokenExtractor {

private static final String BEARER_TYPE = "Bearer ";
private static final String PREFIX = "Bearer";
private static final String BEARER_JWT_REGEX = "^Bearer [A-Za-z0-9-_=]+\\.[A-Za-z0-9-_=]+\\.?[A-Za-z0-9-_.+/=]*$";

public static String extract(String bearer) {
validate(bearer);
return bearer.replace(BEARER_TYPE, "").trim();
return bearer.replace(PREFIX, "").trim();
}

private static void validate(String authorization) {
if (authorization == null) {
private static void validate(String bearer) {
if (bearer == null) {
throw new BumawikiException(ErrorCode.TOKEN_MISSING);
}
if (!authorization.matches(BEARER_JWT_REGEX)) {
if (!bearer.matches(BEARER_JWT_REGEX)) {
throw new BumawikiException(ErrorCode.INVALID_JWT);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,11 @@ public List<ThumbsUpResponseDto> getList() {
.toList();
}

public User update(BsmResourceResponse resource) {
public void update(BsmResourceResponse resource) {
this.email = resource.getEmail();
this.name = resource.getStudent().getName();
this.enroll = resource.getStudent().getEnrolledAt();
this.nickName = resource.getNickname();
return this;
}

public void changeUserAuthority(Authority authority) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@
import org.springframework.data.jpa.repository.JpaRepository;

import com.project.bumawiki.domain.user.domain.User;
import com.project.bumawiki.domain.user.exception.UserNotFoundException;

public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);

default User getById(Long id) {
return findById(id).orElseThrow(() -> UserNotFoundException.EXCEPTION);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.project.bumawiki.domain.user.implementation;

import com.project.bumawiki.domain.user.domain.User;
import com.project.bumawiki.domain.user.domain.authority.Authority;
import com.project.bumawiki.domain.user.domain.repository.UserRepository;
import com.project.bumawiki.global.annotation.Implementation;

import leehj050211.bsmOauth.dto.response.BsmResourceResponse;
import lombok.RequiredArgsConstructor;

@Implementation
@RequiredArgsConstructor
public class UserCreator {
private final UserRepository userRepository;

public void create(BsmResourceResponse resource) {
userRepository.save(
User.builder()
.email(resource.getEmail())
.nickName(resource.getNickname())
.authority(Authority.USER)
.enroll(resource.getStudent().getEnrolledAt())
.name(resource.getStudent().getName())
.build()
);
}
Copy link
Contributor

@hw9402 hw9402 Apr 15, 2024

Choose a reason for hiding this comment

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

dto를 넘겨서 저장하기 보단 비즈니스 레이어에서 엔티티로 변환 후 User를 매개변수로 받아서 저장하는 건 어떨까요? 이러한 방법이 재사용성을 더 높일 수 있을 것 같아요

Copy link
Member Author

Choose a reason for hiding this comment

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

어떤 방식인지 예시를 들어주실 수 있나요?

Copy link
Member

Choose a reason for hiding this comment

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

저는 handler에서 가져올 때 바로 User로 가져오면 좋겠다는 생각이 들어요. 그렇게 하면, 다른 implementation레이어나 service레이어는 BSM의 상세 구현에 대한 의존 없이 작동할 수 있기 때문에 유지보수성이 좋아질 거라고 생각해요.

Copy link
Contributor

Choose a reason for hiding this comment

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

public void create(User user) {
    userRepository.save(user);
}

제가 말한 방식은 이러한 방식이었습니다

비즈니스 레이어에서 dto.toEntity()와 같은 방법으로 dto를 entity로 변환 후 create(dto.toEntity()) 이런식으로 메서드를 호출한다면 재사용성이 늘어날 것 같습니다!

Copy link
Member Author

Choose a reason for hiding this comment

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

toEntity 쓰고싶지만 라이브러리라 사용 할 수 없어요ㅜㅜ

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.project.bumawiki.domain.user.implementation;

import com.project.bumawiki.domain.user.domain.User;
import com.project.bumawiki.domain.user.domain.repository.UserRepository;
import com.project.bumawiki.global.annotation.Implementation;
import com.project.bumawiki.global.error.exception.BumawikiException;
import com.project.bumawiki.global.error.exception.ErrorCode;

import lombok.RequiredArgsConstructor;

@Implementation
@RequiredArgsConstructor
public class UserReader {
private final UserRepository userRepository;

public User getById(Long id) {
return userRepository.findById(id).orElseThrow(() -> new BumawikiException(ErrorCode.USER_NOT_FOUND));
}

public User getByEmail(String email) {
return userRepository.findByEmail(email).orElseThrow(() -> new BumawikiException(ErrorCode.USER_NOT_FOUND));
}
}
Loading
Loading