Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
leestana01 committed Aug 6, 2024
2 parents 6e42134 + 7e0a1e8 commit 363914b
Show file tree
Hide file tree
Showing 50 changed files with 1,914 additions and 4 deletions.
12 changes: 8 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,18 @@ repositories {
}

dependencies {
// implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
// implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation 'io.jsonwebtoken:jjwt-api:0.12.6'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.2'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6'
compileOnly 'org.projectlombok:lombok'
// runtimeOnly 'com.mysql:mysql-connector-j'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// testImplementation 'org.springframework.security:spring-security-test'
Expand Down
8 changes: 8 additions & 0 deletions dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM --platform=linux/amd64 openjdk:17-jdk-slim

EXPOSE 8080

ARG JAR_FILE=build/libs/runwithmate-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} app.jar

ENTRYPOINT ["java","-jar","/app.jar"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package likelion.hufsglobal.lgtu.runwithmate.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsMvcConfig implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry corsRegistry) {

corsRegistry.addMapping("/**")
.exposedHeaders("Set-Cookie")
.allowedOrigins("http://localhost:5173","https://runwithmate.klr.kr");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package likelion.hufsglobal.lgtu.runwithmate.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);

// ObjectMapper에 JavaTimeModule 등록
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());

template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));

template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));
return template;
}

@Bean // Serialize 진행
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package likelion.hufsglobal.lgtu.runwithmate.config;

import jakarta.servlet.DispatcherType;
import jakarta.servlet.http.HttpServletRequest;
import likelion.hufsglobal.lgtu.runwithmate.service.OAuth2UserService;
import likelion.hufsglobal.lgtu.runwithmate.utils.CustomSuccessHandler;
import likelion.hufsglobal.lgtu.runwithmate.utils.JwtFilter;
import likelion.hufsglobal.lgtu.runwithmate.utils.JwtUtil;
import lombok.RequiredArgsConstructor;
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.oauth2.client.web.OAuth2LoginAuthenticationFilter;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

private final OAuth2UserService oauth2UserService;
private final CustomSuccessHandler customSuccessHandler;

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http, JwtUtil jwtUtil) throws Exception {
http
.cors(corsCustomizer -> corsCustomizer.configurationSource(request -> {
CorsConfiguration configuration = new CorsConfiguration();

configuration.setAllowedOrigins(Arrays.asList("http://localhost:5173","https://runwithmate.klr.kr"));
configuration.setAllowedMethods(Arrays.asList("POST", "GET", "OPTIONS", "DELETE"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type", "Set-Cookie"));
configuration.setMaxAge(3600L);
configuration.setExposedHeaders(Arrays.asList("Set-Cookie", "Authorization"));

return configuration;
}))
.csrf(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable)
.formLogin(AbstractHttpConfigurer::disable)
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))

// .addFilterAfter(new JwtFilter(jwtUtil), OAuth2LoginAuthenticationFilter.class)
.addFilterBefore(new JwtFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class)

.oauth2Login(oauth2 -> oauth2
.userInfoEndpoint(userInfoEndpointConfig -> userInfoEndpointConfig
.userService(oauth2UserService))
.successHandler(customSuccessHandler))

.authorizeHttpRequests( request -> request
.requestMatchers("/", "/oauth2/**", "/login/**", "/connect", "/api/games/test").permitAll()
.anyRequest().authenticated()
);


return http.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package likelion.hufsglobal.lgtu.runwithmate.config;

import likelion.hufsglobal.lgtu.runwithmate.utils.JwtUtil;
import likelion.hufsglobal.lgtu.runwithmate.utils.ws.JwtHandshakeInterceptor;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@RequiredArgsConstructor
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

private final JwtUtil jwtUtil;

@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/send"); // 클라이언트에서 보낸 메시지를 받을 prefix
registry.enableSimpleBroker("/room"); // 해당 주소를 구독하고 있는 클라이언트들에게 메시지 전달
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/connect")
.addInterceptors(new JwtHandshakeInterceptor(jwtUtil))
.setAllowedOriginPatterns("*");
}

/**
* 추후 학습용 주석
* message를 중간에 Intercept하려면
*
* @Override
* public void configureClientInboundChannel(ChannelRegistration registration) {
* registration.interceptors(new WebSocketChannelInterceptor());
*/
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package likelion.hufsglobal.lgtu.runwithmate.controller;

