diff --git a/build.gradle b/build.gradle index adbb027..641ccee 100644 --- a/build.gradle +++ b/build.gradle @@ -27,6 +27,8 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2' + implementation 'org.springframework.security:spring-security-crypto' + implementation 'org.springframework.boot:spring-boot-starter-validation' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' diff --git a/src/main/java/com/umc/hackaton/snapspot/config/SecurityConfig.java b/src/main/java/com/umc/hackaton/snapspot/config/SecurityConfig.java new file mode 100644 index 0000000..c846e46 --- /dev/null +++ b/src/main/java/com/umc/hackaton/snapspot/config/SecurityConfig.java @@ -0,0 +1,16 @@ +package com.umc.hackaton.snapspot.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class SecurityConfig { + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} + diff --git a/src/main/java/com/umc/hackaton/snapspot/config/entity/BaseEntity.java b/src/main/java/com/umc/hackaton/snapspot/config/entity/BaseEntity.java new file mode 100644 index 0000000..7516f39 --- /dev/null +++ b/src/main/java/com/umc/hackaton/snapspot/config/entity/BaseEntity.java @@ -0,0 +1,27 @@ +package com.umc.hackaton.snapspot.config.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; +import java.time.LocalDateTime; +import lombok.Getter; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +@MappedSuperclass +@Getter +@EntityListeners(AuditingEntityListener.class) +public abstract class BaseEntity { + + @CreatedDate + @Column(name = "created_at",updatable = false) + private LocalDateTime createdAt; + + @LastModifiedDate + @Column(name = "updated_at") + private LocalDateTime updatedAt; + + @Column(name = "deleted", nullable = false, columnDefinition = "bit(1) default 0") + private Boolean isDeleted = false; +} diff --git a/src/main/java/com/umc/hackaton/snapspot/user/controller/UserController.java b/src/main/java/com/umc/hackaton/snapspot/user/controller/UserController.java new file mode 100644 index 0000000..921d1ee --- /dev/null +++ b/src/main/java/com/umc/hackaton/snapspot/user/controller/UserController.java @@ -0,0 +1,27 @@ +package com.umc.hackaton.snapspot.user.controller; + +import com.umc.hackaton.snapspot.user.dto.UserRequestDto; +import com.umc.hackaton.snapspot.user.repository.UserRepository; +import com.umc.hackaton.snapspot.user.service.UserService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +@RequiredArgsConstructor +@RestController("/api/v1/users") +public class UserController { + + private final UserService userService; + + @PostMapping("/signup") + public ResponseEntity signUp(UserRequestDto dto) { + try { + userService.signUp(dto); + return ResponseEntity.ok().body("회원가입 성공."); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("회원가입에 실패하였습니다."); + } + } +} diff --git a/src/main/java/com/umc/hackaton/snapspot/user/dto/UserRequestDto.java b/src/main/java/com/umc/hackaton/snapspot/user/dto/UserRequestDto.java new file mode 100644 index 0000000..1d06235 --- /dev/null +++ b/src/main/java/com/umc/hackaton/snapspot/user/dto/UserRequestDto.java @@ -0,0 +1,22 @@ +package com.umc.hackaton.snapspot.user.dto; + +import com.umc.hackaton.snapspot.user.entity.User; +import lombok.Builder; +import lombok.Getter; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Getter +public class UserRequestDto { + private String userId; + private String password; + private String nickname; + + @Builder + public User toEntity(PasswordEncoder passwordEncoder) { + return User.builder() + .userId(userId) + .password(passwordEncoder.encode(password)) + .nickname(nickname) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/umc/hackaton/snapspot/user/dto/UserResponseDto.java b/src/main/java/com/umc/hackaton/snapspot/user/dto/UserResponseDto.java new file mode 100644 index 0000000..55cce2d --- /dev/null +++ b/src/main/java/com/umc/hackaton/snapspot/user/dto/UserResponseDto.java @@ -0,0 +1,10 @@ +package com.umc.hackaton.snapspot.user.dto; + +import lombok.Getter; + +@Getter + +public class UserResponseDto { + private String id; + private String password; +} diff --git a/src/main/java/com/umc/hackaton/snapspot/user/entity/User.java b/src/main/java/com/umc/hackaton/snapspot/user/entity/User.java new file mode 100644 index 0000000..7ee1652 --- /dev/null +++ b/src/main/java/com/umc/hackaton/snapspot/user/entity/User.java @@ -0,0 +1,35 @@ +package com.umc.hackaton.snapspot.user.entity; + +import com.umc.hackaton.snapspot.config.entity.BaseEntity; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "user") +public class User extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "nickname", nullable = false) + private String nickname; + + @Column(name = "user_id", nullable = false) + private String userId; + + @Column(name = "password", nullable = false) + private String password; + + @Column(name = "profile_img", nullable = false) + private String profileImg; + +} diff --git a/src/main/java/com/umc/hackaton/snapspot/user/repository/UserRepository.java b/src/main/java/com/umc/hackaton/snapspot/user/repository/UserRepository.java new file mode 100644 index 0000000..5e8ac12 --- /dev/null +++ b/src/main/java/com/umc/hackaton/snapspot/user/repository/UserRepository.java @@ -0,0 +1,10 @@ +package com.umc.hackaton.snapspot.user.repository; + +import com.umc.hackaton.snapspot.user.entity.User; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface UserRepository extends JpaRepository { + Optional findByUserId(String userId); +} diff --git a/src/main/java/com/umc/hackaton/snapspot/user/service/UserService.java b/src/main/java/com/umc/hackaton/snapspot/user/service/UserService.java new file mode 100644 index 0000000..8957fb5 --- /dev/null +++ b/src/main/java/com/umc/hackaton/snapspot/user/service/UserService.java @@ -0,0 +1,29 @@ +package com.umc.hackaton.snapspot.user.service; + +import com.umc.hackaton.snapspot.user.dto.UserRequestDto; +import com.umc.hackaton.snapspot.user.entity.User; +import com.umc.hackaton.snapspot.user.repository.UserRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class UserService { + + private final UserRepository userRepository; + private final BCryptPasswordEncoder encoder; + + @Transactional + public void signUp(UserRequestDto dto) { + +// Optional existingUser = userRepository.findByUserId(dto.getUserId()); +// if (existingUser.isPresent()) { +// User user = existingUser.get(); +// } else { + User user = dto.toEntity(encoder); + userRepository.save(user); + } +} +