Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
cad431a
Merge pull request #1 from kimhana11/hana
kimhana11 Jan 14, 2024
56c929a
Merge pull request #2 from kimhana11/hana
kimhana11 Jan 14, 2024
304b799
Merge pull request #3 from kimhana11/hana
kimhana11 Jan 19, 2024
bb0045d
Merge pull request #4 from kimhana11/hana
kimhana11 Jan 19, 2024
55a587f
Merge pull request #6 from kimhana11/main
kimhana11 Jan 21, 2024
ebc4066
Merge pull request #9 from kimhana11/main
kimhana11 Jan 24, 2024
453cbb1
Merge pull request #10 from kimhana11/main
kimhana11 Jan 25, 2024
4735443
Merge pull request #11 from kimhana11/main
kimhana11 Feb 4, 2024
69db48c
Merge pull request #12 from kimhana11/main
kimhana11 Feb 8, 2024
36417dc
Merge pull request #14 from kimhana11/main
kimhana11 Feb 22, 2024
2c4092b
Merge pull request #15 from kimhana11/main
kimhana11 Feb 24, 2024
981e61e
[Docs] 코드 통합
sitduk143 Feb 29, 2024
0161422
[fix] 403해결 토큰에서 문제 있는거같아서 수정중
sitduk143 Mar 1, 2024
82fc3b7
[fix] idchk 완
sitduk143 Mar 4, 2024
4524354
[fix] id체크 문자열 500에러 수정
sitduk143 Mar 8, 2024
6aed06c
[fix]토큰은 됐는데 연관관계가 ..
sitduk143 Mar 22, 2024
db2770d
.
sitduk143 Mar 27, 2024
2f3f612
postman으로 테스트 시 200
sitduk143 Mar 29, 2024
e8311c0
fin
sitduk143 Mar 29, 2024
ed92f4c
유저프로필 에러
jwj9127 Apr 3, 2024
c835f6b
모든 기능 총통합
jwj9127 Apr 11, 2024
b2e95d7
[[Feat] 학습용 입력값 추가
kimhana11 Apr 17, 2024
ca866bd
[ai 학습용 데이터 입력 추가
kimhana11 Apr 17, 2024
38bff1f
crawling update
kimhana11 Apr 18, 2024
f47fe77
crawling update
kimhana11 Apr 18, 2024
4ed625b
crawling update
kimhana11 Apr 18, 2024
f868b4f
Merge branch 'hana' of https://github.com/capstone-design-kim/Back-en…
kimhana11 Apr 18, 2024
346cb05
[Feat] Learning Data
kimhana11 Apr 18, 2024
b273345
[Feat]리뷰 작성 가능 ê¸기능 추가
kimhana11 Apr 23, 2024
b1c9ed1
[심사기간 리뷰 작성 가능
kimhana11 Apr 23, 2024
885cf30
[Feat] 심사 종료시 리뷰 작성 가능
kimhana11 Apr 23, 2024
d8e670b
[Fix] profile update 수정
kimhana11 Apr 30, 2024
242554d
[Fix] review 마감기한 수정
kimhana11 Apr 30, 2024
65c62c3
[Refactor] ProcessBuilder 적용
kimhana11 May 1, 2024
5e8feb8
[ã[Feat] ai 유저 추천 끝!
kimhana11 May 2, 2024
2a89d43
[Feat] 참여 신청한 공모전 id, title 조회
kimhana11 May 3, 2024
eb2eff9
자잘한 수정
jwj9127 May 4, 2024
7e1b2a0
뷰 플러스 오류 수정
jwj9127 May 4, 2024
e31f354
[Update] 그냥 이것저것 수정완
kimhana11 May 4, 2024
2c7a00d
Merge branch 'hana' of https://github.com/capstone-design-kim/Back-en…
kimhana11 May 4, 2024
9f73fd0
[Fix] 자잘한 실수랄까
kimhana11 May 4, 2024
34ad28f
[Feat] Room, Team 기능 통합
kimhana11 May 5, 2024
77e0e5d
[Feat] LastMessage 추가
kimhana11 May 5, 2024
17fd60e
[Feat] 유저 추천 리스트 추가
kimhana11 May 11, 2024
47e3f2f
자잘한 수정
kimhana11 May 11, 2024
cd759b6
[Fix] ai 매칭 에러 주성
kimhana11 May 11, 2024
c63bd12
[Fix] 쿼리 수정
kimhana11 May 13, 2024
8f230bb
[Fix] 쿼리 수정
kimhana11 May 16, 2024
3adafd5
소켓 조금 수정
jwj9127 May 24, 2024
54db5de
응원 소켓 완
jwj9127 May 24, 2024
614cc0d
git 충돌
kimhana11 May 25, 2024
cd1b61c
git 충돌
kimhana11 May 25, 2024
e56f91f
[Feat] 프로필 조회시 userName 추가
kimhana11 May 25, 2024
dbbe1b5
[Fix] 프로필 조회 수정
kimhana11 May 29, 2024
3a8a45c
[Fix] 채팅 전송시 userName으로 전송
kimhana11 May 29, 2024
1ae81d3
[Feat] 기본 데이터 코드 추가
kimhana11 May 31, 2024
d6c0d4a
[ãRefactor] 리뷰 작성 제한 해제
kimhana11 Jun 2, 2024
5c35c08
[Feat] MessageDto 추가
kimhana11 Jun 2, 2024
0cabc4e
[Refactor] 구조 변경
kimhana11 Jun 3, 2024
e9f3e89
[Feat] 기본 데이터 추가
kimhana11 Jun 9, 2024
dca9d52
Merge pull request #19 from kimhana11/hana
kimhana11 Jun 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions 1_16.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"rank": 1, "user_id": 47}, {"rank": 2, "user_id": 43}]
1 change: 1 addition & 0 deletions 2_2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"rank": 1, "user_id": 83}]
1 change: 1 addition & 0 deletions 2_7.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"rank": 1, "user_id": 83}]
1 change: 1 addition & 0 deletions 2_8.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"rank": 1, "user_id": 83}, {"rank": 2, "user_id": 21}]
1 change: 1 addition & 0 deletions 3_2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"rank": 1, "user_id": 84}, {"rank": 2, "user_id": 18}, {"rank": 3, "user_id": 22}, {"rank": 4, "user_id": 49}]
1 change: 1 addition & 0 deletions 3_7.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"rank": 1, "user_id": 84}, {"rank": 2, "user_id": 18}, {"rank": 3, "user_id": 49}]
1 change: 1 addition & 0 deletions 4_13.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"rank": 1, "user_id": 19}]
1 change: 1 addition & 0 deletions 4_8.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"rank": 1, "user_id": 19}]
1 change: 1 addition & 0 deletions 6_8.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"rank": 1, "user_id": 87}]
19 changes: 19 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,33 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
implementation 'mysql:mysql-connector-java:8.0.23'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'

implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
testAnnotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.projectlombok:lombok'

annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'com.googlecode.json-simple:json-simple:1.1.1'
//웹소켓
implementation 'org.springframework.boot:spring-boot-starter-websocket'

implementation 'org.modelmapper:modelmapper:3.1.0'

//파일 읽기
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.2'
implementation 'org.apache.poi:poi-ooxml:5.2.3'


}

tasks.named('test') {
Expand Down
2 changes: 1 addition & 1 deletion contestkorea_contest_data.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/main/java/com/example/capd/CapDApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class CapDApplication {

public static void main(String[] args) {
SpringApplication.run(CapDApplication.class, args);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.example.capd.Exception;

public class ReviewSubmissionPeriodNotEndedException extends RuntimeException {
public ReviewSubmissionPeriodNotEndedException(){
super("심사 기간이 끝나지 않아 리뷰를 작성할 수 없습니다.");
}
public ReviewSubmissionPeriodNotEndedException(int n){
super("접수 기간이 끝나지 않아 리뷰를 작성할 수 없습니다.");
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ public class UserWithDesiredStackNotFoundException extends RuntimeException{
public UserWithDesiredStackNotFoundException() {
super("원하는 스택을 가지고 있는 유저가 존재하지 않습니다.");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.example.capd.User.JWT;

import jakarta.servlet.http.HttpServletRequest;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Component;

import java.util.Enumeration;

//헤더에서 토큰 추출하기
@Component
public class AuthorizationExtractor {
public static final String AUTHORIZATION = "AAuthorization";
public static final String ACCESS_TOKEN_TYPE = AuthorizationExtractor.class.getSimpleName() + ".ACCESS_TOKEN_TYPE";

public String extract(HttpServletRequest request, String type) {
Enumeration<String> headers = request.getHeaders(AUTHORIZATION);
while (headers.hasMoreElements()) {
String value = headers.nextElement();
if (value.toLowerCase().startsWith(type.toLowerCase())) {
return value.substring(type.length()).trim();
}
}

return Strings.EMPTY;
}
}
36 changes: 36 additions & 0 deletions src/main/java/com/example/capd/User/JWT/BearerAuthInterceptor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//package com.example.capd.User.JWT;
//
//import jakarta.servlet.http.HttpServletRequest;
//import jakarta.servlet.http.HttpServletResponse;
//import org.springframework.stereotype.Component;
//import org.springframework.util.StringUtils;
//import org.springframework.web.servlet.HandlerInterceptor;
//
//@Component
//public class BearerAuthInterceptor implements HandlerInterceptor {
// private AuthorizationExtractor authExtractor;
// private TokenProvider jwtTokenProvider;
//
// public BearerAuthInterceptor(AuthorizationExtractor authExtractor, TokenProvider jwtTokenProvider) {
// this.authExtractor = authExtractor;
// this.jwtTokenProvider = jwtTokenProvider;
// }
//
// @Override
// public boolean preHandle(HttpServletRequest request,
// HttpServletResponse response, Object handler) {
// System.out.println(">>> interceptor.preHandle 호출");
// String token = authExtractor.extract(request, "Bearer");
// if (StringUtils.isEmpty(token)) {
// return true;
// }
//
// if (!jwtTokenProvider.validateToken(token)) {
// throw new IllegalArgumentException("유효하지 않은 토큰");
// }
//
// String name = jwtTokenProvider.getUsername(token);
// request.setAttribute("name", name);
// return true;
// }
//}
52 changes: 52 additions & 0 deletions src/main/java/com/example/capd/User/JWT/JwtAuthFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.example.capd.User.JWT;

import com.example.capd.User.service.CustomUserDetailsService;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

@RequiredArgsConstructor
public class JwtAuthFilter extends OncePerRequestFilter { // OncePerRequestFilter -> 한 번 실행 보장

private final CustomUserDetailsService customUserDetailsService;
private final JwtUtil jwtUtil;

@Override
/**
* JWT 토큰 검증 필터 수행
*/
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String authorizationHeader = request.getHeader("Authorization");

//JWT가 헤더에 있는 경우
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
String token = authorizationHeader.substring(7);
//JWT 유효성 검증
if (jwtUtil.validateToken(token)) {
Long userId = jwtUtil.getId(token);

//유저와 토큰 일치 시 userDetails 생성
UserDetails userDetails = customUserDetailsService.loadUserByUsername(userId.toString());

if (userDetails != null) {
//UserDetsils, Password, Role -> 접근권한 인증 Token 생성
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());

//현재 Request의 Security Context에 접근권한 설정
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
}

filterChain.doFilter(request, response); // 다음 필터로 넘기기
}
}
110 changes: 110 additions & 0 deletions src/main/java/com/example/capd/User/JWT/JwtUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package com.example.capd.User.JWT;

import com.example.capd.User.dto.CustomUserInfoDto;
import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.security.Key;
import java.time.ZonedDateTime;
import java.util.Date;

@Slf4j
@Component
public class JwtUtil {
private final Key key;
private final long accessTokenExpTime;

public JwtUtil(
@Value("${jwt.secret}") String secretKey,
@Value("${jwt.expiration_time}") long accessTokenExpTime
) {
byte[] keyBytes = Decoders.BASE64.decode(secretKey);
this.key = Keys.hmacShaKeyFor(keyBytes);
this.accessTokenExpTime = accessTokenExpTime;
}


/**
* Access Token 생성
* @param user
* @return Access Token String
*/
public String createAccessToken(CustomUserInfoDto user) {
return createToken(user, accessTokenExpTime);
}


/**
* JWT 생성
* @param user
* @param expireTime
* @return JWT String
*/
private String createToken(CustomUserInfoDto user, long expireTime) {
Claims claims = Jwts.claims();
claims.put("Id", user.getId());
claims.put("email", user.getUserId());
claims.put("role", user.getRoles());

ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime tokenValidity = now.plusSeconds(expireTime);


return Jwts.builder()
.setClaims(claims)
.setIssuedAt(Date.from(now.toInstant()))
.setExpiration(Date.from(tokenValidity.toInstant()))
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}


/**
* Token에서 User ID 추출
* @param token
* @return User ID
*/
public Long getId(String token) {
return parseClaims(token).get("Id", Long.class);
}


/**
* JWT 검증
* @param token
* @return IsValidate
*/
public boolean validateToken(String token) {
try {
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);
return true;
} catch (io.jsonwebtoken.security.SecurityException | MalformedJwtException e) {
log.info("Invalid JWT Token", e);
} catch (ExpiredJwtException e) {
log.info("Expired JWT Token", e);
} catch (UnsupportedJwtException e) {
log.info("Unsupported JWT Token", e);
} catch (IllegalArgumentException e) {
log.info("JWT claims string is empty.", e);
}
return false;
}


/**
* JWT Claims 추출
* @param accessToken
* @return JWT Claims
*/
public Claims parseClaims(String accessToken) {
try {
return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(accessToken).getBody();
} catch (ExpiredJwtException e) {
return e.getClaims();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//package com.example.capd.User.JWT;
//
//import jakarta.servlet.*;
//import jakarta.servlet.http.HttpServletRequest;
//import jakarta.servlet.http.HttpServletResponse;
//import lombok.RequiredArgsConstructor;
//import org.springframework.context.annotation.DependsOn;
//import org.springframework.security.core.Authentication;
//import org.springframework.security.core.context.SecurityContextHolder;
//import org.springframework.stereotype.Component;
//import org.springframework.util.StringUtils;
//import org.springframework.web.filter.GenericFilterBean;
//import org.springframework.web.filter.OncePerRequestFilter;
//
//import java.io.IOException;
//
//public class TokenAuthenticationFilter extends OncePerRequestFilter {
//
// private final TokenProvider tokenProvider;
//
// public TokenAuthenticationFilter(TokenProvider tokenProvider) {
// this.tokenProvider = tokenProvider;
// }
//
////
//
// @Override
// protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// String token = tokenProvider.resolveToken(request);
//
// if (token != null && tokenProvider.validateToken(token)) {
// // check access token
// token = token.split(" ")[1].trim();
// Authentication auth = tokenProvider.getAuthentication(token);
// SecurityContextHolder.getContext().setAuthentication(auth);
// }
//
// filterChain.doFilter(request, response);
// }
//
//}
//
//// private String getAccessToken(String authorizationHeader) {
//// if (authorizationHeader != null && authorizationHeader.startsWith(TOKEN_PREFIX)) {
//// return authorizationHeader.substring(TOKEN_PREFIX.length());
//// }
//// return null;
//// }
//
//// Request Header 에서 토큰 정보를 꺼내오기 위한 메소드
//// private String resolveToken(HttpServletRequest request) {
//// String bearerToken = request.getHeader(HEADER_AUTHORIZATION);
////
//// if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
//// return bearerToken.substring(7);
//// }
////
//// return null;
//// }
Loading