Skip to content

Commit

Permalink
[feat] : login 처리, 회원가입시 이메일로 중복 검증
Browse files Browse the repository at this point in the history
  • Loading branch information
BlackBean99 committed Sep 1, 2023
1 parent 0904aa3 commit 93541c2
Show file tree
Hide file tree
Showing 23 changed files with 97 additions and 42 deletions.
Binary file modified server/.gradle/7.6.1/executionHistory/executionHistory.bin
Binary file not shown.
Binary file modified server/.gradle/7.6.1/executionHistory/executionHistory.lock
Binary file not shown.
Binary file modified server/.gradle/7.6.1/fileHashes/fileHashes.bin
Binary file not shown.
Binary file modified server/.gradle/7.6.1/fileHashes/fileHashes.lock
Binary file not shown.
Binary file modified server/.gradle/7.6.1/fileHashes/resourceHashesCache.bin
Binary file not shown.
Binary file modified server/.gradle/buildOutputCleanup/buildOutputCleanup.lock
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.econovation.recruit.api.applicant.usecase.ApplicantRegisterUseCase;
import com.econovation.recruitcommon.utils.Result;
import com.econovation.recruitdomain.common.aop.domainEvent.Events;
import com.econovation.recruitdomain.domain.applicant.Applicant;
import com.econovation.recruitdomain.domains.applicant.adaptor.AnswerAdaptor;
import com.econovation.recruitdomain.domains.applicant.adaptor.QuestionAdaptor;
import com.econovation.recruitdomain.domains.applicant.domain.Answer;
Expand All @@ -13,7 +12,6 @@
import com.econovation.recruitdomain.domains.applicant.exception.ApplicantDuplicateSubmitException;
import com.econovation.recruitdomain.domains.applicant.exception.QuestionNotFoundException;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -120,23 +118,4 @@ private String convertToSubmitApplicantEventTitle(List<Answer> results) {
titleBuilder.append("[").append(hopeField).append("] ").append(name);
return titleBuilder.toString();
}

