Skip to content

Commit 8e3cfac

Browse files
authored
Merge branch 'dev' into feat/#38-1
2 parents 52651c0 + 1917f71 commit 8e3cfac

File tree

12 files changed

+138
-11
lines changed

12 files changed

+138
-11
lines changed

src/main/java/dmu/dasom/api/domain/applicant/dto/ApplicantCreateRequestDto.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package dmu.dasom.api.domain.applicant.dto;
22

3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import com.fasterxml.jackson.annotation.JsonSetter;
5+
import com.fasterxml.jackson.annotation.Nulls;
36
import dmu.dasom.api.domain.applicant.entity.Applicant;
47
import io.swagger.v3.oas.annotations.media.Schema;
58
import jakarta.validation.constraints.*;
@@ -9,6 +12,11 @@
912
@Schema(name = "ApplicantCreateRequestDto", description = "지원자 생성 요청 DTO")
1013
public class ApplicantCreateRequestDto {
1114

15+
@NotNull
16+
@Size(max = 16)
17+
@Schema(description = "이름", example = "홍길동")
18+
private String name;
19+
1220
@NotNull
1321
@Pattern(regexp = "^[0-9]{8}$")
1422
@Size(min = 8, max = 8)
@@ -39,15 +47,21 @@ public class ApplicantCreateRequestDto {
3947
private String reasonForApply;
4048

4149
@Size(max = 200)
42-
@Schema(description = "활동 희망사항", example = "동아리 활동 참여")
50+
@Schema(description = "활동 희망사항", example = "동아리 활동 참여", nullable = true)
4351
private String activityWish;
4452

4553
@NotNull
4654
@Schema(description = "개인정보 처리방침 동의 여부", example = "true")
4755
private Boolean isPrivacyPolicyAgreed;
4856

57+
@JsonProperty(defaultValue = "false")
58+
@JsonSetter(nulls = Nulls.SKIP)
59+
@Schema(description = "지원서 덮어쓰기 확인 여부", example = "false", defaultValue = "false", nullable = true)
60+
private Boolean isOverwriteConfirmed = false;
61+
4962
public Applicant toEntity() {
5063
return Applicant.builder()
64+
.name(this.name)
5165
.studentNo(this.studentNo)
5266
.contact(this.contact)
5367
.email(this.email)

src/main/java/dmu/dasom/api/domain/applicant/entity/Applicant.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dmu.dasom.api.domain.applicant.entity;
22

3+
import dmu.dasom.api.domain.applicant.dto.ApplicantCreateRequestDto;
34
import dmu.dasom.api.domain.applicant.dto.ApplicantDetailsResponseDto;
45
import dmu.dasom.api.domain.applicant.dto.ApplicantResponseDto;
56
import dmu.dasom.api.domain.applicant.enums.ApplicantStatus;
@@ -9,6 +10,7 @@
910
import lombok.Builder;
1011
import lombok.Getter;
1112
import lombok.NoArgsConstructor;
13+
import org.hibernate.annotations.DynamicUpdate;
1214
import org.springframework.data.annotation.CreatedDate;
1315
import org.springframework.data.annotation.LastModifiedDate;
1416
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@@ -17,6 +19,7 @@
1719

1820
@AllArgsConstructor
1921
@Builder
22+
@DynamicUpdate
2023
@Entity
2124
@EntityListeners(AuditingEntityListener.class)
2225
@Getter
@@ -32,7 +35,7 @@ public class Applicant {
3235
@Size(max = 16)
3336
private String name;
3437

35-
@Column(name = "student_no", nullable = false, length = 8)
38+
@Column(name = "student_no", nullable = false, unique = true, length = 8)
3639
@Pattern(regexp = "^[0-9]{8}$")
3740
@Size(min = 8, max = 8)
3841
private String studentNo;
@@ -105,4 +108,14 @@ public ApplicantDetailsResponseDto toApplicantDetailsResponse() {
105108
.build();
106109
}
107110

111+
public void overwrite(final ApplicantCreateRequestDto request) {
112+
this.name = request.getName();
113+
this.contact = request.getContact();
114+
this.email = request.getEmail();
115+
this.grade = request.getGrade();
116+
this.reasonForApply = request.getReasonForApply();
117+
this.activityWish = request.getActivityWish();
118+
this.isPrivacyPolicyAgreed = request.getIsPrivacyPolicyAgreed();
119+
}
120+
108121
}

src/main/java/dmu/dasom/api/domain/applicant/repository/ApplicantRepository.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@
66
import org.springframework.data.jpa.repository.JpaRepository;
77
import org.springframework.data.jpa.repository.Query;
88

9+
import java.util.Optional;
10+
911
public interface ApplicantRepository extends JpaRepository<Applicant, Long> {
1012

1113
@Query("SELECT a FROM Applicant a ORDER BY a.id DESC")
1214
Page<Applicant> findAllWithPageRequest(final Pageable pageable);
1315

16+
Optional<Applicant> findByStudentNo(final String studentNo);
17+
1418
}

src/main/java/dmu/dasom/api/domain/applicant/service/ApplicantServiceImpl.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@
1616
import org.springframework.data.domain.Page;
1717
import org.springframework.data.domain.PageRequest;
1818
import org.springframework.stereotype.Service;
19+
import org.springframework.transaction.annotation.Transactional;
20+
21+
import java.util.Optional;
1922

2023
import java.util.List;
2124

2225
@Slf4j
2326
@RequiredArgsConstructor
2427
@Service
28+
@Transactional
2529
public class ApplicantServiceImpl implements ApplicantService {
2630

2731
private final static int DEFAULT_PAGE_SIZE = 20;
@@ -32,6 +36,20 @@ public class ApplicantServiceImpl implements ApplicantService {
3236
// 지원자 저장
3337
@Override
3438
public void apply(final ApplicantCreateRequestDto request) {
39+
final Optional<Applicant> applicant = findByStudentNo(request.getStudentNo());
40+
41+
// 이미 지원한 학번이 존재할 경우
42+
if (applicant.isPresent()) {
43+
// 덮어쓰기 확인 여부가 false일 경우 예외 발생
44+
if (!request.getIsOverwriteConfirmed())
45+
throw new CustomException(ErrorCode.DUPLICATED_STUDENT_NO);
46+
47+
// 기존 지원자 정보 갱신 수행
48+
applicant.get().overwrite(request);
49+
return;
50+
}
51+
52+
// 새로운 지원자일 경우 저장
3553
applicantRepository.save(request.toEntity());
3654
}
3755

@@ -89,4 +107,9 @@ private Applicant findById(final Long id) {
89107
.orElseThrow(() -> new CustomException(ErrorCode.EMPTY_RESULT));
90108
}
91109

110+
// 학번으로 지원자 존재 여부 확인
111+
private Optional<Applicant> findByStudentNo(final String studentNo) {
112+
return applicantRepository.findByStudentNo(studentNo);
113+
}
114+
92115
}

src/main/java/dmu/dasom/api/domain/common/exception/ErrorCode.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ public enum ErrorCode {
1919
NOT_FOUND(404, "C010", "해당 리소스를 찾을 수 없습니다."),
2020
WRITE_FAIL(400, "C011", "데이터를 쓰는데 실패하였습니다."),
2121
EMPTY_RESULT(400, "C012", "조회 결과가 없습니다."),
22-
SEND_EMAIL_FAIL(400, "C014", "이메일 전송에 실패하였습니다."),
22+
DUPLICATED_STUDENT_NO(400, "C013", "이미 등록된 학번입니다."),
23+
SEND_EMAIL_FAIL(400, "C014", "이메일 전송에 실패하였습니다.")
2324
;
2425

2526
private final int status;

src/main/java/dmu/dasom/api/domain/member/controller/MemberController.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public ResponseEntity<Void> tokenRotation(@AuthenticationPrincipal final UserDet
6464
final HttpHeaders headers = new HttpHeaders();
6565
headers.add("Access-Token", tokenBox.getAccessToken());
6666
headers.add("Refresh-Token", tokenBox.getRefreshToken());
67+
headers.add("Authority", tokenBox.getAuthority());
6768

6869
return ResponseEntity.ok().headers(headers).build();
6970
}

src/main/java/dmu/dasom/api/domain/member/service/MemberServiceImpl.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@
99
import dmu.dasom.api.global.auth.jwt.JwtUtil;
1010
import dmu.dasom.api.global.auth.userdetails.UserDetailsImpl;
1111
import lombok.RequiredArgsConstructor;
12+
import org.springframework.security.core.GrantedAuthority;
1213
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
1314
import org.springframework.stereotype.Service;
1415
import org.springframework.transaction.annotation.Transactional;
1516

17+
import java.util.Collection;
18+
import java.util.Iterator;
19+
1620
@RequiredArgsConstructor
1721
@Service
1822
@Transactional(readOnly = true)
@@ -49,7 +53,13 @@ public void signUp(final SignupRequestDto request) {
4953
// 토큰 갱신
5054
@Override
5155
public TokenBox tokenRotation(final UserDetailsImpl userDetails) {
52-
return jwtUtil.tokenRotation(userDetails);
56+
final Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();
57+
final Iterator<? extends GrantedAuthority> iterator = authorities.iterator();
58+
final GrantedAuthority auth = iterator.next();
59+
60+
final String authority = auth.getAuthority();
61+
62+
return jwtUtil.tokenRotation(userDetails.getUsername(), authority);
5363
}
5464

5565
}

src/main/java/dmu/dasom/api/domain/recruit/controller/RecruitController.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
import dmu.dasom.api.domain.applicant.dto.ApplicantCreateRequestDto;
44
import dmu.dasom.api.domain.applicant.service.ApplicantService;
5+
import dmu.dasom.api.domain.common.exception.ErrorResponse;
56
import io.swagger.v3.oas.annotations.Operation;
7+
import io.swagger.v3.oas.annotations.media.Content;
8+
import io.swagger.v3.oas.annotations.media.ExampleObject;
9+
import io.swagger.v3.oas.annotations.media.Schema;
610
import io.swagger.v3.oas.annotations.responses.ApiResponse;
711
import io.swagger.v3.oas.annotations.responses.ApiResponses;
812
import jakarta.validation.Valid;
@@ -23,8 +27,15 @@ public class RecruitController {
2327
// 지원하기
2428
@Operation(summary = "부원 지원하기")
2529
@ApiResponses(value = {
26-
@ApiResponse(responseCode = "200", description = "지원 성공")
27-
})
30+
@ApiResponse(responseCode = "200", description = "지원 성공"),
31+
@ApiResponse(responseCode = "400", description = "실패 케이스",
32+
content = @Content(
33+
mediaType = "application/json",
34+
schema = @Schema(implementation = ErrorResponse.class),
35+
examples = {
36+
@ExampleObject(
37+
name = "학번 중복",
38+
value = "{ \"code\": \"C013\", \"message\": \"이미 등록된 학번입니다.\" }")}))})
2839
@PostMapping("/apply")
2940
public ResponseEntity<Void> apply(@Valid @RequestBody final ApplicantCreateRequestDto request) {
3041
applicantService.apply(request);

src/main/java/dmu/dasom/api/global/auth/dto/TokenBox.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,8 @@ public class TokenBox {
1919
@NotNull
2020
private String refreshToken;
2121

22+
@Schema(description = "권한")
23+
@NotNull
24+
private String authority;
25+
2226
}

src/main/java/dmu/dasom/api/global/auth/filter/CustomAuthenticationFilter.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
1818
import org.springframework.security.core.Authentication;
1919
import org.springframework.security.core.AuthenticationException;
20+
import org.springframework.security.core.GrantedAuthority;
2021
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
2122

2223
import java.io.IOException;
24+
import java.util.Collection;
25+
import java.util.Iterator;
2326

2427
@RequiredArgsConstructor
2528
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@@ -47,12 +50,19 @@ protected void successfulAuthentication(final HttpServletRequest request, final
4750
// 기존 토큰 만료 처리
4851
jwtUtil.blacklistTokens(authResult.getName());
4952

53+
final Collection<? extends GrantedAuthority> authorities = authResult.getAuthorities();
54+
final Iterator<? extends GrantedAuthority> iterator = authorities.iterator();
55+
final GrantedAuthority auth = iterator.next();
56+
57+
final String authority = auth.getAuthority();
58+
5059
// 토큰 생성
51-
final TokenBox tokenBox = jwtUtil.generateTokenBox(authResult.getName());
60+
final TokenBox tokenBox = jwtUtil.generateTokenBox(authResult.getName(), authority);
5261

5362
response.setStatus(HttpStatus.OK.value());
5463
response.setHeader("Access-Token", tokenBox.getAccessToken());
5564
response.setHeader("Refresh-Token", tokenBox.getRefreshToken());
65+
response.setHeader("Authority", tokenBox.getAuthority());
5666
}
5767

5868
@Override

0 commit comments

Comments
 (0)