diff --git a/.docker/docker-compose.yml b/.docker/docker-compose.yml index d1faef5..145be23 100644 --- a/.docker/docker-compose.yml +++ b/.docker/docker-compose.yml @@ -34,6 +34,7 @@ services: APPLE_CLIENT_ID: ${APPLE_CLIENT_ID} KAKAO_ADMIN_KEY: ${KAKAO_ADMIN_KEY} INVITATION_CODE_KEY: ${INVITATION_CODE_KEY} + APP_MINIMUM_VERSION: ${APP_MINIMUM_VERSION} volumes: - ./logfile:/logs diff --git a/src/main/java/com/moneymong/global/config/security/SecurityConfig.java b/src/main/java/com/moneymong/global/config/security/SecurityConfig.java index 759a99a..4e46e99 100644 --- a/src/main/java/com/moneymong/global/config/security/SecurityConfig.java +++ b/src/main/java/com/moneymong/global/config/security/SecurityConfig.java @@ -36,6 +36,7 @@ public SecurityFilterChain httpSecurity(HttpSecurity http) throws Exception { auth.requestMatchers("/favicon.ico").permitAll(); auth.requestMatchers("/api/v1/users").permitAll(); auth.requestMatchers("/api/v1/tokens").permitAll(); + auth.requestMatchers("/api/v1/version").permitAll(); auth.requestMatchers("/actuator/**").permitAll(); auth.anyRequest().authenticated(); }) diff --git a/src/main/java/com/moneymong/global/exception/enums/ErrorCode.java b/src/main/java/com/moneymong/global/exception/enums/ErrorCode.java index c9098b9..16e3206 100644 --- a/src/main/java/com/moneymong/global/exception/enums/ErrorCode.java +++ b/src/main/java/com/moneymong/global/exception/enums/ErrorCode.java @@ -11,6 +11,7 @@ public enum ErrorCode { BAD_REQUEST(MoneymongConstant.BAD_REQUEST, "GLOBAL-400", "잘못된 요청입니다."), ACCESS_DENIED(MoneymongConstant.FORBIDDEN, "GLOBAL-403", "접근 권한이 없습니다."), INTERNAL_SERVER(MoneymongConstant.INTERNAL_SERVER_ERROR, "GLOBAL-500", "서버 내부 오류입니다."), + VERSION_TOO_LOW(MoneymongConstant.BAD_REQUEST, "GLOBAL-400", "앱 업데이트가 필요합니다."), // ---- 유저 ---- // USER_NOT_FOUND(MoneymongConstant.NOT_FOUND, "USER-001", "존재하지 않는 회원입니다."), diff --git a/src/main/java/com/moneymong/global/version/VersionController.java b/src/main/java/com/moneymong/global/version/VersionController.java new file mode 100644 index 0000000..7eb0db5 --- /dev/null +++ b/src/main/java/com/moneymong/global/version/VersionController.java @@ -0,0 +1,45 @@ +package com.moneymong.global.version; + +import com.moneymong.global.exception.enums.ErrorCode; +import com.moneymong.global.version.dto.VersionRequest; +import com.moneymong.global.version.exception.VersionTooLowException; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1/version") +public class VersionController { + + @Value("${app.minimum.version}") + private String minimumAppVersion; + + @PostMapping + public String checkVersion(@RequestBody VersionRequest request) { + if (isVersionLower(request.getVersion(), minimumAppVersion)) { + throw new VersionTooLowException(ErrorCode.VERSION_TOO_LOW); + } + + return "Version is up to date."; + } + + private boolean isVersionLower(String currentVersion, String minimumVersion) { + String[] currentParts = currentVersion.split("\\."); + String[] minimumParts = minimumVersion.split("\\."); + + int length = Math.max(currentParts.length, minimumParts.length); + for (int i = 0; i < length; i++) { + int currentPart = i < currentParts.length ? Integer.parseInt(currentParts[i]) : 0; + int minimumPart = i < minimumParts.length ? Integer.parseInt(minimumParts[i]) : 0; + + if (currentPart < minimumPart) { + return true; + } else if (currentPart > minimumPart) { + return false; + } + } + return false; + } +} diff --git a/src/main/java/com/moneymong/global/version/dto/VersionRequest.java b/src/main/java/com/moneymong/global/version/dto/VersionRequest.java new file mode 100644 index 0000000..371cdb7 --- /dev/null +++ b/src/main/java/com/moneymong/global/version/dto/VersionRequest.java @@ -0,0 +1,8 @@ +package com.moneymong.global.version.dto; + +import lombok.Getter; + +@Getter +public class VersionRequest { + private String version; +} diff --git a/src/main/java/com/moneymong/global/version/exception/VersionTooLowException.java b/src/main/java/com/moneymong/global/version/exception/VersionTooLowException.java new file mode 100644 index 0000000..6402229 --- /dev/null +++ b/src/main/java/com/moneymong/global/version/exception/VersionTooLowException.java @@ -0,0 +1,14 @@ +package com.moneymong.global.version.exception; + +import com.moneymong.global.exception.custom.BusinessException; +import com.moneymong.global.exception.enums.ErrorCode; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.BAD_REQUEST) +public class VersionTooLowException extends BusinessException { + + public VersionTooLowException(ErrorCode errorCode) { + super(errorCode); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index fe1b988..d1d7f97 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -70,3 +70,7 @@ decorator: agency: invitation-code: key: ${INVITATION_CODE_KEY} + +app: + minimum: + version: ${APP_MINIMUM_VERSION} \ No newline at end of file