private Applicant createApplicantFromUserInput(Map<String, String> userInput) {
return Applicant.builder()
.id(UUID.randomUUID())
.hopeField(userInput.get("hopeField"))
.firstPriority(userInput.get("firstPriority"))
.secondPriority(userInput.get("secondPriority"))
.name(userInput.get("name"))
.phoneNumber(userInput.get("phoneNumber"))
.studentId(Integer.parseInt(userInput.get("studentId")))
.grade(Integer.parseInt(userInput.get("grade")))
.semester(Integer.parseInt(userInput.get("semester")))
.major(userInput.get("major"))
.doubleMajor(userInput.get("doubleMajor"))
.minor(userInput.get("minor"))
.supportPath(userInput.get("supportPath"))
.email(userInput.get("email"))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
@AllArgsConstructor
@Getter
public class AuthDetails implements UserDetails {

private String userId;
private String idpId;

private String role;

Expand All @@ -28,7 +27,7 @@ public String getPassword() {

@Override
public String getUsername() {
return userId;
return idpId;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
Expand Down Expand Up @@ -71,18 +72,21 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// .permitAll()
// .mvcMatchers("/v1/auth/token/refresh")
// .permitAll()
// .mvcMatchers(HttpMethod.GET, "/api/v1/token}")
// .permitAll()
// .mvcMatchers(HttpMethod.GET,
// "/v1/events/{eventId:[0-9]*$}/ticketItems")
// .permitAll()
// .mvcMatchers(HttpMethod.GET,
// "/v1/events/{eventId:[0-9]*$}/comments/**")
// .permitAll()
// .mvcMatchers(HttpMethod.GET, "/v1/events/search")
// .permitAll()
// .mvcMatchers(HttpMethod.GET, "/v1/examples/health")
// TODO 임시로 모든 요청 permit
.mvcMatchers(HttpMethod.POST, "/api/v1/questions")
.permitAll()
.mvcMatchers(HttpMethod.POST, "/api/v1/applicants")
.permitAll()
.mvcMatchers(HttpMethod.POST, "/api/v1/signup")
.permitAll()
.mvcMatchers(HttpMethod.POST, "/api/v1/login")
.permitAll()
// TODO 임시로 모든 요청 permit -> 채승이가 로그인 로직 완성하면 수정
.mvcMatchers("/**")
.permitAll()
// 스웨거용 인메모리 유저의 권한은 SWAGGER 이다
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
import com.econovation.recruit.api.user.usecase.UserRegisterUseCase;
import com.econovation.recruitcommon.annotation.ApiErrorExceptionsExample;
import com.econovation.recruitcommon.annotation.DevelopOnlyApi;
import com.econovation.recruitcommon.dto.TokenResponse;
import com.econovation.recruitcommon.jwt.JwtTokenProvider;
import com.econovation.recruitdomain.domains.dto.LoginRequestDto;
import com.econovation.recruitdomain.domains.dto.SignUpRequestDto;
import com.econovation.recruitdomain.domains.dto.TokenResponse;
import com.econovation.recruitdomain.domains.interviewer.domain.Role;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand All @@ -21,14 +21,15 @@
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;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1")
@Slf4j
@Tag(name = "[0.0]. 유저 관련 임시 API", description = "유저 관련 API")
@Tag(name = "[0.0]. 유저 관련 API", description = "유저 API")
public class UserController {
private final JwtTokenProvider jwtTokenProvider;
private final UserRegisterUseCase userRegisterUseCase;
Expand Down Expand Up @@ -58,7 +59,7 @@ public ResponseEntity<TokenResponse> login(LoginRequestDto loginRequestDto) {
@Operation(summary = "회원가입합니다.", description = "회원가입합니다.")
@ApiErrorExceptionsExample(InterviewerExceptionDocs.class)
@PostMapping("/signup")
public ResponseEntity<String> signUp(@Valid SignUpRequestDto signUpRequestDto) {
public ResponseEntity<String> signUp(@Valid @RequestBody SignUpRequestDto signUpRequestDto) {
userRegisterUseCase.signUp(signUpRequestDto);
return new ResponseEntity<>(INTERVIEWER_SUCCESS_SIGNUP_MESSAGE, HttpStatus.OK);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.econovation.recruit.api.user.docs;

import com.econovation.recruitcommon.annotation.ExceptionDoc;
import com.econovation.recruitcommon.annotation.ExplainError;
import com.econovation.recruitcommon.exception.RecruitCodeException;
import com.econovation.recruitcommon.interfaces.SwaggerExampleExceptions;
import com.econovation.recruitdomain.domains.interviewer.exception.InterviewerNotMatchException;
import com.econovation.recruitdomain.domains.interviewer.exception.InvalidPasswordException;

@ExceptionDoc
public class LoginExceptionDocs implements SwaggerExampleExceptions {
@ExplainError("유효하지 않은 비밀번호를 입력한 경우")
public RecruitCodeException 비밀번호_부적절 = InvalidPasswordException.EXCEPTION;

@ExplainError("등록되지 않은 이메일과 비밀번호로 로그인을 시도한 경우")
public RecruitCodeException 이메일_비밀번호_불일치 = InterviewerNotMatchException.EXCEPTION;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

import com.econovation.recruit.api.user.usecase.UserLoginUseCase;
import com.econovation.recruit.api.user.usecase.UserRegisterUseCase;
import com.econovation.recruitcommon.dto.TokenResponse;
import com.econovation.recruitcommon.jwt.JwtTokenProvider;
import com.econovation.recruitdomain.domains.dto.LoginRequestDto;
import com.econovation.recruitdomain.domains.dto.SignUpRequestDto;
import com.econovation.recruitdomain.domains.dto.TokenResponse;
import com.econovation.recruitdomain.domains.interviewer.domain.Interviewer;
import com.econovation.recruitdomain.domains.interviewer.exception.InterviewerNotMatchException;
import com.econovation.recruitdomain.out.InterviewerLoadPort;
import com.econovation.recruitdomain.out.InterviewerRecordPort;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
Expand All @@ -16,14 +19,29 @@
@RequiredArgsConstructor
public class UserService implements UserRegisterUseCase, UserLoginUseCase {
private final InterviewerRecordPort interviewerRecordPort;
private final InterviewerLoadPort interviewerLoadPort;
private final JwtTokenProvider jwtTokenProvider;
private final PasswordEncoder passwordEncoder;

@Override
public TokenResponse execute(LoginRequestDto loginRequestDto) {}
@Transactional
public TokenResponse execute(LoginRequestDto loginRequestDto) {
Interviewer account =
interviewerLoadPort.loadInterviewerByEmail(loginRequestDto.getEmail());
checkPassword(loginRequestDto.getPassword(), account.getPassword());
return jwtTokenProvider.createToken(account.getId(), account.getRole().name());
}

private void checkPassword(String password, String encodePassword) {
boolean isMatch = passwordEncoder.matches(password, encodePassword);
if (!isMatch) throw InterviewerNotMatchException.EXCEPTION;
}

@Override
@Transactional
public void signUp(SignUpRequestDto signUpRequestDto) {
if (interviewerLoadPort.loadInterviewerByEmail(signUpRequestDto.getEmail()) != null)
throw InterviewerNotMatchException.EXCEPTION;
String encededPassword = passwordEncoder.encode(signUpRequestDto.getPassword());
Interviewer interviewer =
Interviewer.builder()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.econovation.recruit.api.user.usecase;

import com.econovation.recruitcommon.annotation.UseCase;
import com.econovation.recruitcommon.dto.TokenResponse;
import com.econovation.recruitdomain.domains.dto.LoginRequestDto;
import com.econovation.recruitdomain.domains.dto.TokenResponse;

@UseCase
public interface UserLoginUseCase {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.econovation.recruitdomain.domains.dto;
package com.econovation.recruitcommon.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static com.econovation.recruitcommon.consts.RecruitStatic.*;

import com.econovation.recruitcommon.dto.AccessTokenInfo;
import com.econovation.recruitcommon.dto.TokenResponse;
import com.econovation.recruitcommon.exception.ExpiredTokenException;
import com.econovation.recruitcommon.exception.InvalidTokenException;
import com.econovation.recruitcommon.exception.RefreshTokenExpiredException;
Expand All @@ -24,6 +25,12 @@ public class JwtTokenProvider {

private final JwtProperties jwtProperties;

public TokenResponse createToken(Long idpId, String role) {
String accessToken = generateAccessToken(idpId, role);
String refreshToken = generateRefreshToken(idpId);
return new TokenResponse(accessToken, refreshToken);
}

private Jws<Claims> getJws(String token) {
try {
return Jwts.parserBuilder().setSigningKey(getSecretKey()).build().parseClaimsJws(token);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@Getter
@Builder
public class CommentPairVo {
private Long id;
private LocalDateTime createdAt;
private String interviewerName;
private String content;
Expand All @@ -16,6 +17,7 @@ public class CommentPairVo {

public static CommentPairVo of(Comment comment, Boolean isLike, String interviewerName) {
return CommentPairVo.builder()
.id(comment.getId())
.createdAt(comment.getCreatedAt())
.content(comment.getContent())
.isLike(isLike)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.econovation.recruitcommon.annotation.Adaptor;
import com.econovation.recruitdomain.domains.interviewer.domain.Interviewer;
import com.econovation.recruitdomain.domains.interviewer.domain.InterviewerRepository;
import com.econovation.recruitdomain.domains.interviewer.exception.InterviewerNotFoundException;
import com.econovation.recruitdomain.out.InterviewerLoadPort;
import com.econovation.recruitdomain.out.InterviewerRecordPort;
import java.util.List;
Expand Down Expand Up @@ -32,6 +33,13 @@ public List<Interviewer> findAll() {
return interviewerRepository.findAll();
}

@Override
public Interviewer loadInterviewerByEmail(String email) {
return interviewerRepository
.findByEmail(email)
.orElseThrow(() -> InterviewerNotFoundException.EXCEPTION);
}

public List<Interviewer> saveAll(List<Interviewer> interviewer) {
return interviewerRepository.saveAll(interviewer);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
@Getter
public class Interviewer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "idp_id")
private Long id;

Expand All @@ -33,6 +34,11 @@ public class Interviewer {
@Column(name = "role")
private Role role;

@PrePersist
public void prePersist() {
this.role = Role.ROLE_TF;
}

public void updateRole(Role role) {
this.role = role;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.econovation.recruitdomain.domains.interviewer.domain;

import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface InterviewerRepository extends JpaRepository<Interviewer, Long> {}
public interface InterviewerRepository extends JpaRepository<Interviewer, Long> {
Optional<Interviewer> findByEmail(String email);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public enum InterviewerErrorCode implements BaseErrorCode {
INTERVIEWER_IDP_SERVER(FORBIDDEN, "INTERVIEWER_400_3", "Idp가 정상 동작하지 않습니다."),
INTERVIEWER_INVALID_ROLE(BAD_REQUEST, "INTERVIEWER_400_4", "유효하지 않은 Role 을 입력했습니다."),
INVALID_PASSWORD(BAD_REQUEST, "INTERVIEWER_400_5", "유효하지 않은 비밀번호입니다."),
INTERVIEWER_NOT_MATCH(NOT_FOUND, "INTERVIEWER_400_6", "등록되지 않은 이메일과 비밀번호로 로그인을 시도했습니다."),
;
private Integer status;
private String code;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.econovation.recruitdomain.domains.interviewer.exception;

import com.econovation.recruitcommon.exception.RecruitCodeException;

public class InterviewerNotMatchException extends RecruitCodeException {
public static final RecruitCodeException EXCEPTION = new InterviewerNotMatchException();

private InterviewerNotMatchException() {
super(InterviewerErrorCode.INTERVIEWER_NOT_MATCH);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ public interface InterviewerLoadPort {
List<Interviewer> loadInterviewerByIdpIds(List<Long> idpIds);

List<Interviewer> findAll();

Interviewer loadInterviewerByEmail(String email);
}
5 changes: 1 addition & 4 deletions server/Recruit-Domain/src/main/resources/init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,4 @@ INSERT INTO navigation (navigation_id, created_at, updated_at, title) VALUES (4,
INSERT INTO navigation (navigation_id, created_at, updated_at, title) VALUES (5,NOW(),NOW(),"지원자 대응팀");
INSERT INTO navigation (navigation_id, created_at, updated_at, title) VALUES (6,NOW(),NOW(),"OT 담당팀");
INSERT INTO navigation (navigation_id, created_at, updated_at, title) VALUES (7,NOW(),NOW(),"기타 참고");
INSERT INTO interviewer (idp_id, name, role, year) VALUES (0,"이서현_관리자","ROLE_TF", 21);
INSERT INTO interviewer (idp_id, name, role, year) VALUES (1,"임채승","ROLE_TF", 22);
INSERT INTO interviewer (idp_id, name, role, year) VALUES (2,"강바다","ROLE_TF", 24);
INSERT INTO interviewer (idp_id, name, role, year) VALUES (3,"이도연","ROLE_PRESIDENT", 23);
INSERT INTO interviewer (idp_id, name, role, year, email, password) VALUES (0,"이서현_관리자","ROLE_TF", 21, "[email protected]","asldnwlq!@Tqwashg");

0 comments on commit 93541c2

Please sign in to comment.