Skip to content

Commit

Permalink
Update: kakao oauth 연동 및 oauth type별 팩토리 패턴 적용, apple oauth 기초공사
Browse files Browse the repository at this point in the history
  • Loading branch information
BYEONGRYEOL committed Apr 28, 2024
1 parent 3ec2245 commit fb65236
Show file tree
Hide file tree
Showing 17 changed files with 248 additions and 83 deletions.
40 changes: 40 additions & 0 deletions src/main/java/com/gt/genti/config/auth/AppleOauthAttributes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.gt.genti.config.auth;

import java.util.Map;

import com.gt.genti.domain.enums.OauthType;

public class AppleOauthAttributes implements OauthAttributes {

private Map<String, Object> attributes;
// private String nameAttributeKey;
private String name;
private String email;
private final OauthType oauthType = OauthType.APPLE;

public AppleOauthAttributes(Map<String, Object> attributes) {
this.attributes = attributes;
this.name = (String)attributes.get("name");
this.email = (String)attributes.get("email");
}

@Override
public String getEmail() {
return this.email;
}

@Override
public String getUsername() {
return this.name;
}

@Override
public OauthType getOauthType() {
return this.oauthType;
}

// @Override
// public OauthAttribute of(Map<String, Object> attribute) {
// return null;
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic
Optional<User> optionalUser = userRepository.findByEmail(email);
User user;
if (optionalUser.isEmpty()) {
String userNameAttributeName = userRequest.getClientRegistration()
.getProviderDetails()
.getUserInfoEndpoint()
.getUserNameAttributeName();

OAuthAttributes attributes = OAuthAttributes.of(registrationId, userNameAttributeName,
oAuth2User.getAttributes());
user = User.createNewSocialUser(attributes);
// String userNameAttributeName = userRequest.getClientRegistration()
// .getProviderDetails()
// .getUserInfoEndpoint()
// .getUserNameAttributeName();

OauthAttributes oauthAttributes = OauthAttributeBuilder.of(registrationId, oAuth2User.getAttributes());
user = User.createNewSocialUser(oauthAttributes);

user = userRepository.save(user);
roles = UserRole.addRole(UserRole.getAllRoles(user.getUserRole()), UserRole.OAUTH_FIRST_JOIN);
} else {
Expand Down
35 changes: 35 additions & 0 deletions src/main/java/com/gt/genti/config/auth/GoogleOauthAttributes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.gt.genti.config.auth;

import java.util.Map;

import com.gt.genti.domain.enums.OauthType;

public class GoogleOauthAttributes implements OauthAttributes {

private Map<String, Object> attributes;
// private String nameAttributeKey;
private String name;
private String email;
private final OauthType oauthType = OauthType.GOOGLE;

public GoogleOauthAttributes(Map<String, Object> attributes) {
this.attributes = attributes;
this.name = (String)attributes.get("name");
this.email = (String)attributes.get("email");
}

@Override
public String getEmail() {
return null;
}

@Override
public String getUsername() {
return null;
}

@Override
public OauthType getOauthType() {
return this.oauthType;
}
}
41 changes: 41 additions & 0 deletions src/main/java/com/gt/genti/config/auth/KakaoOauthAttributes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.gt.genti.config.auth;

import java.util.Map;
import java.util.UUID;

import com.gt.genti.domain.enums.OauthType;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class KakaoOauthAttributes implements OauthAttributes {

private Map<String, Object> attributes;
// private String nameAttributeKey;
private String nickname;
private String email;
private final OauthType oauthType = OauthType.KAKAO;

public KakaoOauthAttributes(Map<String, Object> attributes) {
log.info("attributes.toString() : " + attributes.toString());
Map<String, Object> properties = (Map<String, Object>)attributes.get("properties");
this.nickname = (String)properties.get("nickname");
log.info("this.nickname : " + this.nickname);
this.email = UUID.randomUUID().toString();
}

@Override
public String getEmail() {
return this.email;
}

@Override
public String getUsername() {
return this.nickname;
}

@Override
public OauthType getOauthType() {
return this.oauthType;
}
}
54 changes: 4 additions & 50 deletions src/main/java/com/gt/genti/config/auth/OAuthAttributes.java
Original file line number Diff line number Diff line change
@@ -1,55 +1,9 @@
package com.gt.genti.config.auth;

import java.util.Map;

import com.gt.genti.domain.enums.OauthType;
import com.gt.genti.domain.enums.converter.EnumUtil;

import lombok.Builder;
import lombok.Getter;

@Getter
public class OAuthAttributes {
private Map<String, Object> attributes;
private String nameAttributeKey;
private String name;
private String email;

@Builder
public OAuthAttributes(Map<String, Object> attributes, String nameAttributeKey, String name, String email) {
this.attributes = attributes;
this.nameAttributeKey = nameAttributeKey;
this.name = name;
this.email = email;
}

public static OAuthAttributes of(String registrationId, String userNameAttributeName,
Map<String, Object> attributes) {
OauthType oauthType = EnumUtil.stringToEnum(OauthType.class, registrationId);
switch (oauthType) {
case GOOGLE -> {
return ofGoogle(userNameAttributeName, attributes);
}
case KAKAO -> {
// return ofGoogle(userNameAttributeName, attributes);
}
case APPLE -> {
// return ofGoogle(userNameAttributeName, attributes);
}
case NULL -> {

}
}
throw new RuntimeException("등록되지 않은 oauth type? ");
}

private static OAuthAttributes ofGoogle(String userNameAttributeName, Map<String, Object> attributes) {
return OAuthAttributes.builder()
.name((String)attributes.get("name"))
.email((String)attributes.get("email"))
.attributes(attributes)
.nameAttributeKey(userNameAttributeName)
.build();
}

public interface OauthAttributes {
String getEmail();
String getUsername();
OauthType getOauthType();
}
46 changes: 46 additions & 0 deletions src/main/java/com/gt/genti/config/auth/OauthAttributeBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.gt.genti.config.auth;

import java.util.Map;

import com.gt.genti.domain.enums.OauthType;
import com.gt.genti.domain.enums.converter.EnumUtil;

import lombok.Builder;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

@Getter
@Slf4j
public class OauthAttributeBuilder {
private Map<String, Object> attributes;
// private String nameAttributeKey;
private String name;
private String email;

@Builder
public OauthAttributeBuilder(Map<String, Object> attributes, String nameAttributeKey, String name, String email) {
this.attributes = attributes;
// this.nameAttributeKey = nameAttributeKey;
this.name = name;
this.email = email;
}

public static OauthAttributes of(String registrationId, Map<String, Object> attributes) {
OauthType oauthType = EnumUtil.stringToEnumIgnoreCase(OauthType.class, registrationId);
switch (oauthType) {
case GOOGLE -> {
return new GoogleOauthAttributes(attributes);
}
case KAKAO -> {
return new KakaoOauthAttributes(attributes);
}
case APPLE -> {
return new AppleOauthAttributes(attributes);
}
case NULL -> {

}
}
throw new RuntimeException("등록되지 않은 oauth type :" + registrationId);
}
}
3 changes: 1 addition & 2 deletions src/main/java/com/gt/genti/config/auth/UserDetailsImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ public boolean isEnabled() {

@Override
public String getName() {
String sub = attributes.get("sub").toString();
return sub;
return attributes.get("sub").toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class CommonLoginSuccessHandler extends SavedRequestAwareAuthenticationSu
private final JwtTokenProvider jwtTokenProvider;
// private final CustomOAuth2UserService customOAuth2UserService;

@Value("${jwt.redirect-url}")
@Value("${spring.security.oauth2.redirect-url}")
private String redirectUrl;

@Override
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/com/gt/genti/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
import java.time.Period;
import java.util.List;

import com.gt.genti.config.auth.OAuthAttributes;
import com.gt.genti.config.auth.OauthAttributes;
import com.gt.genti.domain.common.BaseTimeEntity;
import com.gt.genti.domain.enums.OauthType;
import com.gt.genti.domain.enums.UserRole;
import com.gt.genti.domain.enums.UserStatus;
import com.gt.genti.domain.enums.converter.OauthTypeConverter;
import com.gt.genti.domain.enums.converter.OauthTypeConverterIgnoreCase;
import com.gt.genti.domain.enums.converter.UserRoleConverter;
import com.gt.genti.domain.enums.converter.UserStatusConverter;
import com.gt.genti.dto.UserInfoUpdateRequestDto;
Expand Down Expand Up @@ -84,7 +84,7 @@ public class User extends BaseTimeEntity {
Creator creator;

@Column(name = "last_login_social_platform")
@Convert(converter = OauthTypeConverter.class)
@Convert(converter = OauthTypeConverterIgnoreCase.class)
OauthType lastLoginSocialPlatform;

@Column(name = "deleted_at")
Expand Down Expand Up @@ -119,13 +119,13 @@ private User(Long id) {
this.id = id;
}

public static User createNewSocialUser(OAuthAttributes attributes) {
String email = attributes.getEmail();
String username = attributes.getName();
public static User createNewSocialUser(OauthAttributes oauthAttributes) {
String email = oauthAttributes.getEmail();
String username = oauthAttributes.getUsername();
//TODO 최초가입자 닉네임 랜덤 생성 && Oauth타입알아내기
// edited at 2024-04-25
// author
OauthType oauthType = OauthType.GOOGLE;
OauthType oauthType = oauthAttributes.getOauthType();
String nickname = "최초로그인시닉네임";
return new User(email, username, nickname, oauthType, UserRole.USER);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,22 @@
import com.gt.genti.domain.enums.ConvertableEnum;

import jakarta.persistence.AttributeConverter;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public class DefaultStringAttributeConverter<T extends Enum<T> & ConvertableEnum> implements AttributeConverter<T, String> {
public class DefaultStringAttributeConverter<T extends Enum<T> & ConvertableEnum>
implements AttributeConverter<T, String> {
private final Class<T> enumClassType;

@Override
public String convertToDatabaseColumn(T attribute) {
return attribute.getStringValue();
}

@Override
public T convertToEntityAttribute(String dbData) {
return EnumUtil.stringToEnum(enumClassType, dbData);
return EnumUtil.stringToEnum(getEnumClassType(), dbData);
}
}
23 changes: 22 additions & 1 deletion src/main/java/com/gt/genti/domain/enums/converter/EnumUtil.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.gt.genti.domain.enums.converter;

import org.thymeleaf.util.StringUtils;

import com.gt.genti.domain.enums.ConvertableEnum;

import lombok.extern.slf4j.Slf4j;
Expand All @@ -19,7 +21,26 @@ enum type : %s은 null 값을 허용하지 않습니다.

public static <E extends Enum<E> & ConvertableEnum> E stringToEnum(Class<E> enumType, String value) {
for (E enumValue : enumType.getEnumConstants()) {
if (enumValue.getStringValue().equals(value)) {
if (StringUtils.equals(value, enumValue.getStringValue())) {
return enumValue;
}
}

try {
return convertNullToEnum(enumType);
} catch (Exception e) {
throw new RuntimeException("""
DB -> ENUM 값 불러오기 실패 enum : %s value : %s \n%s
""".formatted(enumType.getName(), value, e.getMessage()));
}
}

public static <E extends Enum<E> & ConvertableEnum> E stringToEnumIgnoreCase(Class<E> enumType, String value) {
for (E enumValue : enumType.getEnumConstants()) {
log.info("enumValue.name() : " + enumValue.name());
log.info("enumValue.getStringValue() : " + enumValue.getStringValue());
log.info("value : " + value);
if (StringUtils.equalsIgnoreCase(value, enumValue.getStringValue())) {
return enumValue;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.gt.genti.domain.enums.converter;

import com.gt.genti.domain.enums.ConvertableEnum;

public class IgnoreCaseStringAttributeConverter<T extends Enum<T> & ConvertableEnum>
extends DefaultStringAttributeConverter<T> {
public IgnoreCaseStringAttributeConverter(Class<T> enumClassType) {
super(enumClassType);
}

@Override
public String convertToDatabaseColumn(T attribute) {
return attribute.getStringValue().toUpperCase();
}

@Override
public T convertToEntityAttribute(String dbData) {
return EnumUtil.stringToEnumIgnoreCase(getEnumClassType(), dbData);
}

}
Loading

0 comments on commit fb65236

Please sign in to comment.