import likelion.hufsglobal.lgtu.runwithmate.domain.game.GameInfo;
import likelion.hufsglobal.lgtu.runwithmate.domain.game.UserPosition;
import likelion.hufsglobal.lgtu.runwithmate.domain.game.dto.GameFinishResDto;
import likelion.hufsglobal.lgtu.runwithmate.domain.game.dto.PositionUpdateResDto;
import likelion.hufsglobal.lgtu.runwithmate.domain.game.dto.StartCheckResDto;
import likelion.hufsglobal.lgtu.runwithmate.domain.oauth2.CustomOAuth2User;
import likelion.hufsglobal.lgtu.runwithmate.service.GameService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController("/api/games")
@RequiredArgsConstructor
public class GameController {

private final GameService gameService;

@MessageMapping("/start_check/{roomId}")
@SendTo("/room/{roomId}")
public StartCheckResDto checkStart(@DestinationVariable String roomId, UserPosition userPosition, Authentication authentication) {
String userId = authentication.getName();
return gameService.checkStart(roomId, userId, userPosition);
}

@MessageMapping("/update_position/{roomId}")
@SendTo("/room/{roomId}")
public PositionUpdateResDto updatePosition(@DestinationVariable String roomId, UserPosition userPosition, Authentication authentication) {
String userId = authentication.getName();
return gameService.updatePosition(roomId, userId, userPosition);
}

@MessageMapping("/surrender/{roomId}")
@SendTo("/room/{roomId}")
public void gameSurrender(@DestinationVariable String roomId) {

}

@GetMapping("/my-games")
public ResponseEntity<List<GameInfo>> getMyGames(Authentication authentication) {
CustomOAuth2User oAuth2User = (CustomOAuth2User) authentication.getPrincipal();
String userId = oAuth2User.getUserId();
return ResponseEntity.ok(gameService.getAllGameInfos(userId));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package likelion.hufsglobal.lgtu.runwithmate.controller;

import likelion.hufsglobal.lgtu.runwithmate.domain.gameroom.*;
import likelion.hufsglobal.lgtu.runwithmate.domain.oauth2.CustomOAuth2User;
import likelion.hufsglobal.lgtu.runwithmate.service.GameRoomService;
import likelion.hufsglobal.lgtu.runwithmate.utils.JwtUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

import java.security.Principal;

@Controller
@Slf4j
@RequiredArgsConstructor
public class GameRoomController {

private final GameRoomService gameRoomService;

@PostMapping("/api/games/join")
public ResponseEntity<RoomCreateResDto> joinGameRoom() {
CustomOAuth2User oAuth2User = JwtUtil.getOAuth2User();
String userId = oAuth2User.getUserId();
return ResponseEntity.ok(gameRoomService.createRoom(userId));
}

@MessageMapping("/update_room/{roomId}")
@SendTo("/room/{roomId}")
public RoomUpdateResDto updateRoom(@DestinationVariable String roomId, RoomUpdateReqDto roomUpdateReqDto, Authentication authentication) {
String userId = authentication.getName();
System.out.println("userId: " + userId);
log.info("userId: " + userId);
return gameRoomService.updateRoom(roomId, userId, roomUpdateReqDto.getBetPoint(), roomUpdateReqDto.getTimeLimit());
}

@MessageMapping("/check_room/{roomId}")
@SendTo("/room/{roomId}")
public RoomJoinResDto checkRoom(@DestinationVariable String roomId) {
return gameRoomService.checkRoomStatus(roomId);
}

@MessageMapping("/join_room/{roomId}")
@SendTo("/room/{roomId}")
public RoomJoinResDto joinRoom(@DestinationVariable String roomId, Authentication authentication) {
String userId = authentication.getName();
return gameRoomService.joinRoom(roomId, userId);
}

@MessageMapping("/start_game/{roomId}")
@SendTo("/room/{roomId}")
public GameStartResDto startGame(@PathVariable String roomId) {
// 박스 위치 정보는 GameController에서 모든 플레이어들이 게임 시작 요청하면, 위치정보를 받으면서 랜덤으로 박스 위치를 생성하여 전달
return gameRoomService.startGame(roomId);
}

// ----
@MessageMapping("/hello")
@SendTo("/room")
public String send(String message, Principal principal) throws Exception {
String userId = principal.getName();
return "User " + userId + " sent: " + message;
}

@PostMapping("/api/games/test")
public ResponseEntity<Void> test() {
gameRoomService.createRoomForTest();
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package likelion.hufsglobal.lgtu.runwithmate.controller;

import likelion.hufsglobal.lgtu.runwithmate.domain.oauth2.CustomOAuth2User;
import likelion.hufsglobal.lgtu.runwithmate.domain.user.CheckUpdateResDto;
import likelion.hufsglobal.lgtu.runwithmate.service.GameService;
import likelion.hufsglobal.lgtu.runwithmate.service.OAuth2UserService;
import likelion.hufsglobal.lgtu.runwithmate.utils.JwtUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class LobyController {

private final GameService gameService;

@PostMapping("/api/users/check")
public ResponseEntity<CheckUpdateResDto> updateCheck() {
CustomOAuth2User oAuth2User = JwtUtil.getOAuth2User();
String userId = oAuth2User.getUserId();
return ResponseEntity.ok(gameService.updateCheck(userId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package likelion.hufsglobal.lgtu.runwithmate.controller;

import likelion.hufsglobal.lgtu.runwithmate.domain.oauth2.CustomOAuth2User;
import likelion.hufsglobal.lgtu.runwithmate.domain.user.MyInfoResDto;
import likelion.hufsglobal.lgtu.runwithmate.utils.JwtUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class LoginController {

private final JwtUtil jwtUtil;

@GetMapping("/myinfo")
public MyInfoResDto getTokenAndUsername() {
CustomOAuth2User oAuth2User = JwtUtil.getOAuth2User();
String userId = oAuth2User.getUserId();
String role = oAuth2User.getAuthorities().stream().findFirst().get().getAuthority();
String accessToken = jwtUtil.createToken(userId, role, 60*60*60*24*30L);
return new MyInfoResDto(userId, accessToken);
}
}
Loading

0 comments on commit 363914b

Please sign in to comment.