Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
)
.authorizeHttpRequests(authorizeRequests -> authorizeRequests
.requestMatchers(
"/api/auth/epicgames/callback", // 토큰 호출 부분
"/login",
"/**",
"/v3/api-docs/**", // Swagger API Docs 경로
"/swagger-ui/**", // Swagger UI 정적 리소스 경로
"/swagger-ui.html", // Swagger UI 페이지 경로
Expand All @@ -64,23 +63,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
).permitAll() // Swagger 관련 경로 허용
.anyRequest().authenticated()
)

// oauth2Login 설정이 다른 경로에서만 작동하도록 설정
.oauth2Login(oauth2Login -> oauth2Login
.loginPage("/login")
.defaultSuccessUrl("/", true)
.failureUrl("/login?error=true")
.userInfoEndpoint(userInfoEndpoint -> userInfoEndpoint
.userService(oauth2UserService())
)
.successHandler(oauth2AuthenticationSuccessHandler())
)
// .logout(logout -> logout
// .logoutUrl("/logout")
// .addLogoutHandler(logoutHandler())
// .logoutSuccessUrl("/")
// )
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); // JWT 필터 추가

return http.build();
}
Expand All @@ -90,52 +73,4 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
// "index.html"로 서블릿 포워딩 되면서 시큐리티 필터를 다시 거치게 되는데 권한 없음으로 403이 내려오는 것이다.
// 요청 한번에 권한 인증이 여러번 되는 이유는 직접 구현한 토큰 인증 필터와 같은 경우 OncePerRequestFilter를 확장해서
// 요청 당 한번만 거치도록 설정하지만 기본적으로 필터는 서블릿에 대한 매요청마다 거치는 것이 기본 전략임

@Bean
public OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService() {
return new DefaultOAuth2UserService();
}

@Bean
public AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler() {
return (HttpServletRequest request, HttpServletResponse response, Authentication authentication) -> {
System.out.println("여기 오냐");
OAuth2User oauthUser = (OAuth2User) authentication.getPrincipal();

// OAuth2AuthorizedClient를 사용하여 액세스 토큰과 리프레시 토큰 가져오기
String clientRegistrationId = ((OAuth2UserRequest) authentication.getDetails()).getClientRegistration().getRegistrationId();
OAuth2AuthorizedClient authorizedClient = authorizedClientService.loadAuthorizedClient(clientRegistrationId, oauthUser.getName());

String accessToken = authorizedClient.getAccessToken().getTokenValue();
String refreshToken = authorizedClient.getRefreshToken() != null ? authorizedClient.getRefreshToken().getTokenValue() : null;

User foundUser = userService.findUserByAccessToken(accessToken);
if(foundUser == null) { // 가입 했던 적이 있는지 확인
foundUser = userService.registUserByAccessToken(accessToken);
foundUser.setRefreshToken(refreshToken);
response.sendRedirect("/user/info"); // 추가 정보 입력 페이지로 이동
} else {
foundUser.setRefreshToken(refreshToken);
response.sendRedirect("/"); // 가입했던 적이 있다면 홈으로 redirect
}
};
}

// @Bean
// public LogoutHandler logoutHandler() {
// return (HttpServletRequest request, HttpServletResponse response, Authentication authentication) -> {
// // 쿠키 삭제
// deleteCookie(response, "access_token");
// deleteCookie(response, "refresh_token");
// };
// }
//
// private void deleteCookie(HttpServletResponse response, String cookieName) {
// Cookie cookie = new Cookie(cookieName, null);
// cookie.setPath("/");
// cookie.setMaxAge(0); // 쿠키 즉시 삭제
// cookie.setHttpOnly(true);
// cookie.setSecure(true);
// response.addCookie(cookie);
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import java.util.List;

