Skip to content

Commit

Permalink
Merge pull request #22 from DDD-Community/feature/ITDS-25-apple-socia…
Browse files Browse the repository at this point in the history
…l-login

Feature/itds 25 apple social login
  • Loading branch information
kikingki authored Sep 9, 2024
2 parents 71cd0d1 + e7d4766 commit 25e5e46
Show file tree
Hide file tree
Showing 19 changed files with 382 additions and 121 deletions.
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ dependencies {
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:4.1.0'
implementation 'io.jsonwebtoken:jjwt:0.9.1'
implementation 'com.nimbusds:nimbus-jose-jwt:9.29'
implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1'

//QueryDSL
Expand All @@ -61,7 +62,7 @@ dependencies {
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"

implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
}

def QDomains = []
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.dissonance.itit.client;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name = "AppleInformationFeignClient", url = "${apple.api_url.information}")
public interface AppleInformationFeignClient {
@GetMapping
String call();
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public enum ErrorCode {
INVALID_FILE_TYPE(HttpStatus.BAD_REQUEST, "파일 형식은 이미지만 가능합니다."),
INVALID_FILE_SIZE(HttpStatus.BAD_REQUEST, "파일 용량은 10MB를 넘을 수 없습니다."),
INVALID_DATE_FORMAT(HttpStatus.BAD_REQUEST, "날짜 변환에 실패했습니다."),
INVALID_APPLE_TOKEN(HttpStatus.BAD_REQUEST, "유효하지 않는 Apple Token입니다."),
INVALID_JSON_FORMAT(HttpStatus.BAD_REQUEST, "잘못된 JSON 형식입니다."),

// 404
NON_EXISTENT_USER_ID(HttpStatus.NOT_FOUND, "해당 id의 사용자가 존재하지 않습니다."),
Expand All @@ -23,7 +25,8 @@ public enum ErrorCode {
REPORTED_INFO_POST_ID(HttpStatus.NOT_FOUND, "해당 id의 게시글은 신고 처리되었습니다."),

// 500
IO_EXCEPTION(HttpStatus.INTERNAL_SERVER_ERROR, "파일 입출력 에러");
IO_EXCEPTION(HttpStatus.INTERNAL_SERVER_ERROR, "파일 입출력 에러"),
INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "서버 내부 에러");

private final HttpStatus httpStatus;
private final String message;
Expand Down
81 changes: 45 additions & 36 deletions src/main/java/com/dissonance/itit/domain/entity/User.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
package com.dissonance.itit.domain.entity;

import com.dissonance.itit.domain.enums.Role;
import jakarta.persistence.*;
import com.dissonance.itit.domain.enums.SocialLoginProvider;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.*;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Builder
Expand All @@ -13,38 +26,34 @@
@Entity
@Table(name = "user")
public class User extends BaseTime {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

@Column(name = "password")
private String password;

@Size(max = 50)
@NotNull
@Column(name = "name")
private String name;

@Size(max = 100)
@NotNull
@Column(name = "email")
private String email;

@Enumerated(EnumType.STRING)
@NotNull
@Column(name = "role")
private Role role;

@Column(name = "provider_id")
private String providerId;

@Size(max = 50)
@NotNull
@Column(name = "provider")
private String provider;

@Size(max = 255)
@Column(name = "profile_img_url")
private String profileImgUrl;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

@Size(max = 50)
@Column(name = "name")
private String name;

@Size(max = 100)
@NotNull
@Column(name = "email")
private String email;

@Enumerated(EnumType.STRING)
@NotNull
@Column(name = "role")
private Role role;

@Column(name = "provider_id")
private String providerId;

@Enumerated(EnumType.STRING)
@NotNull
@Column(name = "provider")
private SocialLoginProvider provider;

@Size(max = 255)
@Column(name = "profile_img_url")
private String profileImgUrl;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public String getUsername() {

@Override
public String getPassword() {
return user.getPassword();
return user.getProviderId();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.dissonance.itit.domain.enums;

public enum SocialLoginProvider {
KAKAO,
APPLE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.dissonance.itit.dto.response;

import com.dissonance.itit.domain.enums.SocialLoginProvider;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Getter
public class AppleUserInfomation implements OAuthUserInformation {
private String providerId;
private String email;

@Override
public SocialLoginProvider getProvider() {
return SocialLoginProvider.APPLE;
}

@Override
public String getProviderId() {
return providerId;
}

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

@Override
public String getNickname() {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.dissonance.itit.dto.response;

import com.dissonance.itit.domain.enums.SocialLoginProvider;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

Expand Down Expand Up @@ -28,8 +29,8 @@ public String getProfileImgUrl() {
}

@Override
public String getProvider() {
return "kakao";
public SocialLoginProvider getProvider() {
return SocialLoginProvider.KAKAO;
}

@Override
Expand Down
23 changes: 23 additions & 0 deletions src/main/java/com/dissonance/itit/dto/response/Keys.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.dissonance.itit.dto.response;

import java.util.List;

import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Getter;

@Getter
public class Keys {
@JsonProperty(value = "keys")
private List<Key> keyList;

@Getter
public static class Key {
private String kty;
private String kid;
private String use;
private String alg;
private String n;
private String e;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.dissonance.itit.dto.response;

import com.dissonance.itit.domain.enums.SocialLoginProvider;

public record LoginUserInfoRes(
boolean isAdmin,
String provider) {
SocialLoginProvider provider) {
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package com.dissonance.itit.dto.response;

import com.dissonance.itit.domain.enums.SocialLoginProvider;

public interface OAuthUserInformation {
String getProvider();
String getProviderId();
String getProfileImgUrl();
String getNickname();
String getEmail();
SocialLoginProvider getProvider();

String getProviderId();

String getProfileImgUrl();

String getNickname();

String getEmail();
}
33 changes: 33 additions & 0 deletions src/main/java/com/dissonance/itit/factory/OAuthServiceFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.dissonance.itit.factory;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.dissonance.itit.common.exception.CustomException;
import com.dissonance.itit.common.exception.ErrorCode;
import com.dissonance.itit.domain.enums.SocialLoginProvider;
import com.dissonance.itit.service.OAuthService;

@Component
public class OAuthServiceFactory {
private final Map<SocialLoginProvider, OAuthService> oAuthServices;

@Autowired
public OAuthServiceFactory(List<OAuthService> oAuthServiceList) {
oAuthServices = oAuthServiceList.stream()
.collect(Collectors.toMap(OAuthService::getProvider, Function.identity()));
}

public OAuthService getOAuthService(SocialLoginProvider provider) {
OAuthService service = oAuthServices.get(provider);
if (service == null) {
throw new CustomException(ErrorCode.INVALID_PROVIDER);
}
return service;
}
}
11 changes: 7 additions & 4 deletions src/main/java/com/dissonance/itit/repository/UserRepository.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.dissonance.itit.repository;

import com.dissonance.itit.domain.entity.User;
import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;
import com.dissonance.itit.domain.entity.User;
import com.dissonance.itit.domain.enums.SocialLoginProvider;

public interface UserRepository extends JpaRepository<User, Long> {
boolean existsByProviderAndProviderId(String provider, String providerId);
Optional<User> findByEmail(String email);
boolean existsByProviderAndProviderId(SocialLoginProvider provider, String providerId);

Optional<User> findByEmail(String email);
}
Loading

0 comments on commit 25e5e46

Please sign in to comment.