Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.mtvs.devlinkbackend.channel.dto.ChannelUpdateRequestDTO;
import com.mtvs.devlinkbackend.channel.entity.Channel;
import com.mtvs.devlinkbackend.channel.service.ChannelService;
import com.mtvs.devlinkbackend.config.JwtUtil;
import com.mtvs.devlinkbackend.util.JwtUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.mtvs.devlinkbackend.comment.dto.CommentUpdateRequestDTO;
import com.mtvs.devlinkbackend.comment.entity.Comment;
import com.mtvs.devlinkbackend.comment.service.CommentService;
import com.mtvs.devlinkbackend.config.JwtUtil;
import com.mtvs.devlinkbackend.util.JwtUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.mtvs.devlinkbackend.config;

import com.mtvs.devlinkbackend.oauth2.service.UserService;
import com.mtvs.devlinkbackend.util.JwtUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
Expand All @@ -17,11 +17,9 @@
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtUtil jwtUtil;
private final UserService userService;

public JwtAuthenticationFilter(JwtUtil jwtUtil, UserService userService) {
public JwtAuthenticationFilter(JwtUtil jwtUtil) {
this.jwtUtil = jwtUtil;
this.userService = userService;
}

@Override
Expand Down Expand Up @@ -53,9 +51,10 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
} catch (Exception e) {
// 검증 실패 시 401 에러 설정
if(e.getMessage().equals("JWT is expired"))
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setStatus(449);
else
response.setStatus(449); // 헤더에 들어 있는 토큰이 잘못됨
System.out.println(e.getMessage());
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 헤더에 들어 있는 토큰이 잘못됨
return;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,25 @@
package com.mtvs.devlinkbackend.config;

import com.mtvs.devlinkbackend.oauth2.entity.User;
import com.mtvs.devlinkbackend.oauth2.service.UserService;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.session.InvalidSessionStrategy;
import org.springframework.web.cors.CorsConfigurationSource;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

private final UserService userService;
private final OAuth2AuthorizedClientService authorizedClientService;
private final CorsConfigurationSource corsConfigurationSource;
private final JwtAuthenticationFilter jwtAuthenticationFilter;

public SecurityConfig(UserService userService, CorsConfigurationSource corsConfigurationSource, OAuth2AuthorizedClientService authorizedClientService, JwtAuthenticationFilter jwtAuthenticationFilter) {
this.userService = userService;
public SecurityConfig(CorsConfigurationSource corsConfigurationSource, OAuth2AuthorizedClientService authorizedClientService, JwtAuthenticationFilter jwtAuthenticationFilter) {
this.corsConfigurationSource = corsConfigurationSource;
this.authorizedClientService = authorizedClientService;
this.jwtAuthenticationFilter = jwtAuthenticationFilter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.mtvs.devlinkbackend.ether.controller;

import com.mtvs.devlinkbackend.config.JwtUtil;
import com.mtvs.devlinkbackend.util.JwtUtil;
import com.mtvs.devlinkbackend.ether.dto.EtherRegistRequestDTO;
import com.mtvs.devlinkbackend.ether.dto.EtherUpdateRequestDTO;
import com.mtvs.devlinkbackend.ether.entity.Ether;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.mtvs.devlinkbackend.guild.controller;

import com.mtvs.devlinkbackend.config.JwtUtil;
import com.mtvs.devlinkbackend.util.JwtUtil;
import com.mtvs.devlinkbackend.guild.dto.GuildMemberModifyRequestDTO;
import com.mtvs.devlinkbackend.guild.dto.GuildRegistRequestDTO;
import com.mtvs.devlinkbackend.guild.dto.GuildUpdateRequestDTO;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package com.mtvs.devlinkbackend.oauth2.controller;

import com.mtvs.devlinkbackend.config.JwtUtil;
import com.mtvs.devlinkbackend.oauth2.service.UserService;
import com.mtvs.devlinkbackend.util.JwtUtil;
import com.mtvs.devlinkbackend.oauth2.dto.EpicGamesCallbackRequestDTO;
import com.mtvs.devlinkbackend.oauth2.entity.User;
import com.mtvs.devlinkbackend.oauth2.service.EpicGamesTokenService;
import com.mtvs.devlinkbackend.oauth2.service.UserService;
import com.mtvs.devlinkbackend.oauth2.service.UserPartnerService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
Expand All @@ -15,41 +16,21 @@
import java.util.Map;

@RestController
@RequestMapping("/api/auth")
@RequestMapping("/api/auth/epicgames")
public class Oauth2UserController {

private final EpicGamesTokenService epicGamesTokenService;
private final UserService userService;
private final JwtUtil jwtUtil;
private final UserService userService;

public Oauth2UserController(EpicGamesTokenService epicGamesTokenService, UserService userService, JwtUtil jwtUtil) {
public Oauth2UserController(EpicGamesTokenService epicGamesTokenService, JwtUtil jwtUtil, UserService userService) {
this.epicGamesTokenService = epicGamesTokenService;
this.userService = userService;
this.jwtUtil = jwtUtil;
}

// 로컬 user 정보 가져오는 API
@GetMapping("/local/user-info")
@Operation(
summary = "로컬 유저 정보 조회",
description = "DevLink만의 DB에 저장된 유저 정보를 조회한다."
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "조회 성공"),
@ApiResponse(responseCode = "400", description = "잘못된 헤더 또는 파라미터 전달"),
@ApiResponse(responseCode = "401", description = "인증되지 않음")
})
public ResponseEntity<?> getLocalUserInfo(@RequestHeader("Authorization") String authorizationHeader) {

try {
return ResponseEntity.ok(userService.findUserByAuthorizationHeader(authorizationHeader));
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid token");
}
this.userService = userService;
}

// epicgames 계정 정보 가져오는 API
@GetMapping("/epicgames/user-info")
@GetMapping("/user-info")
@Operation(
summary = "EpicGames 유저 정보 조회",
description = "EpicGames의 유저 정보를 조회한다."
Expand All @@ -74,18 +55,19 @@ public ResponseEntity<?> getEpicGamesUserInfo(
}
}

@GetMapping("/epicgames/accountId")
@GetMapping("/accountId")
public ResponseEntity<?> getAccountId(
@RequestHeader("Authorization") String authorizationHeader) {

try {
return ResponseEntity.ok(jwtUtil.getSubjectFromAuthHeaderWithAuth(authorizationHeader));
return ResponseEntity.ok(jwtUtil.getSubjectFromAuthHeaderWithoutAuth(authorizationHeader));
} catch (Exception e) {
System.out.println(e.getMessage());
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid token");
}
}

@PostMapping("/epicgames/callback")
@PostMapping("/callback")
@Operation(
summary = "EpicGames AccessToken 요청",
description = "EpicGames로부터 사용자에게 AccessToken을 전달한다."
Expand All @@ -107,19 +89,13 @@ public ResponseEntity<?> handleEpicGamesCallback(
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

@PostMapping("/login")
@GetMapping("/login")
public ResponseEntity<?> authLogin(
@RequestHeader(name = "Authorization") String authorizationHeader) {
@RequestHeader(name = "Authorization") String authorizationHeader) throws Exception {
User user = userService.findUserByAuthorizationHeader(authorizationHeader);

// 222 : 해당 User는 이미 서비스를 사용한 경험이 있음
// 260 : 해당 User가 처음 서비스를 사용
return user != null ? ResponseEntity.status(222).body("Existing User") : ResponseEntity.status(260).body("New User");
}

@PatchMapping("/local/user-info")
public ResponseEntity<?> updateLocalUserInfo() {
// User 추가 정보 확정되면 개발 예정
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package com.mtvs.devlinkbackend.oauth2.controller;

import com.mtvs.devlinkbackend.oauth2.dto.UserClientGroupRequestDTO;
import com.mtvs.devlinkbackend.oauth2.entity.UserClientGroup;
import com.mtvs.devlinkbackend.oauth2.service.UserClientGroupService;
import com.mtvs.devlinkbackend.util.JwtUtil;
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.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/user/group")
public class UserClientGroupController {
private final UserClientGroupService userClientGroupService;
private final JwtUtil jwtUtil;

public UserClientGroupController(UserClientGroupService userClientGroupService, JwtUtil jwtUtil) {
this.userClientGroupService = userClientGroupService;
this.jwtUtil = jwtUtil;
}

@Operation(summary = "UserClientGroup 등록")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 UserClientGroup이 등록됨"),
@ApiResponse(responseCode = "400", description = "잘못된 입력 데이터")
})
@PostMapping
public ResponseEntity<UserClientGroup> convertUserToUserClientGroup(
@RequestBody UserClientGroupRequestDTO userClientGroupRequestDTO,
@RequestHeader("Authorization") String authorizationHeader) throws Exception {

String accountId = jwtUtil.getSubjectFromAuthHeaderWithoutAuth(authorizationHeader);
UserClientGroup userClientGroup =
userClientGroupService.registUserClientGroup(userClientGroupRequestDTO, accountId);
return ResponseEntity.ok(userClientGroup);
}

@Operation(summary = "Authorization Header로 UserClientGroup 조회")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 UserClientGroup을 조회함"),
@ApiResponse(responseCode = "404", description = "UserClientGroup을 찾을 수 없음")
})
@GetMapping
public ResponseEntity<UserClientGroup> findUserClientGroupByAuthorizationHeader(
@RequestHeader("Authorization") String authorizationHeader) throws Exception {

String accountId = jwtUtil.getSubjectFromAuthHeaderWithoutAuth(authorizationHeader);
UserClientGroup userClientGroup = userClientGroupService.findUserClientGroupByAccountId(accountId);
return ResponseEntity.ok(userClientGroup);
}

@Operation(summary = "담당자 이름에 특정 키워드가 포함된 UserClientGroups 조회")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 UserClientGroups를 조회함")
})
@GetMapping("/manager-name/{managerName}")
public ResponseEntity<List<UserClientGroup>> findByManagerNameContainingIgnoreCase(@PathVariable String managerName) {
List<UserClientGroup> userClientGroups = userClientGroupService.findByManagerNameContainingIgnoreCase(managerName);
return ResponseEntity.ok(userClientGroups);
}

@Operation(summary = "그룹 이름에 특정 키워드가 포함된 UserClientGroups 조회")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 UserClientGroups를 조회함")
})
@GetMapping("/group-name/{groupName}")
public ResponseEntity<List<UserClientGroup>> findByGroupNameContainingIgnoreCase(@PathVariable String groupName) {
List<UserClientGroup> userClientGroups = userClientGroupService.findByGroupNameContainingIgnoreCase(groupName);
return ResponseEntity.ok(userClientGroups);
}

