Skip to content

Commit

Permalink
Merge pull request codesquad-members-2024#36 from CodeSquad-Airbnb-Te…
Browse files Browse the repository at this point in the history
…am07/Dev

[Team07] 2주차 두 번째 PR
  • Loading branch information
moto6 authored Jun 15, 2024
2 parents 2f34443 + 9dae09f commit 86dcf69
Show file tree
Hide file tree
Showing 128 changed files with 2,100 additions and 1,083 deletions.
1 change: 1 addition & 0 deletions BE/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ dependencies {
testImplementation 'org.springframework.security:spring-security-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testImplementation 'io.rest-assured:rest-assured'
testImplementation 'com.navercorp.fixturemonkey:fixture-monkey-starter:1.0.18'

// Swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
Expand Down
10 changes: 5 additions & 5 deletions BE/src/main/java/team07/airbnb/AirbnbApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableJpaAuditing
@SpringBootApplication
@EnableScheduling
public class AirbnbApplication {

public static void main(String[] args) {
SpringApplication.run(AirbnbApplication.class, args);
}
public static void main(String[] args) {
SpringApplication.run(AirbnbApplication.class, args);
}

}
24 changes: 0 additions & 24 deletions BE/src/main/java/team07/airbnb/common/GlobalExceptionHandler.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import lombok.Builder;
import lombok.Getter;
import team07.airbnb.domain.user.entity.UserEntity;
import team07.airbnb.domain.user.enums.RegistrationID;
import team07.airbnb.domain.user.enums.Role;
import team07.airbnb.data.user.enums.RegistrationID;
import team07.airbnb.data.user.enums.Role;
import team07.airbnb.entity.UserEntity;

import java.util.Map;

Expand Down Expand Up @@ -65,6 +65,7 @@ private static OAuthAttributes ofGoogle(String registrationId, String usernameAt
.registrationId(registrationId)
.build();
}

public UserEntity toEntity() {
return UserEntity.builder()
.name(name)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package team07.airbnb.common.auth.aop;

import team07.airbnb.domain.user.enums.Role;
import team07.airbnb.data.user.enums.Role;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import team07.airbnb.common.auth.JwtAuthenticationFilter;
import team07.airbnb.domain.user.enums.Role;
import team07.airbnb.common.auth.jwt.JwtAuthenticationFilter;
import team07.airbnb.data.user.enums.Role;
import team07.airbnb.exception.auth.AuthenticateException;
import team07.airbnb.exception.auth.UnAuthorizedException;

import java.util.Collection;

import static team07.airbnb.domain.user.enums.Role.*;
import static team07.airbnb.data.user.enums.Role.ADMIN;
import static team07.airbnb.data.user.enums.Role.HOST;

@Component
@Aspect
Expand All @@ -27,14 +30,14 @@ public class AuthenticationAspect {

@Around("@annotation(authenticated)")
public Object authenticate(ProceedingJoinPoint joinPoint, Authenticated authenticated) throws Throwable {
jwtRequestFilter.validateJwt(request);
String jwt = jwtRequestFilter.validateJwt(request);
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
throw new SecurityException("인증과정에서 문제가 발생했습니다");
throw new AuthenticateException("인증과정에서 문제가 발생했습니다", jwt);
}

if (!userHasGrant(authenticated, authentication)) {
throw new SecurityException("허가되지 않은 접근입니다");
throw new UnAuthorizedException("AOP 에서 권한 예외 발생함");
}

return joinPoint.proceed();
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package team07.airbnb.common.auth;
package team07.airbnb.common.auth.jwt;

import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import team07.airbnb.domain.user.dto.TokenUserInfo;
import team07.airbnb.data.user.dto.response.TokenUserInfo;

import java.util.Collection;
import java.util.Collections;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package team07.airbnb.common.auth;
package team07.airbnb.common.auth.jwt;

import com.fasterxml.jackson.core.JsonProcessingException;
import jakarta.servlet.FilterChain;
Expand All @@ -10,8 +10,7 @@
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import team07.airbnb.domain.user.dto.TokenUserInfo;
import team07.airbnb.common.util.jwt.JwtUtil;
import team07.airbnb.data.user.dto.response.TokenUserInfo;

import java.io.IOException;

Expand All @@ -27,13 +26,22 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
filterChain.doFilter(request, response);
}

public void validateJwt(HttpServletRequest request) throws JsonProcessingException {
public String validateJwt(HttpServletRequest request) throws JsonProcessingException {
String jwt = resolveToken(request);
if (jwt != null && jwtUtil.validateToken(jwt)) {
TokenUserInfo userEntity = jwtUtil.getUserEntity(jwt);
Authentication authentication = new JwtAuthentication(jwt, userEntity, true);
Authentication authentication = null;
TokenUserInfo userInfo = null;

if (jwt == null || !jwtUtil.validateToken(jwt)) {
authentication = new JwtAuthentication(jwt, userInfo, false);
SecurityContextHolder.getContext().setAuthentication(authentication);
return jwt;
}

userInfo = jwtUtil.getTokenUserInfo(jwt);
authentication = new JwtAuthentication(jwt, userInfo, true);
SecurityContextHolder.getContext().setAuthentication(authentication);

return jwt;
}

private String resolveToken(HttpServletRequest request) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package team07.airbnb.common.auth;
package team07.airbnb.common.auth.jwt;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.core.user.OAuth2User;
import team07.airbnb.domain.user.dto.TokenUserInfo;
import team07.airbnb.domain.user.entity.UserEntity;
import team07.airbnb.data.user.dto.response.TokenUserInfo;

import java.util.Collection;
import java.util.Collections;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package team07.airbnb.common.util.jwt;
package team07.airbnb.common.auth.jwt;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand All @@ -9,8 +9,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import team07.airbnb.domain.user.dto.TokenUserInfo;
import team07.airbnb.common.auth.JwtUserDetails;
import team07.airbnb.data.user.dto.response.TokenUserInfo;

import javax.crypto.SecretKey;
import java.util.Date;
Expand All @@ -27,7 +26,7 @@ public class JwtUtil {
private final SecretKey key;

public JwtUtil(
@Value("${jwt.secret}")String jwtSecret,
@Value("${jwt.secret}") String jwtSecret,
@Value("${jwt.expiration_time}") long jwtExpirationMs) {
this.jwtExpirationMs = jwtExpirationMs;
this.key = Keys.hmacShaKeyFor(jwtSecret.getBytes());
Expand All @@ -46,7 +45,17 @@ public String generateToken(JwtUserDetails userDetails) throws JsonProcessingExc
.compact();
}

public TokenUserInfo getUserEntity(String token) throws JsonProcessingException {
public boolean validateToken(String token) {
try {
Jwts.parser().verifyWith(key).build().parseSignedClaims(token);
return true;
} catch (Exception e) {
log.error("Not Valid Token %s".formatted(token));
}
return false;
}

public TokenUserInfo getTokenUserInfo(String token) throws JsonProcessingException {
Claims claims = extractClaims(token);
String userJson = claims.get("user", String.class);
return mapper.readValue(userJson, TokenUserInfo.class);
Expand All @@ -59,14 +68,4 @@ private Claims extractClaims(String token) {
.parseSignedClaims(token)
.getPayload();
}

public boolean validateToken(String token) {
try {
Jwts.parser().verifyWith(key).build().parseSignedClaims(token);
return true;
} catch (Exception e) {
log.error("Not Valid Token %s".formatted(token));
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package team07.airbnb.common.util;
package team07.airbnb.common.auth.jwt;

import org.springframework.core.MethodParameter;
import org.springframework.security.core.Authentication;
Expand All @@ -8,7 +8,7 @@
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import team07.airbnb.domain.user.dto.TokenUserInfo;
import team07.airbnb.data.user.dto.response.TokenUserInfo;

@Component
public class TokenArgumentResolver implements HandlerMethodArgumentResolver {
Expand All @@ -23,7 +23,7 @@ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer m
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
return (TokenUserInfo) authentication.getPrincipal();
return authentication.getPrincipal();
}
return null;
}
Expand Down
17 changes: 17 additions & 0 deletions BE/src/main/java/team07/airbnb/common/util/DateHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package team07.airbnb.common.util;

import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.YearMonth;

@Component
public class DateHelper {
public boolean isDateInMonthYear(int year, int month, LocalDate date) {
YearMonth yearMonth = YearMonth.of(year, month);
LocalDate startOfMonth = yearMonth.atDay(1);
LocalDate endOfMonth = yearMonth.atEndOfMonth();

return !date.isBefore(startOfMonth) && !date.isAfter(endOfMonth);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package team07.airbnb.common.validation;

import jakarta.validation.Constraint;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = CheckOutAfterCheckInValidator.class)
public @interface CheckOutAfterCheckIn {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package team07.airbnb.common.validation;

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import team07.airbnb.data.booking.dto.request.BookingRequest;

import java.time.LocalDate;

public class CheckOutAfterCheckInValidator implements ConstraintValidator<CheckOutAfterCheckIn, BookingRequest> {

@Override
public void initialize(CheckOutAfterCheckIn constraintAnnotation) {
ConstraintValidator.super.initialize(constraintAnnotation);
}

@Override
public boolean isValid(BookingRequest request, ConstraintValidatorContext context) {
LocalDate checkIn = request.checkIn();
LocalDate checkOut = request.checkOut();

if (checkIn == null || checkOut == null) {
return true; // null 값은 다른 validator가 처리
}

return !checkOut.isBefore(checkIn);
}
}
7 changes: 7 additions & 0 deletions BE/src/main/java/team07/airbnb/config/JpaConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package team07.airbnb.config;

import org.springframework.context.annotation.Configuration;

@Configuration
public class JpaConfig {
}
12 changes: 11 additions & 1 deletion BE/src/main/java/team07/airbnb/config/SwaggerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.servers.Server;
import io.swagger.v3.oas.models.tags.Tag;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

@Configuration
Expand All @@ -21,7 +23,15 @@ public OpenAPI customOpenAPI() {
.info(new Info()
.title("Squadbnb API")
.version("1.0")
.description("스쿼드비엔비 API 문서입니다"));
.description("스쿼드비엔비 API 문서입니다"))
.tags(Arrays.asList(
new Tag().name("User"),
new Tag().name("Host"),
new Tag().name("숙소"),
new Tag().name("상품"),
new Tag().name("예약"),
new Tag().name("리뷰")
));
}
}

2 changes: 1 addition & 1 deletion BE/src/main/java/team07/airbnb/config/WebConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import org.springframework.web.filter.ForwardedHeaderFilter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import team07.airbnb.common.util.TokenArgumentResolver;
import team07.airbnb.common.auth.jwt.TokenArgumentResolver;

import java.util.List;

Expand Down
Loading

0 comments on commit 86dcf69

Please sign in to comment.