diff --git a/src/main/java/com/archisemtle/semtlewebserverspring/application/member/AuthService.java b/src/main/java/com/archisemtle/semtlewebserverspring/application/member/AuthService.java new file mode 100644 index 0000000..bb9c6c8 --- /dev/null +++ b/src/main/java/com/archisemtle/semtlewebserverspring/application/member/AuthService.java @@ -0,0 +1,8 @@ +package com.archisemtle.semtlewebserverspring.application.member; + +import com.archisemtle.semtlewebserverspring.dto.member.MemberSignupRequestDto; + +public interface AuthService { + + void memberSignup(MemberSignupRequestDto memberSignupRequestDto); +} diff --git a/src/main/java/com/archisemtle/semtlewebserverspring/application/member/AuthServiceImpl.java b/src/main/java/com/archisemtle/semtlewebserverspring/application/member/AuthServiceImpl.java new file mode 100644 index 0000000..93803b2 --- /dev/null +++ b/src/main/java/com/archisemtle/semtlewebserverspring/application/member/AuthServiceImpl.java @@ -0,0 +1,49 @@ +package com.archisemtle.semtlewebserverspring.application.member; + +import com.archisemtle.semtlewebserverspring.common.BaseException; +import com.archisemtle.semtlewebserverspring.common.BaseResponseStatus; +import com.archisemtle.semtlewebserverspring.domain.Member; +import com.archisemtle.semtlewebserverspring.dto.member.MemberSignupRequestDto; +import com.archisemtle.semtlewebserverspring.infrastructure.MemberRepository; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +@Slf4j +public class AuthServiceImpl implements AuthService { + + private final MemberRepository memberRepository; + private final PasswordEncoder passwordEncoder; + + @Override + public void memberSignup(MemberSignupRequestDto memberSignupRequestDto) { + memberRepository.findByEmailOrStudentId(memberSignupRequestDto.getEmail(), + memberSignupRequestDto.getStudentId()) + .ifPresent(member -> { + if (member.getEmail().equals(memberSignupRequestDto.getEmail())) { + throw new BaseException(BaseResponseStatus.DUPLICATE_EMAIL); + } + if (member.getStudentId().equals(memberSignupRequestDto.getStudentId())) { + throw new BaseException(BaseResponseStatus.DUPLICATED_MEMBERS); + } + }); + + Member member = Member.builder() + .birth(memberSignupRequestDto.getBirth()) + .username(memberSignupRequestDto.getName()) + .uuid(UUID.randomUUID()) + .role("member") + .studentId(memberSignupRequestDto.getStudentId()) + .email(memberSignupRequestDto.getEmail()) + .password(passwordEncoder.encode(memberSignupRequestDto.getPassword())) + .build(); + + memberRepository.save(member); + } +} diff --git a/src/main/java/com/archisemtle/semtlewebserverspring/config/SecurityConfig.java b/src/main/java/com/archisemtle/semtlewebserverspring/config/SecurityConfig.java index 400494c..08c9062 100644 --- a/src/main/java/com/archisemtle/semtlewebserverspring/config/SecurityConfig.java +++ b/src/main/java/com/archisemtle/semtlewebserverspring/config/SecurityConfig.java @@ -49,7 +49,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti SessionCreationPolicy.STATELESS)) // Stateless 설정 .authorizeHttpRequests(auth -> auth - .requestMatchers(HttpMethod.POST, "/api/v1/members", "/api/v1/auth/signin") + .requestMatchers(HttpMethod.POST, "/api/v1/members", "/api/v1/auth/signin", + "/api/v1/auth/signup") .permitAll() .requestMatchers(HttpMethod.GET, "/api/v1/index/**", "/api/v1/projectboard/**", "/api/v1/promotions/**", "/api/v1/activity/**").permitAll() diff --git a/src/main/java/com/archisemtle/semtlewebserverspring/domain/Member.java b/src/main/java/com/archisemtle/semtlewebserverspring/domain/Member.java index a917619..f75650c 100644 --- a/src/main/java/com/archisemtle/semtlewebserverspring/domain/Member.java +++ b/src/main/java/com/archisemtle/semtlewebserverspring/domain/Member.java @@ -36,6 +36,7 @@ public class Member implements UserDetails { @Column(nullable = false) private String password; + @Column(nullable = false) private String studentId; private String username; diff --git a/src/main/java/com/archisemtle/semtlewebserverspring/dto/member/MemberSignupRequestDto.java b/src/main/java/com/archisemtle/semtlewebserverspring/dto/member/MemberSignupRequestDto.java new file mode 100644 index 0000000..922ec7c --- /dev/null +++ b/src/main/java/com/archisemtle/semtlewebserverspring/dto/member/MemberSignupRequestDto.java @@ -0,0 +1,20 @@ +package com.archisemtle.semtlewebserverspring.dto.member; + +import java.util.Date; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class MemberSignupRequestDto { + + private String email; + private String password; + private String name; + private Date birth; + private String studentId; + +} diff --git a/src/main/java/com/archisemtle/semtlewebserverspring/infrastructure/MemberRepository.java b/src/main/java/com/archisemtle/semtlewebserverspring/infrastructure/MemberRepository.java index cc9461e..9c56c05 100644 --- a/src/main/java/com/archisemtle/semtlewebserverspring/infrastructure/MemberRepository.java +++ b/src/main/java/com/archisemtle/semtlewebserverspring/infrastructure/MemberRepository.java @@ -18,4 +18,6 @@ public interface MemberRepository extends JpaRepository { Page findByUsernameContaining(String searchName, Pageable pageable); + Optional findByEmailOrStudentId(String email, String studentId); + } \ No newline at end of file diff --git a/src/main/java/com/archisemtle/semtlewebserverspring/presentation/AuthController.java b/src/main/java/com/archisemtle/semtlewebserverspring/presentation/AuthController.java index 1700d5c..5faa694 100644 --- a/src/main/java/com/archisemtle/semtlewebserverspring/presentation/AuthController.java +++ b/src/main/java/com/archisemtle/semtlewebserverspring/presentation/AuthController.java @@ -1,5 +1,6 @@ package com.archisemtle.semtlewebserverspring.presentation; +import com.archisemtle.semtlewebserverspring.application.member.AuthService; import com.archisemtle.semtlewebserverspring.application.member.MemberService; import com.archisemtle.semtlewebserverspring.application.member.PasswordResetService; import com.archisemtle.semtlewebserverspring.common.BaseException; @@ -14,6 +15,7 @@ import com.archisemtle.semtlewebserverspring.infrastructure.MemberRepository; import com.archisemtle.semtlewebserverspring.vo.member.LoginResponseVo; import com.archisemtle.semtlewebserverspring.vo.member.MemberPasswordResetResponseVo; +import com.archisemtle.semtlewebserverspring.vo.member.MemberSignupRequestVo; import io.swagger.v3.oas.annotations.Operation; import java.util.UUID; import lombok.RequiredArgsConstructor; @@ -32,6 +34,7 @@ public class AuthController { private final MemberService memberService; + private final AuthService authService; private final PasswordResetService passwordResetService; private final MemberRepository memberRepository; @@ -90,4 +93,11 @@ public CommonResponse verifyAdmin( return CommonResponse.success("관리자 2차인증에 성공하셨습니다."); } + + @PostMapping("/signup") + public CommonResponse memberSignUp( + @RequestBody MemberSignupRequestVo memberSignupRequestVo) { + authService.memberSignup(MemberSignupRequestVo.voToDto(memberSignupRequestVo)); + return CommonResponse.success("회원가입을 성공했습니다."); + } } diff --git a/src/main/java/com/archisemtle/semtlewebserverspring/vo/member/MemberSignupRequestVo.java b/src/main/java/com/archisemtle/semtlewebserverspring/vo/member/MemberSignupRequestVo.java new file mode 100644 index 0000000..2a436de --- /dev/null +++ b/src/main/java/com/archisemtle/semtlewebserverspring/vo/member/MemberSignupRequestVo.java @@ -0,0 +1,28 @@ +package com.archisemtle.semtlewebserverspring.vo.member; + +import com.archisemtle.semtlewebserverspring.dto.member.MemberSignupRequestDto; +import java.util.Date; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +public class MemberSignupRequestVo { + + private String email; + private String password; + private String name; + private Date birth; + private String studentId; + + public static MemberSignupRequestDto voToDto(MemberSignupRequestVo memberSignupRequestVo) { + return MemberSignupRequestDto.builder() + .birth(memberSignupRequestVo.getBirth()) + .email(memberSignupRequestVo.getEmail()) + .studentId(memberSignupRequestVo.getStudentId()) + .name(memberSignupRequestVo.getName()) + .password(memberSignupRequestVo.getPassword()) + .build(); + } +}