-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
56 changed files
with
1,817 additions
and
2 deletions.
There are no files selected for viewing
54 changes: 54 additions & 0 deletions
54
src/main/java/com/atwoz/member/application/auth/AuthService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.atwoz.member.application.auth; | ||
|
||
import com.atwoz.global.event.Events; | ||
import com.atwoz.member.application.auth.dto.LoginRequest; | ||
import com.atwoz.member.application.auth.dto.SignupRequest; | ||
import com.atwoz.member.domain.auth.RegisteredEvent; | ||
import com.atwoz.member.domain.auth.TokenProvider; | ||
import com.atwoz.member.domain.member.Member; | ||
import com.atwoz.member.domain.member.MemberRepository; | ||
import com.atwoz.member.domain.member.NicknameGenerator; | ||
import com.atwoz.member.exception.exceptions.member.MemberAlreadyExistedException; | ||
import com.atwoz.member.exception.exceptions.member.MemberNotFoundException; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@RequiredArgsConstructor | ||
@Service | ||
public class AuthService { | ||
|
||
private final MemberRepository memberRepository; | ||
private final TokenProvider tokenProvider; | ||
private final NicknameGenerator nicknameGenerator; | ||
|
||
@Transactional | ||
public String signup(final SignupRequest request) { | ||
validateExistedMember(request.email()); | ||
|
||
Member member = Member.createDefaultRole(request.email(), request.password(), nicknameGenerator); | ||
Member signupMember = memberRepository.save(member); | ||
Events.raise(new RegisteredEvent(member.getId(), member.getEmail(), member.getNickname())); | ||
|
||
return tokenProvider.create(signupMember.getId()); | ||
} | ||
|
||
private void validateExistedMember(final String email) { | ||
if (memberRepository.existsByEmail(email)) { | ||
throw new MemberAlreadyExistedException(); | ||
} | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public String login(final LoginRequest request) { | ||
Member member = findMemberByEmail(request.email()); | ||
member.validatePassword(request.password()); | ||
|
||
return tokenProvider.create(member.getId()); | ||
} | ||
|
||
private Member findMemberByEmail(final String email) { | ||
return memberRepository.findByEmail(email) | ||
.orElseThrow(MemberNotFoundException::new); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/com/atwoz/member/application/auth/dto/LoginRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.atwoz.member.application.auth.dto; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
|
||
public record LoginRequest( | ||
@NotBlank(message = "이메일을 입력해주세요.") | ||
String email, | ||
|
||
@NotBlank(message = "패스워드를 입력해주세요.") | ||
String password | ||
) { | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/com/atwoz/member/application/auth/dto/SignupRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.atwoz.member.application.auth.dto; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
|
||
public record SignupRequest( | ||
@NotBlank(message = "이메일을 입력해주세요.") | ||
String email, | ||
|
||
@NotBlank(message = "패스워드를 입력해주세요.") | ||
String password | ||
) { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.atwoz.member.config; | ||
|
||
import com.atwoz.member.ui.auth.interceptor.LoginValidCheckerInterceptor; | ||
import com.atwoz.member.ui.auth.interceptor.ParseMemberIdFromTokenInterceptor; | ||
import com.atwoz.member.ui.auth.interceptor.PathMatcherInterceptor; | ||
import com.atwoz.member.ui.auth.support.resolver.AuthArgumentResolver; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.method.support.HandlerMethodArgumentResolver; | ||
import org.springframework.web.servlet.HandlerInterceptor; | ||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; | ||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||
|
||
import java.util.List; | ||
|
||
import static com.atwoz.member.ui.auth.interceptor.HttpMethod.ANY; | ||
import static com.atwoz.member.ui.auth.interceptor.HttpMethod.OPTIONS; | ||
|
||
@RequiredArgsConstructor | ||
@Configuration | ||
public class AuthConfig implements WebMvcConfigurer { | ||
|
||
private final AuthArgumentResolver authArgumentResolver; | ||
private final ParseMemberIdFromTokenInterceptor parseMemberIdFromTokenInterceptor; | ||
private final LoginValidCheckerInterceptor loginValidCheckerInterceptor; | ||
|
||
@Override | ||
public void addInterceptors(InterceptorRegistry registry) { | ||
registry.addInterceptor(parseMemberIdFromTokenInterceptor()); | ||
registry.addInterceptor(loginValidCheckerInterceptor()); | ||
} | ||
|
||
private HandlerInterceptor parseMemberIdFromTokenInterceptor() { | ||
return new PathMatcherInterceptor(parseMemberIdFromTokenInterceptor) | ||
.excludePathPattern("/**", OPTIONS) | ||
.addPathPatterns("/admin/**", ANY); | ||
} | ||
|
||
/** | ||
* @AuthMember를 통해서 인증이 필요한 경우에 해당 메서드에 URI를 추가해주면 된다. | ||
* 추가를 해야지 인증,인가 가능 | ||
*/ | ||
private HandlerInterceptor loginValidCheckerInterceptor() { | ||
return new PathMatcherInterceptor(loginValidCheckerInterceptor) | ||
.excludePathPattern("/**", OPTIONS); | ||
} | ||
|
||
@Override | ||
public void addArgumentResolvers(final List<HandlerMethodArgumentResolver> resolvers) { | ||
resolvers.add(authArgumentResolver); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
src/main/java/com/atwoz/member/domain/auth/RegisteredEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.atwoz.member.domain.auth; | ||
|
||
import com.atwoz.global.event.Event; | ||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public class RegisteredEvent extends Event { | ||
|
||
private final Long memberId; | ||
private final String email; | ||
private final String nickname; | ||
} |
8 changes: 8 additions & 0 deletions
8
src/main/java/com/atwoz/member/domain/auth/TokenProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.atwoz.member.domain.auth; | ||
|
||
public interface TokenProvider { | ||
|
||
String create(final Long id); | ||
|
||
Long extract(final String token); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package com.atwoz.member.domain.member; | ||
|
||
import com.atwoz.global.domain.BaseEntity; | ||
import com.atwoz.member.exception.exceptions.member.PasswordNotMatchedException; | ||
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 lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.EqualsAndHashCode; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@Builder | ||
@EqualsAndHashCode(of = "id", callSuper = false) | ||
@AllArgsConstructor(access = AccessLevel.PRIVATE) | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@Entity | ||
public class Member extends BaseEntity { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
@Column(nullable = false, unique = true) | ||
private String email; | ||
|
||
@Column(nullable = false) | ||
private String password; | ||
|
||
@Column(nullable = false) | ||
private String nickname; | ||
|
||
@Enumerated(value = EnumType.STRING) | ||
@Column(nullable = false) | ||
private MemberRole memberRole; | ||
|
||
public boolean isAdmin() { | ||
return this.memberRole.isAdministrator(); | ||
} | ||
|
||
public static Member createDefaultRole(final String email, | ||
final String password, | ||
final NicknameGenerator nicknameGenerator) { | ||
return Member.builder() | ||
.email(email) | ||
.password(password) | ||
.nickname(nicknameGenerator.createRandomNickname()) | ||
.memberRole(MemberRole.MEMBER) | ||
.build(); | ||
} | ||
|
||
public void validatePassword(final String password) { | ||
if (!this.password.equals(password)) { | ||
throw new PasswordNotMatchedException(); | ||
} | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/atwoz/member/domain/member/MemberRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.atwoz.member.domain.member; | ||
|
||
import java.util.Optional; | ||
|
||
public interface MemberRepository { | ||
|
||
Optional<Member> findById(final Long id); | ||
|
||
Optional<Member> findByNickname(final String nickname); | ||
|
||
Optional<Member> findByEmail(final String email); | ||
|
||
Member save(final Member member); | ||
|
||
boolean existsByEmail(final String email); | ||
} |
30 changes: 30 additions & 0 deletions
30
src/main/java/com/atwoz/member/domain/member/MemberRole.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.atwoz.member.domain.member; | ||
|
||
import com.atwoz.member.exception.exceptions.member.RoleNotFoundException; | ||
import lombok.Getter; | ||
|
||
import java.util.Arrays; | ||
|
||
@Getter | ||
public enum MemberRole { | ||
|
||
MEMBER("member"), | ||
ADMIN("admin"); | ||
|
||
private final String role; | ||
|
||
MemberRole(final String role) { | ||
this.role = role; | ||
} | ||
|
||
public static MemberRole from(final String role) { | ||
return Arrays.stream(values()) | ||
.filter(value -> value.role.equalsIgnoreCase(role)) | ||
.findFirst() | ||
.orElseThrow(RoleNotFoundException::new); | ||
} | ||
|
||
public boolean isAdministrator() { | ||
return this.equals(ADMIN); | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
src/main/java/com/atwoz/member/domain/member/NicknameGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.atwoz.member.domain.member; | ||
|
||
public interface NicknameGenerator { | ||
|
||
String createRandomNickname(); | ||
} |
92 changes: 92 additions & 0 deletions
92
src/main/java/com/atwoz/member/exception/MemberExceptionHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package com.atwoz.member.exception; | ||
|
||
import com.atwoz.member.exception.exceptions.auth.ExpiredTokenException; | ||
import com.atwoz.member.exception.exceptions.auth.LoginInvalidException; | ||
import com.atwoz.member.exception.exceptions.auth.SignatureInvalidException; | ||
import com.atwoz.member.exception.exceptions.auth.TokenFormInvalidException; | ||
import com.atwoz.member.exception.exceptions.auth.TokenInvalidException; | ||
import com.atwoz.member.exception.exceptions.auth.UnsupportedTokenException; | ||
import com.atwoz.member.exception.exceptions.member.MemberAlreadyExistedException; | ||
import com.atwoz.member.exception.exceptions.member.MemberNotFoundException; | ||
import com.atwoz.member.exception.exceptions.member.PasswordNotMatchedException; | ||
import com.atwoz.member.exception.exceptions.member.RoleNotFoundException; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.RestControllerAdvice; | ||
|
||
@RestControllerAdvice | ||
public class MemberExceptionHandler { | ||
|
||
// member | ||
@ExceptionHandler(RoleNotFoundException.class) | ||
public ResponseEntity<String> handleRoleNotFoundException(final RoleNotFoundException e) { | ||
return getNotFoundResponse(e); | ||
} | ||
|
||
@ExceptionHandler(MemberAlreadyExistedException.class) | ||
public ResponseEntity<String> handleMemberAlreadyExistedException(final MemberAlreadyExistedException e) { | ||
return getConflicted(e); | ||
} | ||
|
||
@ExceptionHandler(MemberNotFoundException.class) | ||
public ResponseEntity<String> handleMemberNotFoundException(final MemberNotFoundException e) { | ||
return getNotFoundResponse(e); | ||
} | ||
|
||
@ExceptionHandler(PasswordNotMatchedException.class) | ||
public ResponseEntity<String> handlePasswordNotMatchedException(final PasswordNotMatchedException e) { | ||
return getConflicted(e); | ||
} | ||
|
||
// auth | ||
@ExceptionHandler(SignatureInvalidException.class) | ||
public ResponseEntity<String> handleSignatureInvalidException(final SignatureInvalidException e) { | ||
return getUnauthorized(e); | ||
} | ||
|
||
@ExceptionHandler(TokenFormInvalidException.class) | ||
public ResponseEntity<String> handleTokenFormInvalidException(final TokenFormInvalidException e) { | ||
return getUnauthorized(e); | ||
} | ||
|
||
@ExceptionHandler(ExpiredTokenException.class) | ||
public ResponseEntity<String> handleExpiredTokenException(final ExpiredTokenException e) { | ||
return getUnauthorized(e); | ||
} | ||
|
||
@ExceptionHandler(UnsupportedTokenException.class) | ||
public ResponseEntity<String> handleUnsupportedTokenException(final UnsupportedTokenException e) { | ||
return getUnauthorized(e); | ||
} | ||
|
||
@ExceptionHandler(TokenInvalidException.class) | ||
public ResponseEntity<String> handleTokenInvalidException(final TokenInvalidException e) { | ||
return getUnauthorized(e); | ||
} | ||
|
||
@ExceptionHandler(LoginInvalidException.class) | ||
public ResponseEntity<String> handleLoginInvalidException(final LoginInvalidException e) { | ||
return getUnauthorized(e); | ||
} | ||
|
||
private ResponseEntity<String> getNotFoundResponse(final Exception e) { | ||
return ResponseEntity.status(HttpStatus.NOT_FOUND) | ||
.body(e.getMessage()); | ||
} | ||
|
||
private ResponseEntity<String> getUnauthorized(final Exception e) { | ||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED) | ||
.body(e.getMessage()); | ||
} | ||
|
||
private ResponseEntity<String> getConflicted(final Exception e) { | ||
return ResponseEntity.status(HttpStatus.CONFLICT) | ||
.body(e.getMessage()); | ||
} | ||
|
||
private ResponseEntity<String> getBadRequest(final Exception e) { | ||
return ResponseEntity.status(HttpStatus.BAD_REQUEST) | ||
.body(e.getMessage()); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/main/java/com/atwoz/member/exception/exceptions/auth/ExpiredTokenException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.atwoz.member.exception.exceptions.auth; | ||
|
||
public class ExpiredTokenException extends RuntimeException { | ||
|
||
public ExpiredTokenException() { | ||
super("이미 만료된 토큰입니다"); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/main/java/com/atwoz/member/exception/exceptions/auth/LoginInvalidException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.atwoz.member.exception.exceptions.auth; | ||
|
||
public class LoginInvalidException extends RuntimeException { | ||
|
||
public LoginInvalidException() { | ||
super("로그인 정보를 찾을 수 없습니다."); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/main/java/com/atwoz/member/exception/exceptions/auth/SignatureInvalidException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.atwoz.member.exception.exceptions.auth; | ||
|
||
public class SignatureInvalidException extends RuntimeException { | ||
|
||
public SignatureInvalidException() { | ||
super("서명을 확인하지 못했습니다."); | ||
} | ||
} |
Oops, something went wrong.