@RestController
@RequestMapping("/ether")
@RequestMapping("/api/ether")
public class EtherController {
private final EtherService etherService;
private final JwtUtil jwtUtil;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import java.util.List;

@RestController
@RequestMapping("/reply")
@RequestMapping("/api/reply")
public class ReplyController {

private final ReplyService replyService;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package com.mtvs.devlinkbackend.request.controller;

import com.mtvs.devlinkbackend.config.JwtUtil;
import com.mtvs.devlinkbackend.request.dto.RequestRegistRequestDTO;
import com.mtvs.devlinkbackend.request.dto.RequestUpdateRequestDTO;
import com.mtvs.devlinkbackend.request.entity.Request;
import com.mtvs.devlinkbackend.request.service.RequestService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

@RestController
@RequestMapping("/api/request")
public class RequestController {

private final RequestService requestService;
private final JwtUtil jwtUtil;

public RequestController(RequestService requestService, JwtUtil jwtUtil) {
this.requestService = requestService;
this.jwtUtil = jwtUtil;
}

@Operation(summary = "새로운 의뢰 등록", description = "새로운 의뢰를 등록합니다.")
@ApiResponses({
@ApiResponse(responseCode = "201", description = "의뢰가 성공적으로 등록됨"),
@ApiResponse(responseCode = "400", description = "잘못된 파라미터")
})
@PostMapping
public ResponseEntity<Request> registerRequest(
@RequestBody RequestRegistRequestDTO requestDTO,
@RequestHeader(name = "Authorization") String authorizationHeader) throws Exception {

String accountId = jwtUtil.getSubjectFromTokenWithoutAuth(authorizationHeader);
Request newRequest = requestService.registRequest(requestDTO, accountId);
return new ResponseEntity<>(newRequest, HttpStatus.CREATED);
}

@Operation(summary = "특정 의뢰 조회", description = "ID로 특정 의뢰를 조회합니다.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "의뢰가 성공적으로 조회됨"),
@ApiResponse(responseCode = "404", description = "의뢰를 찾을 수 없음")
})
@GetMapping("/{requestId}")
public ResponseEntity<Request> getRequestById(@PathVariable Long requestId) {
Request request = requestService.findRequestByRequestId(requestId);
if (request != null) {
return ResponseEntity.ok(request);
} else {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
}

@Operation(summary = "계정별 의뢰 목록 조회", description = "특정 계정에 대한 모든 의뢰를 조회합니다.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "의뢰 목록이 성공적으로 조회됨")
})
@GetMapping("/account")
public ResponseEntity<List<Request>> getRequestsByAccountId(
@RequestHeader(name = "Authorization") String authorizationHeader) throws Exception {

String accountId = jwtUtil.getSubjectFromTokenWithoutAuth(authorizationHeader);
List<Request> requests = requestService.findRequestsByAccountId(accountId);
return ResponseEntity.ok(requests);
}

@Operation(summary = "특정 기간 내의 의뢰 목록 조회", description = "시작과 끝 날짜 사이의 모든 의뢰를 조회합니다.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "의뢰 목록이 성공적으로 조회됨")
})
@GetMapping("/date-range")
public ResponseEntity<List<Request>> getRequestsBetweenDates(@RequestParam LocalDateTime startDateTime, @RequestParam LocalDateTime endDateTime) {
List<Request> requests = requestService.findAllRequestsBetweenStarDateTimeAndEndDateTime(startDateTime, endDateTime);
return ResponseEntity.ok(requests);
}

@Operation(summary = "의뢰 업데이트", description = "기존 의뢰를 업데이트합니다.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "의뢰가 성공적으로 업데이트됨"),
@ApiResponse(responseCode = "400", description = "잘못된 파라미터 또는 권한 없음")
})
@PatchMapping
public ResponseEntity<Request> updateRequest(
@RequestBody RequestUpdateRequestDTO requestDTO,
@RequestHeader(name = "Authorization") String authorizationHeader) {
try {
String accountId = jwtUtil.getSubjectFromTokenWithoutAuth(authorizationHeader);
Request updatedRequest = requestService.updateRequest(requestDTO, accountId);
return ResponseEntity.ok(updatedRequest);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
}

@Operation(summary = "의뢰 삭제", description = "ID로 특정 의뢰를 삭제합니다.")
@ApiResponses({
@ApiResponse(responseCode = "204", description = "의뢰가 성공적으로 삭제됨"),
@ApiResponse(responseCode = "404", description = "의뢰를 찾을 수 없음")
})
@DeleteMapping("/{requestId}")
public ResponseEntity<Void> deleteRequest(@PathVariable Long requestId) {
requestService.deleteRequest(requestId);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.mtvs.devlinkbackend.request.dto;

import lombok.*;

import java.time.LocalDateTime;

@Getter @Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class RequestRegistRequestDTO {
private String title;
private String content;
private LocalDateTime startDateTime;
private LocalDateTime endDateTime;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.mtvs.devlinkbackend.request.dto;

import lombok.*;

import java.time.LocalDateTime;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class RequestUpdateRequestDTO {
private Long requestId;
private String title;
private String content;
private LocalDateTime startDateTime;
private LocalDateTime endDateTime;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.mtvs.devlinkbackend.request.entity;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import java.time.LocalDateTime;

@Table(name = "REQUEST")
@Entity(name = "REQUEST")
@NoArgsConstructor
@ToString
@Getter
public class Request {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "REQUEST_ID")
private Long requestId;

@Column(name = "TITLE", nullable = false)
private String title;

@Column(name = "CONTENT", nullable = false)
private String content;

@Column(name = "START_DATETIME")
private LocalDateTime startDateTime;

@Column(name = "END_DATETIME")
private LocalDateTime endDateTime;

@Column(name = "ACCOUNT_ID", nullable = false)
private String accountId;

@CreationTimestamp
@Column(name = "CREATED_AT")
private LocalDateTime createdAt;

@UpdateTimestamp
@Column(name = "MODIFIED_AT")
private LocalDateTime modifiedAt;

public Request(String title, String content, LocalDateTime startDateTime, LocalDateTime endDateTime, String accountId) {
this.title = title;
this.content = content;
this.startDateTime = startDateTime;
this.endDateTime = endDateTime;
this.accountId = accountId;
}

public void setTitle(String title) {
this.title = title;
}

public void setContent(String content) {
this.content = content;
}

public void setStartDateTime(LocalDateTime startDateTime) {
this.startDateTime = startDateTime;
}

public void setEndDateTime(LocalDateTime endDateTime) {
this.endDateTime = endDateTime;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.mtvs.devlinkbackend.request.repository;

import com.mtvs.devlinkbackend.request.entity.Request;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;

@Repository
public interface RequestRepository extends JpaRepository<Request, Long> {
List<Request> findRequestsByAccountId(String accountId);

@Query("SELECT r FROM REQUEST r WHERE r.startDateTime BETWEEN :startDateTime AND :endDateTime " +
"AND r.endDateTime BETWEEN :startDateTime AND :endDateTime")
List<Request> findRequestsWithinDateRange(
@Param("startDateTime") LocalDateTime startDateTime,
@Param("endDateTime") LocalDateTime endDateTime);
}
Loading