Skip to content

Commit

Permalink
Merge pull request #42 from GSM-MSG/40-feat/signin
Browse files Browse the repository at this point in the history
# 40 로그인 기능 구현
  • Loading branch information
JuuuuHong authored Oct 20, 2023
2 parents 4cfe1a6 + 57caeda commit ce08db8
Show file tree
Hide file tree
Showing 13 changed files with 96 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ class SecurityUtil(
) {
fun passwordEncode(password: String): String =
passwordEncoder.encode(password)

fun isPasswordMatch(currentPassword: String, encodedPassword: String): Boolean =
passwordEncoder.matches(currentPassword, encodedPassword)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package team.msg.domain.auth.exception

import team.msg.domain.auth.exception.constant.AuthErrorCode
import team.msg.global.error.exception.BitgouelException

class MisMatchPasswordException(
message: String
) : BitgouelException(message, AuthErrorCode.MISMATCH_PASSWORD.status)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package team.msg.domain.auth.exception

import team.msg.domain.auth.exception.constant.AuthErrorCode
import team.msg.global.error.exception.BitgouelException

class UnApprovedUserException(
message: String
) : BitgouelException(message, AuthErrorCode.UNAPPROVED_USER.status)
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ enum class AuthErrorCode(
val status: Int
) {
ALREADY_EXIST_EMAIL("이미 가입된 이메일입니다.", 409),
ALREADY_EXIST_PHONE_NUMBER("이미 가입된 전화번호입니다.", 409)
ALREADY_EXIST_PHONE_NUMBER("이미 가입된 전화번호입니다.", 409),
MISMATCH_PASSWORD("일치하지 않는 비밀번호입니다.", 401),
UNAPPROVED_USER("아직 회원가입 대기 상태입니다.", 401)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ interface AuthRequestMapper {
fun professorSignUpWebRequestToDto(webRequest: ProfessorSignUpWebRequest): ProfessorSignUpRequest
fun governmentSignUpWebRequestToDto(webRequest: GovernmentSignUpWebRequest): GovernmentSignUpRequest
fun companyInstructorSignUpWebRequestToDto(webRequest: CompanyInstructorSignUpWebRequest): CompanyInstructorSignUpRequest
fun loginWebRequestToDto(webRequest: LoginWebRequest): LoginRequest
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,13 @@ class AuthRequestMapperImpl : AuthRequestMapper {
clubName = webRequest.clubName,
company = webRequest.company
)

/**
* 로그인 Web Request 를 애플리케이션 영역에서 사용될 Dto 로 매핑합니다.
*/
override fun loginWebRequestToDto(webRequest: LoginWebRequest): LoginRequest =
LoginRequest(
email = webRequest.email,
password = webRequest.password
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import team.msg.domain.auth.mapper.AuthRequestMapper
import team.msg.domain.auth.presentation.data.response.TokenResponse
import team.msg.domain.auth.presentation.data.web.*
import team.msg.domain.auth.service.AuthService

Expand Down Expand Up @@ -46,4 +47,10 @@ class AuthController(
authService.companyInstructorSignUp(authRequestMapper.companyInstructorSignUpWebRequestToDto(request))
return ResponseEntity.status(HttpStatus.CREATED).build()
}

@PostMapping("/login")
fun login(@RequestBody @Valid request: LoginWebRequest): ResponseEntity<TokenResponse> {
val response = authService.login(authRequestMapper.loginWebRequestToDto(request))
return ResponseEntity.ok(response)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package team.msg.domain.auth.presentation.data.request

data class LoginRequest(
val email: String,
val password: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package team.msg.domain.auth.presentation.data.web

import javax.validation.constraints.Email
import javax.validation.constraints.NotNull
import javax.validation.constraints.Pattern

data class LoginWebRequest(
@field:Email
@field:NotNull
val email: String,

@field:Pattern(regexp = "^(?=.*[A-Za-z0-9])[A-Za-z0-9!@#\\\\\$%^&*]{8,24}\$")
val password: String
)
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package team.msg.domain.auth.service

import team.msg.domain.auth.presentation.data.request.*
import team.msg.domain.auth.presentation.data.response.TokenResponse

interface AuthService {
fun studentSignUp(studentSignUpRequest: StudentSignUpRequest)
fun teacherSignUp(teacherSignUpRequest: TeacherSignUpRequest)
fun professorSignUp(professorSignUpRequest: ProfessorSignUpRequest)
fun governmentSignUp(governmentSignUpRequest: GovernmentSignUpRequest)
fun companyInstructorSignUp(companyInstructorSignUpRequest: CompanyInstructorSignUpRequest)
fun login(request: LoginRequest): TokenResponse
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import team.msg.common.enum.ApproveStatus
import team.msg.common.util.SecurityUtil
import team.msg.domain.auth.exception.AlreadyExistEmailException
import team.msg.domain.auth.exception.AlreadyExistPhoneNumberException
import team.msg.domain.auth.exception.MisMatchPasswordException
import team.msg.domain.auth.exception.UnApprovedUserException
import team.msg.domain.auth.presentation.data.request.*
import team.msg.domain.auth.presentation.data.response.TokenResponse
import team.msg.domain.club.exception.ClubNotFoundException
import team.msg.domain.club.model.Club
import team.msg.domain.club.repository.ClubRepository
Expand All @@ -25,8 +28,10 @@ import team.msg.domain.student.repository.StudentRepository
import team.msg.domain.teacher.model.Teacher
import team.msg.domain.teacher.repository.TeacherRepository
import team.msg.domain.user.enums.Authority
import team.msg.domain.user.exception.UserNotFoundException
import team.msg.domain.user.model.User
import team.msg.domain.user.repository.UserRepository
import team.msg.global.security.jwt.JwtTokenGenerator
import java.util.*

@Service
Expand All @@ -39,11 +44,12 @@ class AuthServiceImpl(
private val teacherRepository: TeacherRepository,
private val professorRepository: ProfessorRepository,
private val governmentRepository: GovernmentRepository,
private val companyInstructorRepository: CompanyInstructorRepository
private val companyInstructorRepository: CompanyInstructorRepository,
private val jwtTokenGenerator: JwtTokenGenerator
) : AuthService {

/**
* 학생 회원가입을 처리해주는 비지니스 로직입니다.
* 학생 회원가입을 처리하는 비지니스 로직입니다.
* @param StudentSignUpRequest
*/
@Transactional(rollbackFor = [Exception::class])
Expand Down Expand Up @@ -73,7 +79,7 @@ class AuthServiceImpl(
}

/**
* 취동샘 회원가입을 처리해주는 비지니스 로직입니다.
* 취동샘 회원가입을 처리하는 비지니스 로직입니다.
* @param TeacherSignUpRequest
*/
@Transactional(rollbackFor = [Exception::class])
Expand All @@ -97,7 +103,7 @@ class AuthServiceImpl(
}

/**
* 대학교수 회원가입을 처리해주는 비지니스 로직입니다.
* 대학교수 회원가입을 처리하는 비지니스 로직입니다.
* @param ProfessorSignUpRequest
*/
@Transactional(rollbackFor = [Exception::class])
Expand All @@ -122,9 +128,10 @@ class AuthServiceImpl(
}

/**
* 유관 기관 회원가입을 처리해주는 비지니스 로직입니다.
* 유관 기관 회원가입을 처리하는 비지니스 로직입니다.
* @param GovernmentSignUpRequest
*/
@Transactional(rollbackFor = [Exception::class])
override fun governmentSignUp(request: GovernmentSignUpRequest) {
val user = createUser(
request.email,
Expand All @@ -146,9 +153,10 @@ class AuthServiceImpl(
}

/**
* 기업 강사 회원가입을 처리해주는 비지니스 로직입니다.
* 기업 강사 회원가입을 처리하는 비지니스 로직입니다.
* @param CompanyInstructorSignUpRequest
*/
@Transactional(rollbackFor = [Exception::class])
override fun companyInstructorSignUp(request: CompanyInstructorSignUpRequest) {
val user = createUser(request.email, request.name, request.phoneNumber, request.password, Authority.ROLE_COMPANY_INSTRUCTOR)

Expand All @@ -164,7 +172,25 @@ class AuthServiceImpl(
}

/**
* 유저 생성과 검증을 처리해주는 private 메서드입니다.
* 로그인을 처리하는 비지니스 로직입니다.
* @param LoginRequest
*/
@Transactional(readOnly = true)
override fun login(request: LoginRequest): TokenResponse {
val user = userRepository.findByEmail(request.email)
?: throw UserNotFoundException("존재하지 않는 유저입니다.")

if (!securityUtil.isPasswordMatch(request.password, user.password))
throw MisMatchPasswordException("비말번호가 일치하지 않습니다. info : [ password = ${request.password} ]")

if (user.approveStatus == ApproveStatus.PENDING)
throw UnApprovedUserException("아직 회원가입 대기 중인 유저입니다. info : [ user = ${user.name} ]")

return jwtTokenGenerator.generateToken(user.id, user.authority)
}

/**
* 유저 생성과 검증을 처리하는 private 메서드입니다.
* @param email, name, phoneNumber, password, authority
*/
private fun createUser(email: String, name: String, phoneNumber: String, password: String, authority: Authority): User {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class SecurityConfig(
.mvcMatchers(HttpMethod.POST, "/auth/professor").permitAll()
.mvcMatchers(HttpMethod.POST, "/auth/government").permitAll()
.mvcMatchers(HttpMethod.POST, "/auth/company-instructor").permitAll()
.mvcMatchers(HttpMethod.POST, "/auth/login").permitAll()

.anyRequest().authenticated()
.and()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ import java.util.UUID
interface UserRepository : CrudRepository<User, UUID> {
fun existsByEmail(email: String): Boolean
fun existsByPhoneNumber(phoneNumber: String): Boolean
fun findByEmail(email: String): User?
}

0 comments on commit ce08db8

Please sign in to comment.