Skip to content

Commit

Permalink
Merge branch 'main' into ISSUE-66
Browse files Browse the repository at this point in the history
  • Loading branch information
min429 authored Aug 7, 2024
2 parents cae3877 + 2c44c15 commit 7eceae3
Show file tree
Hide file tree
Showing 16 changed files with 252 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

Expand All @@ -26,10 +27,9 @@ public class AuthController {
private final OAuthService oAuthService;
private final UserService userService;


@Operation(summary = "로그인")
@GetMapping("/sign-in")
public ResponseEntity<Tokens> signIn(LoginRequest loginRequest) {
@PostMapping("/sign-in")
public ResponseEntity<Tokens> signIn(@RequestBody LoginRequest loginRequest) {
OAuthUserDataResponse oAuthUserData = oAuthService.login(loginRequest);

OAuthUserInfo oAuthUserInfo = OAuthUserInfo.from(oAuthUserData);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,23 @@ public class KakaoUserData {
@Getter
@NoArgsConstructor
static class KakaoAccount {
private String email;
private KakaoProfile profile;
}

@Getter
@NoArgsConstructor
static class KakaoProfile {
private String nickname;
}

public String getEmail() {
return kakaoAccount.getEmail();
@JsonProperty("thumbnail_image_url")
private String profileImage;
}

public String getNickname() {
return kakaoAccount.getProfile().getNickname();
}

public String getProfileImage() {
return kakaoAccount.getProfile().getProfileImage();
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.dnd.accompany.domain.auth.oauth.dto;

import com.dnd.accompany.domain.auth.oauth.service.OAuthProvider;

public record LoginRequest(
OAuthProvider provider,
String provider,
String accessToken
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
public class OAuthUserDataResponse {
private String provider;
private String oauthId;
private String email;
private String profileImageUrl;
private String nickname;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ public class OAuthUserInfo {
private String provider;
private String oauthId;
private String nickname;
private String email;
private String appleRefreshToken;
private String profileImageUrl;

public static OAuthUserInfo from(OAuthUserDataResponse oAuthUserDataResponse) {
return OAuthUserInfo.builder()
.provider(oAuthUserDataResponse.getProvider())
.oauthId(oAuthUserDataResponse.getOauthId())
.nickname(oAuthUserDataResponse.getNickname())
.email(oAuthUserDataResponse.getEmail())
.profileImageUrl(oAuthUserDataResponse.getProfileImageUrl())
.build();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,23 @@ public OAuthUserDataResponse getOAuthUserData(OAuthUserDataRequest request) {

try {
ResponseEntity<KakaoUserData> response = restTemplate.exchange(
url,
HttpMethod.GET,
httpRequest,
KakaoUserData.class
url,
HttpMethod.GET,
httpRequest,
KakaoUserData.class
);
assert response.getBody() != null;

KakaoUserData userData = response.getBody();

return OAuthUserDataResponse.builder()
.provider(getAuthProvider().toString())
.oauthId(userData.getId().toString())
.email(userData.getEmail())
.nickname(userData.getNickname())
.build();
.provider(getAuthProvider().toString())
.profileImageUrl(userData.getProfileImage())
.oauthId(userData.getId().toString())
.nickname(userData.getNickname())
.build();

} catch (RestClientException e) {
} catch (Exception e) {
log.warn("[KakaoService] failed to get OAuth User Data = {}", request.getAccessToken());

if (e instanceof RestClientResponseException) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ public enum OAuthProvider {

private final String name;

public static OAuthProvider get(OAuthProvider oAuthProvider) {
public static OAuthProvider get(String name) {
return Arrays.stream(OAuthProvider.values())
.filter(provider -> provider.equals(oAuthProvider))
.filter(provider -> provider.getName().equals(name))
.findAny()
.orElseThrow(() -> new NotFoundException(ErrorCode.INVALID_PROVIDER));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.dnd.accompany.domain.user.api;

import com.dnd.accompany.domain.auth.dto.jwt.JwtAuthentication;
import com.dnd.accompany.domain.user.dto.CreateUserProfileRequest;
import com.dnd.accompany.domain.user.service.UserProfileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "Onboarding")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/profiles")
public class UserProfileController {

private final UserProfileService userProfileService;

@Operation(summary = "온보딩 정보 저장")
@PostMapping
public void createUserProfile(@AuthenticationPrincipal JwtAuthentication user,
@RequestBody @Valid CreateUserProfileRequest createUserProfileRequest
) {
userProfileService.createUserProfile(user.getId(), createUserProfileRequest);
}

@Operation(summary = "온보딩 여부 조회")
@GetMapping("/exist")
public ResponseEntity<Boolean> existUserProfile(@AuthenticationPrincipal JwtAuthentication user) {
boolean result = userProfileService.existByUserId(user.getId());
return ResponseEntity.ok(result);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.dnd.accompany.domain.user.dto;

import com.dnd.accompany.domain.user.entity.enums.FoodPreference;
import com.dnd.accompany.domain.user.entity.enums.Gender;
import com.dnd.accompany.domain.user.entity.enums.TravelPreference;
import com.dnd.accompany.domain.user.entity.enums.TravelStyle;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;

import java.util.List;

public record CreateUserProfileRequest(
int birthYear,

@NotNull
Gender gender,

@NotEmpty
List<TravelPreference> travelPreferences,

@NotEmpty
List<TravelStyle> travelStyles,

@NotEmpty
List<FoodPreference> foodPreferences
) {
}
20 changes: 10 additions & 10 deletions src/main/java/com/dnd/accompany/domain/user/entity/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ public class User extends TimeBaseEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = false)
private String email;

@Column(nullable = false)
private String nickname;

Expand All @@ -46,14 +43,17 @@ public class User extends TimeBaseEntity {
)
private String oauthId;

private boolean deleted = Boolean.FALSE;
@Column(length = 1000)
private String profileImageUrl;

private boolean deleted = false;

public static User of(String email, String nickname, String provider, String oauthId) {
public static User of(String nickname, String provider, String oauthId, String profileImageUrl) {
return User.builder()
.email(email)
.nickname(nickname)
.provider(provider)
.oauthId(oauthId)
.build();
.nickname(nickname)
.provider(provider)
.oauthId(oauthId)
.profileImageUrl(profileImageUrl)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.dnd.accompany.domain.user.exception;

import com.dnd.accompany.global.common.exception.BusinessException;
import com.dnd.accompany.global.common.response.ErrorCode;

public class UserProfileAlreadyExistsException extends BusinessException {
public UserProfileAlreadyExistsException(ErrorCode errorCode) {
super(errorCode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.dnd.accompany.domain.user.service;

import com.dnd.accompany.domain.user.dto.CreateUserProfileRequest;
import com.dnd.accompany.domain.user.entity.UserProfile;
import com.dnd.accompany.domain.user.exception.UserProfileAlreadyExistsException;
import com.dnd.accompany.domain.user.infrastructure.UserProfileRepository;
import com.dnd.accompany.global.common.response.ErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class UserProfileService {

private final UserProfileRepository userProfileRepository;

@Transactional
public void createUserProfile(Long userId, CreateUserProfileRequest createUserProfileRequest) {
validateDuplicateProfile(userId);

UserProfile userProfile = UserProfile.builder()
.userId(userId)
.birthYear(createUserProfileRequest.birthYear())
.gender(createUserProfileRequest.gender())
.travelPreferences(createUserProfileRequest.travelPreferences())
.travelStyles(createUserProfileRequest.travelStyles())
.foodPreferences(createUserProfileRequest.foodPreferences())
.build();

userProfileRepository.save(userProfile);
}

@Transactional(readOnly = true)
public boolean existByUserId(Long userId) {
return userProfileRepository.existsById(userId);
}

private void validateDuplicateProfile(Long userId) {
if (userProfileRepository.existsById(userId)) {
throw new UserProfileAlreadyExistsException(ErrorCode.PROFILE_ALREADY_EXISTS);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ public AuthUserInfo getOrRegister(OAuthUserInfo oauthUserInfo) {
@Transactional
public User registerUser(OAuthUserInfo oauthUserInfo) {
return userRepository.save(User.of(
oauthUserInfo.getEmail(),
oauthUserInfo.getNickname(),
oauthUserInfo.getProvider(),
oauthUserInfo.getOauthId()
oauthUserInfo.getOauthId(),
oauthUserInfo.getProfileImageUrl()
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public enum ErrorCode {
INVALID_PROVIDER(MatripConstant.BAD_REQUEST, "LOGIN-001", "유효하지 않은 로그인 수단입니다."),
INVALID_OAUTH_TOKEN(MatripConstant.BAD_REQUEST, "LOGIN-002", "유효하지 않은 OAuth 토큰입니다."),

// ---- 프로필 ---- //
PROFILE_ALREADY_EXISTS(MatripConstant.BAD_REQUEST, "PROFILE-001", "이미 프로필 정보가 존재합니다."),

// ---- 네트워크 ---- //
HTTP_CLIENT_REQUEST_FAILED(MatripConstant.INTERNAL_SERVER_ERROR, "NETWORK-001", "서버 요청에 실패하였습니다."),

Expand Down
Loading

0 comments on commit 7eceae3

Please sign in to comment.