Skip to content

Commit

Permalink
Merge pull request #17 from PSR-Co/feat/#15-valid-signup
Browse files Browse the repository at this point in the history
[fix] 회원가입 API Valid Annotation 적용
  • Loading branch information
chaerlo127 authored Jul 27, 2023
2 parents 7f55ffb + 3c9708e commit 06276bb
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 34 deletions.
3 changes: 3 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ dependencies {

//log
implementation ("io.github.microutils:kotlin-logging:3.0.5")

// valid
implementation("org.springframework.boot:spring-boot-starter-validation")
}

allOpen {
Expand Down
13 changes: 2 additions & 11 deletions src/main/kotlin/com/psr/psr/global/Constant.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
package com.psr.psr.global

class Constant {
class JWT{
companion object JWT{
class JWT {
companion object JWT {
const val AUTHORIZATION_HEADER = "Authorization"
const val BEARER_PREFIX: String = "Bearer "
}
}

class User{
companion object User{
// 비밀번호 (숫자, 문자, 특수문자 포함 8~15자리 이내)
const val PASSWORD_VALIDATION = "^.*(?=^.{8,15}\$)(?=.*\\d)(?=.*[a-zA-Z])(?=.*[!@#\$%^&+=]).*\$"
const val EMAIL_VALIDATION = "^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}\$"
const val PHONE_VALIDATION = "^01([0|1|6|7|8|9])-?([0-9]{3,4})-?([0-9]{4})\$"
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ enum class BaseResponseCode(status: HttpStatus, message: String) {
EXPIRED_TOKEN(HttpStatus.FORBIDDEN, "만료된 토큰 값입니다."),

// user
INVALID_EMAIL(HttpStatus.BAD_REQUEST, "올바르지 않은 이메일 형식입니다."),
INVALID_PASSWORD(HttpStatus.BAD_REQUEST, "올바르지 않은 비밀번호 형식입니다."),
INVALID_PHONE(HttpStatus.BAD_REQUEST, "올바르지 않은 휴대폰 형식입니다."),
EXISTS_PHONE(HttpStatus.BAD_REQUEST, "이미 가입되어 있는 휴대폰 번호입니다."),
EXISTS_EMAIL(HttpStatus.BAD_REQUEST, "이미 가입되어 있는 이메일입니다."),
EXISTS_NICKNAME(HttpStatus.BAD_REQUEST, "이미 가입되어 있는 닉네임입니다."),
Expand Down
15 changes: 14 additions & 1 deletion src/main/kotlin/com/psr/psr/global/exception/ExceptionHandler.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package com.psr.psr.global.exception

import com.psr.psr.global.dto.BaseResponse
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.validation.FieldError
import org.springframework.web.bind.MethodArgumentNotValidException
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.RestControllerAdvice
import java.util.*


@RestControllerAdvice
class ExceptionHandler {
Expand All @@ -12,4 +17,12 @@ class ExceptionHandler {
return ResponseEntity.status(e.baseResponseCode.status)
.body(BaseRes(e.baseResponseCode.status.value(), e.baseResponseCode.message))
}

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException::class)
protected fun handleMethodArgumentNotValidException(e:MethodArgumentNotValidException): ResponseEntity<BaseRes>{
val fieldError = Objects.requireNonNull(e.fieldError)
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(BaseRes(HttpStatus.BAD_REQUEST.value(), String.format("%s", fieldError?.defaultMessage)))
}
}
4 changes: 2 additions & 2 deletions src/main/kotlin/com/psr/psr/user/controller/UserController.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.psr.psr.user.controller

import com.psr.psr.global.dto.BaseResponse
import com.psr.psr.global.exception.BaseResponseCode
import com.psr.psr.global.jwt.dto.TokenRes
import com.psr.psr.user.dto.SignUpReq
import com.psr.psr.user.service.UserService
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*

@RestController
Expand All @@ -17,7 +17,7 @@ class UserController(
*/
@PostMapping("/signup")
@ResponseBody
fun signUp (@RequestBody signUpReq: SignUpReq) : BaseResponse<TokenRes>{
fun signUp (@RequestBody @Validated signUpReq: SignUpReq) : BaseResponse<TokenRes>{
return BaseResponse(userService.signUp(signUpReq))
}
}
27 changes: 23 additions & 4 deletions src/main/kotlin/com/psr/psr/user/dto/SignUpReq.kt
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@
package com.psr.psr.user.dto

import com.psr.psr.user.entity.*
import java.util.stream.Collector
import jakarta.annotation.Nullable
import jakarta.validation.constraints.Email
import jakarta.validation.constraints.NotBlank
import jakarta.validation.constraints.NotEmpty
import jakarta.validation.constraints.Pattern
import org.jetbrains.annotations.NotNull
import java.util.stream.Collectors




data class SignUpReq (
@field:NotBlank
@field:Email(message = "올바르지 않은 이메일 형식입니다.")
val email: String,
@field:NotBlank
@field:Pattern(
regexp = "^.*(?=^.{8,15}\$)(?=.*\\d)(?=.*[a-zA-Z])(?=.*[!@#\$%^&+=]).*\$",
message = "비밀번호를 숫자, 문자, 특수문자 포함 8~15자리 이내로 입력해주세요"
)
var password: String,
@field:NotBlank
val type: String,
@field:Pattern(
regexp = "^01([0|1|6|7|8|9])-?([0-9]{3,4})-?([0-9]{4})\$",
message = "올바르지 않은 휴대폰 형식입니다."
)
val phone: String,
val imgKey: String,
@field:Nullable
val imgKey: String? = null,
@field:NotBlank
val nickname: String,
val marketing: Boolean,
@field:NotNull
val notification: Boolean,
@field:NotEmpty
val interestList: List<UserInterestReq>
) {
fun toEntity(): User {
Expand Down
13 changes: 0 additions & 13 deletions src/main/kotlin/com/psr/psr/user/service/UserService.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
package com.psr.psr.user.service

import com.fasterxml.jackson.databind.ser.Serializers.Base
import com.psr.psr.global.Constant.User.User.EMAIL_VALIDATION
import com.psr.psr.global.Constant.User.User.PASSWORD_VALIDATION
import com.psr.psr.global.Constant.User.User.PHONE_VALIDATION
import com.psr.psr.global.exception.BaseException
import com.psr.psr.global.exception.BaseResponseCode
import com.psr.psr.global.jwt.dto.TokenRes
import com.psr.psr.global.jwt.utils.JwtUtils
import com.psr.psr.user.dto.SignUpReq
import com.psr.psr.user.entity.Category
import com.psr.psr.user.entity.User
import com.psr.psr.user.entity.UserInterest
import com.psr.psr.user.repository.UserInterestRepository
import com.psr.psr.user.repository.UserRepository
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
Expand All @@ -35,13 +29,6 @@ class UserService(
// 회원가입
@Transactional
fun signUp(signUpReq: SignUpReq): TokenRes {
// 이메일의 형식이 맞는지 확인
if(!isValidRegularExpression(signUpReq.email, EMAIL_VALIDATION)) throw BaseException(BaseResponseCode.INVALID_EMAIL)
// 비밀번호의 형식이 맞는지 확인
if(!isValidRegularExpression(signUpReq.password, PASSWORD_VALIDATION)) throw BaseException(BaseResponseCode.INVALID_PASSWORD)
// 휴대폰 번호의 형식이 맞는지 확인
if(!isValidRegularExpression(signUpReq.phone, PHONE_VALIDATION)) throw BaseException(BaseResponseCode.INVALID_PHONE)
// Category가 알맞은 이름을 갖고 있는지, 값이 중복되어있는지 확인
val categoryCheck = signUpReq.interestList.stream().map { i -> i.checkInterestCategory() }.collect(Collectors.toList()).groupingBy { it }.eachCount().any { it.value > 1 }
if(categoryCheck) throw BaseException(BaseResponseCode.INVALID_USER_INTEREST_COUNT)
// category 의 사이즈 확인
Expand Down

0 comments on commit 06276bb

Please sign in to comment.