@Operation(summary = "Client Type으로 UserClientGroups 조회")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 UserClientGroups를 조회함")
})
@GetMapping("/client-type/{clientType}")
public ResponseEntity<List<UserClientGroup>> findByClientType(@PathVariable String clientType) {
List<UserClientGroup> userClientGroups = userClientGroupService.findByClientType(clientType);
return ResponseEntity.ok(userClientGroups);
}

@Operation(summary = "담당자 전화번호로 UserClientGroups 조회")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 UserClientGroups를 조회함")
})
@GetMapping("/manager-phone/{managerPhone}")
public ResponseEntity<List<UserClientGroup>> findByManagerPhone(@PathVariable String managerPhone) {
List<UserClientGroup> userClientGroups = userClientGroupService.findByManagerPhone(managerPhone);
return ResponseEntity.ok(userClientGroups);
}

@Operation(summary = "UserClientGroup 정보 수정")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "성공적으로 UserClientGroup을 수정함"),
@ApiResponse(responseCode = "404", description = "UserClientGroup을 찾을 수 없음")
})
@PatchMapping
public ResponseEntity<UserClientGroup> updateUserClientGroup(
@RequestBody UserClientGroupRequestDTO userClientGroupRequestDTO,
@RequestHeader("Authorization") String authorizationHeader) throws Exception {

String accountId = jwtUtil.getSubjectFromAuthHeaderWithoutAuth(authorizationHeader);
UserClientGroup userClientGroup =
userClientGroupService.updateUserClientGroup(userClientGroupRequestDTO, accountId);
return ResponseEntity.ok(userClientGroup);
}

@Operation(summary = "Authorization Header의 Account ID를 기반으로 UserClientGroup 삭제")
@ApiResponses(value = {
@ApiResponse(responseCode = "204", description = "성공적으로 UserClientGroup을 삭제함"),
@ApiResponse(responseCode = "404", description = "UserClientGroup을 찾을 수 없음")
})
@DeleteMapping
public ResponseEntity<Void> deleteUserClientGroupByAuthorizationHeader(@RequestHeader("Authorization") String authorizationHeader) throws Exception {

String accountId = jwtUtil.getSubjectFromAuthHeaderWithoutAuth(authorizationHeader);
userClientGroupService.deleteByAccountId(accountId);
return ResponseEntity.noContent().build();
}
}
Loading