Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…m-2-BE into BAR-226-BE-아카이브-테이블-구조-변경
  • Loading branch information
shinyubin989 committed Jan 26, 2024
2 parents c316c22 + 9a56f0e commit 85eb19a
Show file tree
Hide file tree
Showing 38 changed files with 777 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

public interface OAuthClient {

String getSignInUrl();
String getSignInUrl(String host);

OAuthServiceType getOAuthService();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.baro.auth.application.oauth.dto.OAuthMemberInfo;
import com.baro.auth.application.oauth.dto.OAuthTokenInfo;
import com.baro.auth.domain.oauth.OAuthServiceType;

import java.util.Map;
import java.util.Set;
import org.springframework.stereotype.Component;
Expand All @@ -23,9 +22,9 @@ public OAuthInfoProvider(Set<OAuthClient> clients) {
.collect(toMap(OAuthClient::getOAuthService, identity()));
}

public String getSignInUrl(String oAuthService) {
public String getSignInUrl(String oAuthService, String host) {
OAuthClient client = getClient(oAuthService);
return client.getSignInUrl();
return client.getSignInUrl(host);
}

public OAuthMemberInfo getMemberInfo(String oAuthService, String code) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package com.baro.auth.infra.oauth.google;

import com.baro.auth.application.oauth.OAuthClient;
import com.baro.auth.application.oauth.dto.OAuthMemberInfo;
import com.baro.auth.application.oauth.dto.OAuthTokenInfo;
import com.baro.auth.domain.oauth.OAuthServiceType;
import com.baro.auth.infra.oauth.google.config.GoogleOAuthProperty;
import com.baro.auth.infra.oauth.google.dto.GoogleMemberResponse;
import com.baro.auth.infra.oauth.google.dto.GoogleTokenResponse;
import com.baro.auth.application.oauth.OAuthClient;
import java.util.LinkedHashMap;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.LinkedHashMap;
import java.util.Map;

@RequiredArgsConstructor
@Component
public class GoogleOAuthClient implements OAuthClient {
Expand All @@ -22,12 +21,12 @@ public class GoogleOAuthClient implements OAuthClient {
private final GoogleRequestApi googleRequestApi;

@Override
public String getSignInUrl() {
public String getSignInUrl(String host) {
return UriComponentsBuilder
.fromUriString(googleOAuthProperty.signInAuthorizeUrl())
.queryParam("client_id", googleOAuthProperty.clientId())
.queryParam("redirect_uri", googleOAuthProperty.redirectUri())
.queryParam("response_type", googleOAuthProperty.responseType())
.queryParam("redirect_uri", host + googleOAuthProperty.redirectUri())
.queryParam("scope", String.join(",", googleOAuthProperty.scope()))
.toUriString();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package com.baro.auth.infra.oauth.kakao;

import com.baro.auth.application.oauth.OAuthClient;
import com.baro.auth.application.oauth.dto.OAuthMemberInfo;
import com.baro.auth.application.oauth.dto.OAuthTokenInfo;
import com.baro.auth.domain.oauth.OAuthServiceType;
import com.baro.auth.infra.oauth.kakao.config.KakaoOAuthProperty;
import com.baro.auth.infra.oauth.kakao.dto.KakaoMemberResponse;
import com.baro.auth.infra.oauth.kakao.dto.KakaoTokenResponse;
import com.baro.auth.application.oauth.OAuthClient;

import java.util.LinkedHashMap;
import java.util.Map;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;
Expand All @@ -23,12 +21,12 @@ public class KakaoOAuthClient implements OAuthClient {
private final KakaoRequestApi kakaoRequestApi;

@Override
public String getSignInUrl() {
public String getSignInUrl(String host) {
return UriComponentsBuilder
.fromUriString(kakaoOAuthProperty.signInAuthorizeUrl())
.queryParam("response_type", kakaoOAuthProperty.responseType())
.queryParam("client_id", kakaoOAuthProperty.clientId())
.queryParam("redirect_uri", kakaoOAuthProperty.redirectUrl())
.queryParam("redirect_uri", host + kakaoOAuthProperty.redirectUri())
.queryParam("scope", String.join(",", kakaoOAuthProperty.scope()))
.toUriString();
}
Expand All @@ -38,7 +36,7 @@ public OAuthTokenInfo requestAccessToken(String authCode) {
Map<String, String> params = new LinkedHashMap<>();
params.put("grant_type", "authorization_code");
params.put("client_id", kakaoOAuthProperty.clientId());
params.put("redirect_uri", kakaoOAuthProperty.redirectUrl());
params.put("redirect_uri", kakaoOAuthProperty.redirectUri());
params.put("code", authCode);
params.put("client_secret", kakaoOAuthProperty.clientSecret());
KakaoTokenResponse kakaoTokenResponse = kakaoRequestApi.requestToken(params);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
@ConfigurationProperties(prefix = "oauth.kakao")
public record KakaoOAuthProperty(
String clientId,
String redirectUrl,
String redirectUri,
String responseType,
String signInAuthorizeUrl,
String[] scope,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ public class NaverOAuthClient implements OAuthClient {
private final NaverRequestApi naverRequestApi;

@Override
public String getSignInUrl() {
public String getSignInUrl(String host) {
return UriComponentsBuilder
.fromUriString(naverOAuthProperty.signInAuthorizeUrl())
.queryParam("response_type", naverOAuthProperty.responseType())
.queryParam("client_id", naverOAuthProperty.clientId())
.queryParam("redirect_uri", naverOAuthProperty.redirectUri())
.queryParam("redirect_uri", host + naverOAuthProperty.redirectUri())
.queryParam("state", naverOAuthProperty.state())
.toUriString();
}
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/baro/auth/presentation/AuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.baro.auth.domain.AuthMember;
import com.baro.auth.domain.Token;
import com.baro.auth.presentation.dto.OAuthServiceUrlResponse;
import com.baro.common.presentation.RequestHost;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -24,8 +25,8 @@ public class AuthController {
private final OAuthInfoProvider oAuthInfoProvider;

@GetMapping("/oauth/{oauthType}")
ResponseEntity<OAuthServiceUrlResponse> signInRequestUrl(@PathVariable String oauthType) {
String signInUrl = oAuthInfoProvider.getSignInUrl(oauthType);
ResponseEntity<OAuthServiceUrlResponse> signInRequestUrl(@PathVariable String oauthType, @RequestHost String host) {
String signInUrl = oAuthInfoProvider.getSignInUrl(oauthType, host);
return ResponseEntity.ok(new OAuthServiceUrlResponse(signInUrl));
}

Expand Down
6 changes: 5 additions & 1 deletion src/main/java/com/baro/common/config/WebConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.baro.auth.presentation.AuthInterceptor;
import com.baro.auth.presentation.AuthenticationArgumentResolver;
import com.baro.common.presentation.RequestHostArgumentResolver;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
Expand All @@ -15,10 +16,12 @@ public class WebConfig implements WebMvcConfigurer {

private final AuthenticationArgumentResolver authenticationArgumentResolver;
private final AuthInterceptor authInterceptor;
private final RequestHostArgumentResolver requestHostArgumentResolver;

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(authenticationArgumentResolver);
resolvers.add(requestHostArgumentResolver);
}

@Override
Expand All @@ -27,6 +30,7 @@ public void addInterceptors(InterceptorRegistry registry) {
.addPathPatterns("/**")
.excludePathPatterns("/docs/**")
.excludePathPatterns("/auth/**")
.excludePathPatterns("/favicon.ico");
.excludePathPatterns("/favicon.ico")
.excludePathPatterns("/test/**");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public enum CommonRequestExceptionType implements RequestExceptionType {

MISSING_PARAMETER_EXCEPTION("CM01", "Request parameter is empty", HttpStatus.BAD_REQUEST),
INVALID_TYPE_REQUEST_EXCEPTION("CM02", "Request type is invalid", HttpStatus.BAD_REQUEST),
REQUIRED_HEADER_EXCEPTION("CM03", "Request header is empty", HttpStatus.BAD_REQUEST),
;

private final String errorCode;
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/baro/common/presentation/RequestHost.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.baro.common.presentation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(value = RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface RequestHost {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.baro.common.presentation;

import static com.baro.common.exception.CommonRequestExceptionType.REQUIRED_HEADER_EXCEPTION;

import com.baro.common.exception.RequestException;
import com.baro.common.exception.RequestExceptionType;
import java.util.Objects;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

@Component
public class RequestHostArgumentResolver implements HandlerMethodArgumentResolver {

private static final String HOST_HEADER_KEY = "Origin";

@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(RequestHost.class);
}

@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
String host = webRequest.getHeader(HOST_HEADER_KEY);
validateHeaderIsNonNull(host);
return host;
}

private void validateHeaderIsNonNull(String host) {
if (Objects.nonNull(host)) {
return;
}

throw new RequestException() {
@Override
public RequestExceptionType exceptionType() {
return REQUIRED_HEADER_EXCEPTION;
}
};
}
}
22 changes: 22 additions & 0 deletions src/main/java/com/baro/member/application/MemberService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.baro.member.application;

import com.baro.member.application.dto.GetMemberProfileResult;
import com.baro.member.domain.Member;
import com.baro.member.domain.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Transactional
@Service
public class MemberService {

private final MemberRepository memberRepository;

@Transactional(readOnly = true)
public GetMemberProfileResult getMyProfile(Long id) {
Member member = memberRepository.getById(id);
return GetMemberProfileResult.from(member);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.baro.member.application.dto;

import com.baro.member.domain.Member;

public record GetMemberProfileResult(
Long id,
String name,
String nickname,
String profileImageUrl,
String email,
String oAuthServiceType
) {

public static GetMemberProfileResult from(Member member) {
return new GetMemberProfileResult(
member.getId(),
member.getName(),
member.getNickname(),
member.getProfileImageUrl(),
member.getEmail(),
member.getOAuthServiceType()
);
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/baro/member/presentation/MemberController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.baro.member.presentation;

import com.baro.auth.domain.AuthMember;
import com.baro.member.application.MemberService;
import com.baro.member.application.dto.GetMemberProfileResult;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RequestMapping("/members")
@RestController
public class MemberController {

private final MemberService memberService;

@GetMapping("/profile/me")
public ResponseEntity<GetMemberProfileResult> getMyProfile(
AuthMember authMember
) {
GetMemberProfileResult result = memberService.getMyProfile(authMember.id());
return ResponseEntity.ok().body(result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.baro.member.domain.Member;
import com.baro.member.domain.MemberRepository;
import com.baro.memofolder.application.dto.GetMemoFolderResult;
import com.baro.memofolder.application.dto.RenameMemoFolderCommand;
import com.baro.memofolder.application.dto.SaveMemoFolderCommand;
import com.baro.memofolder.application.dto.SaveMemoFolderResult;
import com.baro.memofolder.domain.MemoFolder;
Expand Down Expand Up @@ -45,4 +46,12 @@ public List<GetMemoFolderResult> getMemoFolder(Long memberId) {
.map(GetMemoFolderResult::from)
.toList();
}

public void renameMemoFolder(RenameMemoFolderCommand command) {
MemoFolder memoFolder = memoFolderRepository.getById(command.memoFolderId());
memoFolder.matchOwner(command.memberId());
validateDuplicatedFolderName(memoFolder.getMember(), command.folderName());

memoFolder.rename(command.folderName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.baro.memofolder.application.dto;

public record RenameMemoFolderCommand(
Long memberId,
Long memoFolderId,
String folderName
) {
}
4 changes: 4 additions & 0 deletions src/main/java/com/baro/memofolder/domain/MemoFolder.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,8 @@ public void matchOwner(Long memberId) {
throw new MemoFolderException(MemoFolderExceptionType.NOT_MATCH_OWNER);
}
}

public void rename(String name) {
this.name = MemoFolderName.from(name);
}
}
3 changes: 3 additions & 0 deletions src/main/java/com/baro/memofolder/domain/MemoFolderName.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ private MemoFolderName(String name) {
}

private void validate(String name) {
if (name.isEmpty()) {
throw new MemoFolderException(MemoFolderExceptionType.EMPTY_NAME);
}
if (EmojiUtils.calculateLengthWithEmojis(name) > MAX_FOLDER_SIZE) {
throw new MemoFolderException(MemoFolderExceptionType.OVER_MAX_SIZE_NAME);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public enum MemoFolderExceptionType implements RequestExceptionType {
OVER_MAX_SIZE_NAME("MF02", "폴더 이름은 최대 20자까지 가능합니다.", HttpStatus.BAD_REQUEST),
NOT_EXIST_MEMO_FOLDER("MF03", "존재하지 않는 폴더입니다.", HttpStatus.NOT_FOUND),
NOT_MATCH_OWNER("MF04", "폴더의 소유자가 아닙니다.", HttpStatus.FORBIDDEN),
;
EMPTY_NAME("MF05", "폴더 이름이 공백입니다.", HttpStatus.BAD_REQUEST);

private final String errorCode;
private final String errorMessage;
Expand Down
Loading

0 comments on commit 85eb19a

Please sign in to comment.