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
13 changes: 4 additions & 9 deletions src/main/java/chainsawman/gesture/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package chainsawman.gesture.config;
import chainsawman.gesture.global.TokenProvider;
import chainsawman.gesture.security.CustomUserDetailsService;

import chainsawman.gesture.security.InternalAuthFilter;
import chainsawman.gesture.security.JwtAuthenticationFilter;
import lombok.RequiredArgsConstructor;
Expand All @@ -17,15 +16,13 @@
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {

private final TokenProvider tokenProvider;
private final CustomUserDetailsService customUserDetailsService;
private final JwtAuthenticationFilter jwtAuthenticationFilter;
private final InternalAuthFilter internalAuthFilter;

@Bean
Expand All @@ -38,7 +35,6 @@ public AuthenticationManager authenticationManager(AuthenticationConfiguration c
return configuration.getAuthenticationManager();
}


@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
Expand All @@ -50,17 +46,16 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
.authorizeHttpRequests(auth -> auth
.requestMatchers(
"/auth/**",
"/users/check-id",
"/swagger-ui/**",
"/swagger-ui.html",
"/v3/api-docs/**",
"/v3/api-docs"
).permitAll()
.anyRequest().permitAll()
)
.addFilterBefore(new JwtAuthenticationFilter(tokenProvider, customUserDetailsService),
UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(internalAuthFilter, JwtAuthenticationFilter.class);
return http.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@

public class NotRoomHostException extends DomainException {
public NotRoomHostException() {
super(HttpStatus.FORBIDDEN, "ROOM_007", "통화방 호스트만 초대할 수 있습니다.");
super(HttpStatus.FORBIDDEN, "ROOM_007", "통화방 호스트만 가능한 기능입니다.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@

public class InvalidPasswordException extends DomainException {
public InvalidPasswordException() {
super(HttpStatus.BAD_REQUEST, "USER_003", "비밀번호가 올바르지 않습니다.");
super(HttpStatus.UNAUTHORIZED, "USER_003", "비밀번호가 올바르지 않습니다.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public ResponseEntity<ApiResponse<Void>> handleValidException(MethodArgumentNotV
.findFirst()
.orElse("입력값이 올바르지 않습니다.");
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(ApiResponse.error("COMMON_400", "입력값이 올바르지 않습니다."));
.body(ApiResponse.error("COMMON_400", message));
}

@ExceptionHandler(Exception.class)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package chainsawman.gesture.security;

import chainsawman.gesture.entity.user.User;
import chainsawman.gesture.global.TokenProvider;
import chainsawman.gesture.repository.user.UserRepository;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
Expand All @@ -9,18 +11,19 @@
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.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.List;

@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {

private final TokenProvider tokenProvider;
private final UserDetailsService userDetailsService;
private final UserRepository userRepository;

@Override
protected void doFilterInternal(
Expand All @@ -33,17 +36,13 @@ protected void doFilterInternal(

if (StringUtils.hasText(token) && tokenProvider.validateToken(token)) {
String email = tokenProvider.getEmail(token);
UserDetails userDetails = userDetailsService.loadUserByUsername(email);

if (SecurityContextHolder.getContext().getAuthentication() == null) {
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
userRepository.findByEmailAndIsDeactivatedFalse(email).ifPresent(user -> {
if (SecurityContextHolder.getContext().getAuthentication() == null) {
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(user, null, List.of());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
});
}

filterChain.doFilter(request, response);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/chainsawman/gesture/service/AuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import chainsawman.gesture.global.TokenProvider;
import chainsawman.gesture.repository.user.RefreshTokenRepository;
import chainsawman.gesture.repository.user.UserRepository;
import jakarta.transaction.Transactional;
import org.springframework.transaction.annotation.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/chainsawman/gesture/service/CallService.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import chainsawman.gesture.exceptions.call.CallAlreadyJoinedException;
import chainsawman.gesture.exceptions.call.CallParticipantNotFoundException;
import chainsawman.gesture.exceptions.call.NoActiveCallException;
import chainsawman.gesture.exceptions.room.RoomMemberNotFoundException;
import chainsawman.gesture.exceptions.room.NotRoomMemberException;
import chainsawman.gesture.exceptions.room.RoomNotFoundException;
import chainsawman.gesture.repository.call.CallParticipantRepository;
import chainsawman.gesture.repository.call.CallRepository;
Expand Down Expand Up @@ -42,7 +42,7 @@ public CallJoinResponse joinCall(Long roomIdx) {
.orElseThrow(RoomNotFoundException::new);

if (!roomMemberRepository.existsByRoom_IdxAndUser_Idx(roomIdx, currentUser.getIdx())) {
throw new RoomMemberNotFoundException();
throw new NotRoomMemberException();
}

// 활성 통화 세션이 없으면 새로 생성 (최초 참여자가 호스트)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import chainsawman.gesture.repository.room.RoomRepository;
import chainsawman.gesture.security.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down
7 changes: 3 additions & 4 deletions src/main/java/chainsawman/gesture/service/RoomService.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
import chainsawman.gesture.exceptions.room.RoomFullException;
import chainsawman.gesture.exceptions.room.RoomMaxParticipantExceededException;
import chainsawman.gesture.exceptions.room.RoomMemberNotFoundException;
import chainsawman.gesture.exceptions.room.NotRoomHostException;
import chainsawman.gesture.exceptions.room.RoomNotFoundException;
import chainsawman.gesture.dto.room.response.RoomLeaveResponse;
import chainsawman.gesture.exceptions.user.InvalidPasswordException;
import chainsawman.gesture.repository.chat.ChatParticipantRepository;
import chainsawman.gesture.repository.chat.ChatRoomRepository;
Expand All @@ -26,7 +26,6 @@
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand Down Expand Up @@ -160,7 +159,7 @@ public RoomPatchResponse patchRoom(Long roomIdx, RoomPatchRequest request) {
.orElseThrow(RoomNotFoundException::new);

if (!room.getHost().getIdx().equals(currentUser.getIdx())) {
throw new AccessDeniedException("방장만 수정할 수 있습니다.");
throw new NotRoomHostException();
}

int currentCount = roomMemberRepository.countByRoom_Idx(roomIdx);
Expand Down Expand Up @@ -208,7 +207,7 @@ public RoomDeleteResponse deleteRoom(Long roomIdx) {
.orElseThrow(RoomNotFoundException::new);

if (!room.getHost().getIdx().equals(currentUser.getIdx())) {
throw new AccessDeniedException("방장만 삭제할 수 있습니다.");
throw new NotRoomHostException();
}

roomMemberRepository.deleteAllByRoom_Idx(roomIdx);
Expand Down
1 change: 0 additions & 1 deletion src/main/java/chainsawman/gesture/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import chainsawman.gesture.repository.user.UserRepository;
import chainsawman.gesture.security.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
Expand Down
12 changes: 6 additions & 6 deletions src/test/java/chainsawman/gesture/service/CallServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import chainsawman.gesture.exceptions.call.CallAlreadyJoinedException;
import chainsawman.gesture.exceptions.call.CallParticipantNotFoundException;
import chainsawman.gesture.exceptions.call.NoActiveCallException;
import chainsawman.gesture.exceptions.room.RoomMemberNotFoundException;
import chainsawman.gesture.exceptions.room.NotRoomMemberException;
import chainsawman.gesture.exceptions.room.RoomNotFoundException;
import chainsawman.gesture.repository.call.CallParticipantRepository;
import chainsawman.gesture.repository.call.CallRepository;
Expand Down Expand Up @@ -73,7 +73,7 @@ void joinCall_creates_new_session_when_no_active_call() {
given(roomMemberRepository.existsByRoom_IdxAndUser_Idx(10L, 1L)).willReturn(true);
given(callRepository.findByRoom_IdxAndEndedAtIsNull(10L)).willReturn(Optional.empty());
given(callRepository.save(any(Call.class))).willReturn(newCall);
given(callParticipantRepository.existsByCall_IdxAndUser_IdxAndLeftAtIsNull(100L, 1L)).willReturn(false);
given(callParticipantRepository.existsByUser_IdxAndLeftAtIsNull(1L)).willReturn(false);
given(callParticipantRepository.save(any(CallParticipant.class))).willAnswer(inv -> {
CallParticipant p = inv.getArgument(0);
ReflectionTestUtils.setField(p, "joinedAt", LocalDateTime.now());
Expand All @@ -100,7 +100,7 @@ void joinCall_joins_existing_session() {
given(roomRepository.findById(10L)).willReturn(Optional.of(room));
given(roomMemberRepository.existsByRoom_IdxAndUser_Idx(10L, 1L)).willReturn(true);
given(callRepository.findByRoom_IdxAndEndedAtIsNull(10L)).willReturn(Optional.of(existingCall));
given(callParticipantRepository.existsByCall_IdxAndUser_IdxAndLeftAtIsNull(100L, 1L)).willReturn(false);
given(callParticipantRepository.existsByUser_IdxAndLeftAtIsNull(1L)).willReturn(false);
given(callParticipantRepository.save(any(CallParticipant.class))).willAnswer(inv -> {
CallParticipant p = inv.getArgument(0);
ReflectionTestUtils.setField(p, "joinedAt", LocalDateTime.now());
Expand All @@ -127,14 +127,14 @@ void joinCall_room_not_found() {
}

@Test
@DisplayName("통화 참여 - 방 멤버가 아니면 RoomMemberNotFoundException")
@DisplayName("통화 참여 - 방 멤버가 아니면 NotRoomMemberException")
void joinCall_not_a_room_member() {
given(securityUtils.getCurrentUser()).willReturn(user);
given(roomRepository.findById(10L)).willReturn(Optional.of(room));
given(roomMemberRepository.existsByRoom_IdxAndUser_Idx(10L, 1L)).willReturn(false);

assertThatThrownBy(() -> callService.joinCall(10L))
.isInstanceOf(RoomMemberNotFoundException.class);
.isInstanceOf(NotRoomMemberException.class);
}

@Test
Expand All @@ -146,7 +146,7 @@ void joinCall_already_joined() {
given(roomRepository.findById(10L)).willReturn(Optional.of(room));
given(roomMemberRepository.existsByRoom_IdxAndUser_Idx(10L, 1L)).willReturn(true);
given(callRepository.findByRoom_IdxAndEndedAtIsNull(10L)).willReturn(Optional.of(existingCall));
given(callParticipantRepository.existsByCall_IdxAndUser_IdxAndLeftAtIsNull(100L, 1L)).willReturn(true);
given(callParticipantRepository.existsByUser_IdxAndLeftAtIsNull(1L)).willReturn(true);

assertThatThrownBy(() -> callService.joinCall(10L))
.isInstanceOf(CallAlreadyJoinedException.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import chainsawman.gesture.exceptions.user.UserNotFoundException;
import chainsawman.gesture.repository.friend.FriendInviteRepository;
import chainsawman.gesture.repository.friend.FriendshipRepository;
import chainsawman.gesture.repository.room.RoomMemberRepository;
import chainsawman.gesture.repository.room.RoomRepository;
import chainsawman.gesture.repository.user.UserRepository;
import chainsawman.gesture.security.SecurityUtils;
Expand Down Expand Up @@ -47,6 +48,7 @@ class FriendServiceTest {
@Mock FriendInviteRepository friendInviteRepository;
@Mock UserRepository userRepository;
@Mock RoomRepository roomRepository;
@Mock RoomMemberRepository roomMemberRepository;
@Mock SecurityUtils securityUtils;

@InjectMocks FriendService friendService;
Expand Down Expand Up @@ -81,6 +83,7 @@ void invite_success() {
given(securityUtils.getCurrentUser()).willReturn(sender);
given(userRepository.findByIdxAndIsDeactivatedFalse(2L)).willReturn(Optional.of(receiver));
given(roomRepository.findById(55L)).willReturn(Optional.of(room));
given(roomMemberRepository.existsByRoom_IdxAndUser_Idx(55L, 2L)).willReturn(false);
given(friendInviteRepository.save(any(FriendInvite.class))).willAnswer(inv -> {
FriendInvite invite = inv.getArgument(0);
ReflectionTestUtils.setField(invite, "idx", 10L);
Expand Down Expand Up @@ -132,6 +135,7 @@ void invite_duplicate_pending() {
given(securityUtils.getCurrentUser()).willReturn(sender);
given(userRepository.findByIdxAndIsDeactivatedFalse(2L)).willReturn(Optional.of(receiver));
given(roomRepository.findById(55L)).willReturn(Optional.of(room));
given(roomMemberRepository.existsByRoom_IdxAndUser_Idx(55L, 2L)).willReturn(false);
given(friendInviteRepository.existsBySender_IdxAndReceiver_IdxAndRoom_IdxAndStatus(
1L, 2L, 55L, InvitationStatus.PENDING)).willReturn(true);

Expand Down
Loading
Loading