Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] feat: 목적지 도착 여부 확인 기능 구현 #47

Merged
merged 10 commits into from
Jul 20, 2023
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.now.naaga.auth.application;

import static com.now.naaga.auth.exception.AuthExceptionType.PASSWORD_MISMATCH;

import com.now.naaga.auth.exception.AuthException;
import com.now.naaga.member.application.MemberService;
import com.now.naaga.member.application.dto.MemberCommand;
import com.now.naaga.member.domain.Member;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.now.naaga.auth.exception.AuthExceptionType.PASSWORD_MISMATCH;

@Transactional
@Service
public class AuthService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,28 @@ public enum AuthExceptionType implements BaseExceptionType {
100,
HttpStatus.UNAUTHORIZED,
"비밀번호가 일치하지 않습니다."
);
),

NOT_EXIST_HEADER(
101,
HttpStatus.UNAUTHORIZED,
"헤더 정보가 존재하지 않습니다."
),

INVALID_HEADER(
102,
HttpStatus.UNAUTHORIZED,
"헤더 정보가 유효하지 않습니다."
),
;

private final int errorCode;
private final HttpStatus httpStatus;
private final String errorMessage;

AuthExceptionType(final int errorCode, final HttpStatus httpStatus, final String errorMessage) {
AuthExceptionType(final int errorCode,
final HttpStatus httpStatus,
final String errorMessage) {
this.errorCode = errorCode;
this.httpStatus = httpStatus;
this.errorMessage = errorMessage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,5 @@

public interface AuthenticationExtractor<T> {

String AUTHORIZATION = "Authorization";

T extract(String request);
T extract(final String request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ public class BasicAuthenticationDecoder {
private static final String BASIC_TYPE = "Basic";
private static final String DELIMITER = ":";

public String[] decode(String header) {
String authHeaderValue = header.substring(BASIC_TYPE.length()).trim();
byte[] decodedBytes = Base64.decodeBase64(authHeaderValue);
String decodedString = new String(decodedBytes);
public String[] decode(final String header) {
final String authHeaderValue = header.substring(BASIC_TYPE.length()).trim();
final byte[] decodedBytes = Base64.decodeBase64(authHeaderValue);
final String decodedString = new String(decodedBytes);

return decodedString.split(DELIMITER);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.now.naaga.auth.infrastructure;

import com.now.naaga.auth.exception.AuthException;
import com.now.naaga.member.application.dto.MemberCommand;
import org.springframework.stereotype.Component;

import static com.now.naaga.auth.exception.AuthExceptionType.INVALID_HEADER;
import static com.now.naaga.auth.exception.AuthExceptionType.NOT_EXIST_HEADER;

@Component
public class BasicAuthenticationExtractor implements AuthenticationExtractor<MemberCommand> {

Expand All @@ -16,16 +20,16 @@ public BasicAuthenticationExtractor(final BasicAuthenticationDecoder basicAuthen
this.basicAuthenticationDecoder = basicAuthenticationDecoder;
}

public MemberCommand extract(String header) {
public MemberCommand extract(final String header) {
if (header == null) {
throw new RuntimeException("헤더가 존재하지 않습니다.");
throw new AuthException(NOT_EXIST_HEADER);
}
if (!header.toLowerCase().startsWith(BASIC_TYPE.toLowerCase())) {
throw new RuntimeException("헤더 정보가 잘못됐습니다.");
throw new AuthException(INVALID_HEADER);
}
String[] credentials = basicAuthenticationDecoder.decode(header);
String email = credentials[EMAIL_INDEX];
String password = credentials[PASSWORD_INDEX];
final String[] credentials = basicAuthenticationDecoder.decode(header);
final String email = credentials[EMAIL_INDEX];
final String password = credentials[PASSWORD_INDEX];
return new MemberCommand(email, password);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ public class AuthInterceptor implements HandlerInterceptor {
private final AuthenticationExtractor<MemberCommand> authenticationExtractor;
private final AuthService authService;

public AuthInterceptor(final AuthenticationExtractor<MemberCommand> authenticationExtractor, final AuthService authService) {
public AuthInterceptor(final AuthenticationExtractor<MemberCommand> authenticationExtractor,
final AuthService authService) {
this.authenticationExtractor = authenticationExtractor;
this.authService = authService;
}

@Override
public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler) throws Exception {
public boolean preHandle(final HttpServletRequest request,
final HttpServletResponse response,
final Object handler) throws Exception {
final MemberCommand memberCommand = authenticationExtractor.extract(request.getHeader(HttpHeaders.AUTHORIZATION));
authService.validateAuthentication(memberCommand);
request.setAttribute(AUTH_KEY, memberCommand);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.now.naaga.auth.presentation;

import static com.now.naaga.auth.presentation.AuthInterceptor.AUTH_KEY;

import com.now.naaga.auth.annotation.Auth;
import com.now.naaga.member.application.dto.MemberCommand;
import jakarta.servlet.http.HttpServletRequest;
Expand All @@ -12,6 +10,8 @@
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import static com.now.naaga.auth.presentation.AuthInterceptor.AUTH_KEY;

@Component
public class AuthenticationArgumentResolver implements HandlerMethodArgumentResolver {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@

import com.now.naaga.auth.presentation.AuthInterceptor;
import com.now.naaga.auth.presentation.AuthenticationArgumentResolver;
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class WebConfig implements WebMvcConfigurer {

private final AuthenticationArgumentResolver authenticationArgumentResolver;
private final AuthInterceptor authInterceptor;

public WebConfig(final AuthenticationArgumentResolver authenticationArgumentResolver, final AuthInterceptor authInterceptor) {
public WebConfig(final AuthenticationArgumentResolver authenticationArgumentResolver,
final AuthInterceptor authInterceptor) {
this.authenticationArgumentResolver = authenticationArgumentResolver;
this.authInterceptor = authInterceptor;
}
Expand All @@ -25,7 +27,7 @@ public void addInterceptors(final InterceptorRegistry registry) {
}

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
public void addArgumentResolvers(final List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(authenticationArgumentResolver);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package com.now.naaga.game.application;

import static com.now.naaga.game.exception.GameExceptionType.ALREADY_IN_PROGRESS;
import static com.now.naaga.game.exception.GameExceptionType.INACCESSIBLE_AUTHENTICATION;
import static com.now.naaga.game.exception.GameExceptionType.NOT_EXIST;

import com.now.naaga.game.domain.Game;
import com.now.naaga.game.domain.GameStatus;
import com.now.naaga.game.exception.GameException;
Expand All @@ -14,10 +10,13 @@
import com.now.naaga.place.application.PlaceService;
import com.now.naaga.place.domain.Place;
import com.now.naaga.place.domain.Position;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import static com.now.naaga.game.exception.GameExceptionType.*;

@Transactional
@Service
public class GameService {
Expand All @@ -26,13 +25,16 @@ public class GameService {
private final PlaceService placeService;
private final MemberService memberService;

public GameService(final GameRepository gameRepository, final PlaceService placeService, final MemberService memberService) {
public GameService(final GameRepository gameRepository,
final PlaceService placeService,
final MemberService memberService) {
this.gameRepository = gameRepository;
this.placeService = placeService;
this.memberService = memberService;
}

public Game createGame(final MemberCommand memberCommand, final Position position) {
public Game createGame(final MemberCommand memberCommand,
final Position position) {
final List<Game> gamesByStatus = findGamesByStatus(memberCommand, GameStatus.IN_PROGRESS.name());
if (!gamesByStatus.isEmpty()) {
throw new GameException(ALREADY_IN_PROGRESS);
Expand All @@ -43,8 +45,21 @@ public Game createGame(final MemberCommand memberCommand, final Position positio
return gameRepository.save(game);
}

public Game finishGame(final MemberCommand memberCommand,
final Position requestPosition,
final Long gameId) {
final Game game = gameRepository.findById(gameId)
.orElseThrow(() -> new GameException(NOT_EXIST));
Member member = memberService.findMemberByEmail(memberCommand.getEmail());
game.validateOwner(member);
game.validateInRange(requestPosition);
game.changeGameStatus(GameStatus.DONE);
return game;
}

@Transactional(readOnly = true)
public Game findGame(final MemberCommand memberCommand, final Long id) {
public Game findGame(final MemberCommand memberCommand,
final Long id) {
final Member member = memberService.findMemberByEmail(memberCommand.getEmail());
final Game game = gameRepository.findById(id)
.orElseThrow(() -> new GameException(NOT_EXIST));
Expand All @@ -55,7 +70,8 @@ public Game findGame(final MemberCommand memberCommand, final Long id) {
}

@Transactional(readOnly = true)
public List<Game> findGamesByStatus(final MemberCommand memberCommand, final String gameStatus) {
public List<Game> findGamesByStatus(final MemberCommand memberCommand,
final String gameStatus) {
final Member member = memberService.findMemberByEmail(memberCommand.getEmail());
final Long memberId = member.getId();

Expand Down
41 changes: 31 additions & 10 deletions backend/src/main/java/com/now/naaga/game/domain/Game.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package com.now.naaga.game.domain;

import com.now.naaga.game.exception.GameException;
import com.now.naaga.member.domain.Member;
import com.now.naaga.place.domain.Place;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import com.now.naaga.place.domain.Position;
import jakarta.persistence.*;

import java.util.Objects;

import static com.now.naaga.game.exception.GameExceptionType.INACCESSIBLE_AUTHENTICATION;
import static com.now.naaga.game.exception.GameExceptionType.NOT_ARRIVED;

@Entity
public class Game {

public static final double MIN_RANGE = 0.05;

@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Long id;
Expand All @@ -33,17 +34,37 @@ public class Game {
protected Game() {
}

public Game(final Member member, final Place place) {
public Game(final Member member,
final Place place) {
this(null, GameStatus.IN_PROGRESS, member, place);
}

public Game(final Long id, final GameStatus gameStatus, final Member member, final Place place) {
public Game(final Long id,
final GameStatus gameStatus,
final Member member,
final Place place) {
this.id = id;
this.gameStatus = gameStatus;
this.member = member;
this.place = place;
}

public void validateOwner(final Member member) {
if (!member.equals(this.member)) {
throw new GameException(INACCESSIBLE_AUTHENTICATION);
}
}

public void validateInRange(final Position position) {
if (!place.isInValidRange(position)) {
throw new GameException(NOT_ARRIVED);
}
}

public void changeGameStatus(final GameStatus gameStatus) {
this.gameStatus = gameStatus;
}

public Long getId() {
return id;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ public enum GameStatus {

IN_PROGRESS,
DONE,
;
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ public enum GameExceptionType implements BaseExceptionType {
private final HttpStatus httpStatus;
private final String errorMessage;

GameExceptionType(final int errorCode, final HttpStatus httpStatus, final String errorMessage) {
GameExceptionType(final int errorCode,
final HttpStatus httpStatus,
final String errorMessage) {
this.errorCode = errorCode;
this.httpStatus = httpStatus;
this.errorMessage = errorMessage;
Expand Down
Loading