From ce4c6a1c8da137d09ec700f02864c404a4cf0a4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=A0=95=EB=AF=BC?= Date: Tue, 30 Jul 2024 17:35:37 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20refresh=20token=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/UserController.java | 10 ++ .../exception/ExpriedTokenException.java | 11 ++ .../exception/GlobalExceptionHandler.java | 27 +++++ .../exception/InvalidTokenException.java | 7 ++ .../edufocus/edufocus/user/util/JWTUtil.java | 44 ++++--- .../edufocus/video/controller/Controller.java | 108 ++++++++++++------ 6 files changed, 156 insertions(+), 51 deletions(-) create mode 100644 backend/src/main/java/com/edufocus/edufocus/user/model/exception/ExpriedTokenException.java create mode 100644 backend/src/main/java/com/edufocus/edufocus/user/model/exception/GlobalExceptionHandler.java create mode 100644 backend/src/main/java/com/edufocus/edufocus/user/model/exception/InvalidTokenException.java diff --git a/backend/src/main/java/com/edufocus/edufocus/user/controller/UserController.java b/backend/src/main/java/com/edufocus/edufocus/user/controller/UserController.java index b4bff53..6526a03 100644 --- a/backend/src/main/java/com/edufocus/edufocus/user/controller/UserController.java +++ b/backend/src/main/java/com/edufocus/edufocus/user/controller/UserController.java @@ -3,6 +3,8 @@ package com.edufocus.edufocus.user.controller; import com.edufocus.edufocus.user.model.entity.InfoDto; import com.edufocus.edufocus.user.model.entity.PasswordDto; import com.edufocus.edufocus.user.model.entity.User; +import com.edufocus.edufocus.user.model.exception.ExpriedTokenException; +import com.edufocus.edufocus.user.model.exception.UnAuthorizedException; import com.edufocus.edufocus.user.model.service.UserService; import com.edufocus.edufocus.user.util.JWTUtil; import io.swagger.v3.oas.annotations.Operation; @@ -258,7 +260,15 @@ public class UserController { } + @ExceptionHandler(ExpriedTokenException.class) + public ResponseEntity handleExpiredTokenException(){ + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } + @ExceptionHandler(UnAuthorizedException.class) + public ResponseEntity handleUnauthorizedException(){ + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } diff --git a/backend/src/main/java/com/edufocus/edufocus/user/model/exception/ExpriedTokenException.java b/backend/src/main/java/com/edufocus/edufocus/user/model/exception/ExpriedTokenException.java new file mode 100644 index 0000000..e816b32 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/user/model/exception/ExpriedTokenException.java @@ -0,0 +1,11 @@ +package com.edufocus.edufocus.user.model.exception; + +public class ExpriedTokenException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public ExpriedTokenException() { + super("계정 권한이 유효하지 않습니다.\n다시 로그인을 하세요."); + } + +} diff --git a/backend/src/main/java/com/edufocus/edufocus/user/model/exception/GlobalExceptionHandler.java b/backend/src/main/java/com/edufocus/edufocus/user/model/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..526e6ae --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/user/model/exception/GlobalExceptionHandler.java @@ -0,0 +1,27 @@ +package com.edufocus.edufocus.user.model.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(UnAuthorizedException.class) + public ResponseEntity handleUnAuthorizedException(UnAuthorizedException e) { + + + + return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); + } + + + @ExceptionHandler(ExpriedTokenException.class) + public ResponseEntity handleInvalidTokenException(ExpriedTokenException e) { + // 로그 남기기 (선택 사항) + // log.error("Invalid token", e); + + return new ResponseEntity<>(e.getMessage(), HttpStatus.UNAUTHORIZED); + } +} diff --git a/backend/src/main/java/com/edufocus/edufocus/user/model/exception/InvalidTokenException.java b/backend/src/main/java/com/edufocus/edufocus/user/model/exception/InvalidTokenException.java new file mode 100644 index 0000000..74969f3 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/user/model/exception/InvalidTokenException.java @@ -0,0 +1,7 @@ +package com.edufocus.edufocus.user.model.exception; + +public class InvalidTokenException extends RuntimeException { + public InvalidTokenException() { + super("Token is invalid"); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/edufocus/edufocus/user/util/JWTUtil.java b/backend/src/main/java/com/edufocus/edufocus/user/util/JWTUtil.java index ead01db..ffce34c 100644 --- a/backend/src/main/java/com/edufocus/edufocus/user/util/JWTUtil.java +++ b/backend/src/main/java/com/edufocus/edufocus/user/util/JWTUtil.java @@ -4,6 +4,8 @@ import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.Map; +import com.edufocus.edufocus.user.model.exception.ExpriedTokenException; +import com.edufocus.edufocus.user.model.exception.InvalidTokenException; import com.edufocus.edufocus.user.model.exception.UnAuthorizedException; import io.jsonwebtoken.*; import org.springframework.beans.factory.annotation.Value; @@ -52,19 +54,27 @@ public class JWTUtil { public boolean checkToken(String token) { try { - Jws claims = Jwts.parserBuilder() - .setSigningKey(generateKey()) - .build() - .parseClaimsJws(token); - log.debug("claims: {}", claims); - return true; - } catch (MalformedJwtException | UnsupportedJwtException | IllegalArgumentException | SignatureException | ExpiredJwtException e) { - log.error("Token validation error: {}", e.getMessage()); - return false; - } catch (Exception e) { - System.out.println(token); - log.error("Unexpected error while validating token: {}", e.getMessage()); - return false; + Jws claims = Jwts.parserBuilder() + .setSigningKey(generateKey()) + .build() + .parseClaimsJws(token); + log.debug("claims: {}", claims); + return true; + } catch (MalformedJwtException | UnsupportedJwtException | IllegalArgumentException | SignatureException e) { + log.error("Token validation error: {}", e.getMessage()); + + return false; + } + catch ( ExpiredJwtException e) + { + throw new ExpriedTokenException(); + + } + catch (Exception e) { + System.out.println(token); + System.out.println(e.getMessage()); + log.error("Unexpected error while validating token: {}", e.getMessage()); + return false; } } @@ -77,7 +87,13 @@ public class JWTUtil { Map value = claims.getBody(); log.info("value : {}", value); return (String) value.get("id"); - } catch (Exception e) { + }catch ( ExpiredJwtException e) + { + System.out.println("expired token"); + throw new ExpriedTokenException(); + + } + catch (Exception e) { log.error("Failed to get user ID from token: {}", e.getMessage()); throw new UnAuthorizedException(); } diff --git a/backend/src/main/java/com/edufocus/edufocus/video/controller/Controller.java b/backend/src/main/java/com/edufocus/edufocus/video/controller/Controller.java index c4fa32c..40b206a 100644 --- a/backend/src/main/java/com/edufocus/edufocus/video/controller/Controller.java +++ b/backend/src/main/java/com/edufocus/edufocus/video/controller/Controller.java @@ -7,6 +7,9 @@ import com.edufocus.edufocus.lecture.entity.LectureDetailResponse; import com.edufocus.edufocus.lecture.service.LectureService; import com.edufocus.edufocus.registration.entity.RegistrationStatus; import com.edufocus.edufocus.registration.service.RegistrationService; +import com.edufocus.edufocus.user.model.entity.User; +import com.edufocus.edufocus.user.model.entity.UserRole; +import com.edufocus.edufocus.user.model.repository.UserRepository; import com.edufocus.edufocus.user.model.service.UserService; import com.edufocus.edufocus.user.util.JWTUtil; import com.edufocus.edufocus.video.service.VideoSertvice; @@ -33,6 +36,7 @@ public class Controller { private final LectureService lectureService; private final VideoSertvice videoSertvice; private final RegistrationService registrationService; + private final UserRepository userRepository; @Value("${livekit.api.key}") private String LIVEKIT_API_KEY; @@ -70,39 +74,13 @@ public class Controller { Long userId = Long.parseLong(jwtUtil.getUserId(userToken)); - LectureDetailResponse lecture= lectureService.findLectureById(userId,id); - - String roomName = lecture.getTitle(); - String participantName = userService.getUserName(userId); + User findUser= userRepository.findById(userId).orElse(null); - AccessToken token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET); - token.setName(participantName); - token.setIdentity(participantName); - token.addGrants(new RoomJoin(true), new RoomName(roomName),new RoomCreate(true)); - - videoSertvice.startOnline(userId,id); + if(findUser.getRole()==UserRole.ADMIN) { + LectureDetailResponse lecture = lectureService.findLectureById(userId, id); - - - return ResponseEntity.ok(Map.of("token", token.toJwt())); - } - - - @PostMapping(value = "/joinroom/{lecture_id}") - public ResponseEntity> joinRoom(@PathVariable("lecture_id") Long id, HttpServletRequest request) throws Exception { - - String userToken = request.getHeader("Authorization"); - - Long userId = Long.parseLong(jwtUtil.getUserId(userToken)); - LectureDetailResponse lecture= lectureService.findLectureById(userId,id); - - - //RegistrationStatus registrationStatus = registrationService.isOnline(userId,id); - -// if(registrationStatus==RegistrationStatus.ACCEPTED) -// { String roomName = lecture.getTitle(); String participantName = userService.getUserName(userId); @@ -110,23 +88,79 @@ public class Controller { AccessToken token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET); token.setName(participantName); token.setIdentity(participantName); - token.addGrants(new RoomJoin(true), new RoomName(roomName)); - - //videoSertvice.startOnline(userId,id); + token.addGrants(new RoomJoin(true), new RoomName(roomName), new RoomCreate(true)); + videoSertvice.startOnline(userId, id); return ResponseEntity.ok(Map.of("token", token.toJwt())); -// } -// else{ -// return ResponseEntity.status(HttpStatus.FORBIDDEN).body(Map.of("errorMessage", "Not accepted")); -// -// } + + } + else if(findUser.getRole()==UserRole.STUDENT) + { + LectureDetailResponse lecture = lectureService.findLectureById(userId, id); + + + String roomName = lecture.getTitle(); + String participantName = userService.getUserName(userId); + + + AccessToken token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET); + token.setName(participantName); + token.setIdentity(participantName); + token.addGrants(new RoomJoin(true), new RoomName(roomName), new RoomCreate(true)); + + videoSertvice.startOnline(userId, id); + + + return ResponseEntity.ok(Map.of("token", token.toJwt())); + } + + + return ResponseEntity.ok(Map.of("token", null)); } + +// @PostMapping(value = "/joinroom/{lecture_id}") +// public ResponseEntity> joinRoom(@PathVariable("lecture_id") Long id, HttpServletRequest request) throws Exception { +// +//// String userToken = request.getHeader("Authorization"); +//// +//// Long userId = Long.parseLong(jwtUtil.getUserId(userToken)); +//// LectureDetailResponse lecture= lectureService.findLectureById(userId,id); +//// +//// +//// //RegistrationStatus registrationStatus = registrationService.isOnline(userId,id); +//// +////// if(registrationStatus==RegistrationStatus.ACCEPTED) +////// { +//// String roomName = lecture.getTitle(); +//// String participantName = userService.getUserName(userId); +//// +//// +//// AccessToken token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET); +//// token.setName(participantName); +//// token.setIdentity(participantName); +//// token.addGrants(new RoomJoin(true), new RoomName(roomName)); +//// +//// //videoSertvice.startOnline(userId,id); +//// +//// +//// +//// return ResponseEntity.ok(Map.of("token", token.toJwt())); +////// } +////// else{ +////// return ResponseEntity.status(HttpStatus.FORBIDDEN).body(Map.of("errorMessage", "Not accepted")); +////// +////// } +//// +// +// +// } + @PostMapping(value = "/livekit/webhook", consumes = "application/webhook+json") public ResponseEntity receiveWebhook(@RequestHeader("Authorization") String authHeader, @RequestBody String body) { WebhookReceiver webhookReceiver = new WebhookReceiver(LIVEKIT_API_KEY, LIVEKIT_API_SECRET); From f813e55733486d0617470d3be51afe8af2173eb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=A0=95=EB=AF=BC?= Date: Wed, 31 Jul 2024 10:37:40 +0900 Subject: [PATCH 2/3] BE/userinfo --- .../lecture/service/LectureService.java | 1 + .../lecture/service/LectureServiceImpl.java | 8 ++ .../exception/GlobalExceptionHandler.java | 2 - .../edufocus/video/controller/Controller.java | 103 ++++++++++-------- 4 files changed, 67 insertions(+), 47 deletions(-) diff --git a/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureService.java b/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureService.java index 65153a0..e8483d4 100644 --- a/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureService.java +++ b/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureService.java @@ -28,4 +28,5 @@ public interface LectureService { Lecture findLectureByTitle(String title); void changeState(Long lectureId); + boolean getState(Long lectureId); } diff --git a/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureServiceImpl.java b/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureServiceImpl.java index 90da51c..e770f55 100644 --- a/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureServiceImpl.java +++ b/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureServiceImpl.java @@ -239,5 +239,13 @@ public class LectureServiceImpl implements LectureService { lectureRepository.save(l); } + @Override + public boolean getState(Long lectureId) { + + Lecture lecture= lectureRepository.findById(lectureId).orElse(null); + return lecture.isOnline(); + + } + } diff --git a/backend/src/main/java/com/edufocus/edufocus/user/model/exception/GlobalExceptionHandler.java b/backend/src/main/java/com/edufocus/edufocus/user/model/exception/GlobalExceptionHandler.java index 526e6ae..81042dc 100644 --- a/backend/src/main/java/com/edufocus/edufocus/user/model/exception/GlobalExceptionHandler.java +++ b/backend/src/main/java/com/edufocus/edufocus/user/model/exception/GlobalExceptionHandler.java @@ -19,8 +19,6 @@ public class GlobalExceptionHandler { @ExceptionHandler(ExpriedTokenException.class) public ResponseEntity handleInvalidTokenException(ExpriedTokenException e) { - // 로그 남기기 (선택 사항) - // log.error("Invalid token", e); return new ResponseEntity<>(e.getMessage(), HttpStatus.UNAUTHORIZED); } diff --git a/backend/src/main/java/com/edufocus/edufocus/video/controller/Controller.java b/backend/src/main/java/com/edufocus/edufocus/video/controller/Controller.java index 40b206a..1fe7492 100644 --- a/backend/src/main/java/com/edufocus/edufocus/video/controller/Controller.java +++ b/backend/src/main/java/com/edufocus/edufocus/video/controller/Controller.java @@ -4,6 +4,7 @@ import java.util.Map; import com.edufocus.edufocus.lecture.entity.Lecture; import com.edufocus.edufocus.lecture.entity.LectureDetailResponse; +import com.edufocus.edufocus.lecture.repository.LectureRepository; import com.edufocus.edufocus.lecture.service.LectureService; import com.edufocus.edufocus.registration.entity.RegistrationStatus; import com.edufocus.edufocus.registration.service.RegistrationService; @@ -37,6 +38,7 @@ public class Controller { private final VideoSertvice videoSertvice; private final RegistrationService registrationService; private final UserRepository userRepository; + private final LectureRepository lectureRepository; @Value("${livekit.api.key}") private String LIVEKIT_API_KEY; @@ -67,18 +69,37 @@ public class Controller { // } @PostMapping(value = "/makeroom/{lecture_id}") - public ResponseEntity> startLecture(@PathVariable("lecture_id") Long id, HttpServletRequest request) throws Exception { + public ResponseEntity startLecture(@PathVariable("lecture_id") Long id, HttpServletRequest request) throws Exception { + + + String userToken = request.getHeader("Authorization"); + Long userId = Long.parseLong(jwtUtil.getUserId(userToken)); + + + videoSertvice.startOnline(userId, id); + + return new ResponseEntity<>("방만들기 성공",HttpStatus.OK); + + } + + + @PostMapping(value = "/joinroom/{lecture_id}") + public ResponseEntity> joinRoom(@PathVariable("lecture_id") Long id, HttpServletRequest request) throws Exception + { String userToken = request.getHeader("Authorization"); - log.info("userToekn : ", userToken); Long userId = Long.parseLong(jwtUtil.getUserId(userToken)); User findUser= userRepository.findById(userId).orElse(null); + Lecture lecture= lectureRepository.findById(id).orElse(null); - if(findUser.getRole()==UserRole.ADMIN) { - LectureDetailResponse lecture = lectureService.findLectureById(userId, id); + + + + if(findUser.getRole()==UserRole.ADMIN && lecture.isOnline() ) { + String roomName = lecture.getTitle(); @@ -96,9 +117,8 @@ public class Controller { return ResponseEntity.ok(Map.of("token", token.toJwt())); } - else if(findUser.getRole()==UserRole.STUDENT) + else if(findUser.getRole()==UserRole.STUDENT && lecture.isOnline() ) { - LectureDetailResponse lecture = lectureService.findLectureById(userId, id); String roomName = lecture.getTitle(); @@ -108,7 +128,8 @@ public class Controller { AccessToken token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET); token.setName(participantName); token.setIdentity(participantName); - token.addGrants(new RoomJoin(true), new RoomName(roomName), new RoomCreate(true)); + token.addGrants(new RoomJoin(true), new RoomName(roomName)); + videoSertvice.startOnline(userId, id); @@ -119,48 +140,40 @@ public class Controller { return ResponseEntity.ok(Map.of("token", null)); +// String userToken = request.getHeader("Authorization"); +// +// Long userId = Long.parseLong(jwtUtil.getUserId(userToken)); +// LectureDetailResponse lecture= lectureService.findLectureById(userId,id); +// +// +// //RegistrationStatus registrationStatus = registrationService.isOnline(userId,id); +// +// if(registrationStatus==RegistrationStatus.ACCEPTED) +// { +// String roomName = lecture.getTitle(); +// String participantName = userService.getUserName(userId); +// +// +// AccessToken token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET); +// token.setName(participantName); +// token.setIdentity(participantName); +// token.addGrants(new RoomJoin(true), new RoomName(roomName)); +// +// //videoSertvice.startOnline(userId,id); +// +// +// +// return ResponseEntity.ok(Map.of("token", token.toJwt())); +// } +// else{ +// return ResponseEntity.status(HttpStatus.FORBIDDEN).body(Map.of("errorMessage", "Not accepted")); +// +// } + } - -// @PostMapping(value = "/joinroom/{lecture_id}") -// public ResponseEntity> joinRoom(@PathVariable("lecture_id") Long id, HttpServletRequest request) throws Exception { -// -//// String userToken = request.getHeader("Authorization"); -//// -//// Long userId = Long.parseLong(jwtUtil.getUserId(userToken)); -//// LectureDetailResponse lecture= lectureService.findLectureById(userId,id); -//// -//// -//// //RegistrationStatus registrationStatus = registrationService.isOnline(userId,id); -//// -////// if(registrationStatus==RegistrationStatus.ACCEPTED) -////// { -//// String roomName = lecture.getTitle(); -//// String participantName = userService.getUserName(userId); -//// -//// -//// AccessToken token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET); -//// token.setName(participantName); -//// token.setIdentity(participantName); -//// token.addGrants(new RoomJoin(true), new RoomName(roomName)); -//// -//// //videoSertvice.startOnline(userId,id); -//// -//// -//// -//// return ResponseEntity.ok(Map.of("token", token.toJwt())); -////// } -////// else{ -////// return ResponseEntity.status(HttpStatus.FORBIDDEN).body(Map.of("errorMessage", "Not accepted")); -////// -////// } -//// -// -// -// } - @PostMapping(value = "/livekit/webhook", consumes = "application/webhook+json") public ResponseEntity receiveWebhook(@RequestHeader("Authorization") String authHeader, @RequestBody String body) { WebhookReceiver webhookReceiver = new WebhookReceiver(LIVEKIT_API_KEY, LIVEKIT_API_SECRET); From 62dde35a66e1287426f69bf91f20fce4a6a34ccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=A0=95=EB=AF=BC?= Date: Wed, 31 Jul 2024 11:07:11 +0900 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20global=20exception=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../edufocus/user/model/exception/GlobalExceptionHandler.java | 4 ++-- .../main/java/com/edufocus/edufocus/user/util/JWTUtil.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/com/edufocus/edufocus/user/model/exception/GlobalExceptionHandler.java b/backend/src/main/java/com/edufocus/edufocus/user/model/exception/GlobalExceptionHandler.java index 81042dc..63355d3 100644 --- a/backend/src/main/java/com/edufocus/edufocus/user/model/exception/GlobalExceptionHandler.java +++ b/backend/src/main/java/com/edufocus/edufocus/user/model/exception/GlobalExceptionHandler.java @@ -8,8 +8,8 @@ import org.springframework.web.bind.annotation.ExceptionHandler; @ControllerAdvice public class GlobalExceptionHandler { - @ExceptionHandler(UnAuthorizedException.class) - public ResponseEntity handleUnAuthorizedException(UnAuthorizedException e) { + @ExceptionHandler(InvalidTokenException.class) + public ResponseEntity handleUnAuthorizedException(InvalidTokenException e) { diff --git a/backend/src/main/java/com/edufocus/edufocus/user/util/JWTUtil.java b/backend/src/main/java/com/edufocus/edufocus/user/util/JWTUtil.java index ffce34c..89f068f 100644 --- a/backend/src/main/java/com/edufocus/edufocus/user/util/JWTUtil.java +++ b/backend/src/main/java/com/edufocus/edufocus/user/util/JWTUtil.java @@ -95,7 +95,7 @@ public class JWTUtil { } catch (Exception e) { log.error("Failed to get user ID from token: {}", e.getMessage()); - throw new UnAuthorizedException(); + throw new InvalidTokenException(); } } }