diff --git a/build.gradle b/build.gradle index 41f9996..3f4cdca 100644 --- a/build.gradle +++ b/build.gradle @@ -24,17 +24,16 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-security' - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' - implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'com.google.guava:guava:28.2-jre' implementation 'org.apache.commons:commons-lang3:3.9' implementation 'org.springframework.boot:spring-boot-starter-mail' + compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1' compileOnly 'org.projectlombok:lombok' runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' testImplementation 'org.springframework.boot:spring-boot-starter-test' - implementation 'jakarta.persistence:jakarta.persistence-api' + implementation 'jakarta.persistence:jakarta.persistence-api:3.1.0' implementation 'io.jsonwebtoken:jjwt-api:0.11.5' implementation 'org.springframework.security:spring-security-oauth2-core:5.7.3' implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' diff --git a/src/main/generated/site/moasis/monolithicbe/service/CommentInfoMapperImpl.java b/src/main/generated/site/moasis/monolithicbe/service/CommentInfoMapperImpl.java index 83b43f1..e1b08eb 100644 --- a/src/main/generated/site/moasis/monolithicbe/service/CommentInfoMapperImpl.java +++ b/src/main/generated/site/moasis/monolithicbe/service/CommentInfoMapperImpl.java @@ -5,8 +5,8 @@ @Generated( value = "org.mapstruct.ap.MappingProcessor", - date = "2023-01-27T23:07:40+0900", - comments = "version: 1.4.2.Final, compiler: javac, environment: Java 17.0.5 (Amazon.com Inc.)" + date = "2023-01-29T22:01:20+0900", + comments = "version: 1.4.2.Final, compiler: javac, environment: Java 19.0.2 (Oracle Corporation)" ) public class CommentInfoMapperImpl implements CommentInfoMapper { @@ -20,6 +20,7 @@ public CommentInfo toCommentInfo(Comment comment) { commentInfo.setCommentId( comment.getId() ); commentInfo.setCreatedAt( comment.getCreatedAt() ); + commentInfo.setUserName( comment.getUserName() ); commentInfo.setContent( comment.getContent() ); commentInfo.setIsDeleted( comment.getIsDeleted() ); diff --git a/src/main/java/site/moasis/monolithicbe/MonolithicBeApplication.java b/src/main/java/site/moasis/monolithicbe/MonolithicBeApplication.java index 63418d2..138711b 100644 --- a/src/main/java/site/moasis/monolithicbe/MonolithicBeApplication.java +++ b/src/main/java/site/moasis/monolithicbe/MonolithicBeApplication.java @@ -7,10 +7,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import site.moasis.monolithicbe.domain.article.entity.Article; +import site.moasis.monolithicbe.domain.article.repository.ArticleRepository; import site.moasis.monolithicbe.domain.useraccount.UserRole; import site.moasis.monolithicbe.domain.useraccount.entity.UserAccount; import site.moasis.monolithicbe.domain.useraccount.repository.UserAccountRepository; -import site.moasis.monolithicbe.infrastructure.article.ArticleRepository; @EnableJpaAuditing @SpringBootApplication @@ -43,6 +43,7 @@ public void run(ApplicationArguments args) { .build()); articleRepository.save(Article.builder() + .title("게시글 예시 제목") .content("게시글 예시 내용") .build()); } diff --git a/src/main/java/site/moasis/monolithicbe/configuration/SecurityConfig.java b/src/main/java/site/moasis/monolithicbe/configuration/SecurityConfig.java index 236fd6d..bbbf70b 100644 --- a/src/main/java/site/moasis/monolithicbe/configuration/SecurityConfig.java +++ b/src/main/java/site/moasis/monolithicbe/configuration/SecurityConfig.java @@ -4,30 +4,28 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; +import org.springframework.security.config.annotation.SecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.DefaultSecurityFilterChain; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.web.filter.CorsFilter; -import site.moasis.monolithicbe.domain.useraccount.AccessTokenManager; import site.moasis.monolithicbe.domain.useraccount.JwtAccessDeniedHandler; import site.moasis.monolithicbe.domain.useraccount.JwtAuthenticationEntryPoint; -import site.moasis.monolithicbe.domain.useraccount.service.PrincipalOauth2UserService; - +import site.moasis.monolithicbe.domain.useraccount.AccessTokenManager; @RequiredArgsConstructor @EnableWebSecurity @Configuration -public class SecurityConfig { - +public class SecurityConfig extends SecurityConfigurerAdapter { private final CorsFilter corsFilter; private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; private final JwtAccessDeniedHandler jwtAccessDeniedHandler; private final AccessTokenManager accessTokenManager; - private final PrincipalOauth2UserService principalOauth2UserService; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { @@ -44,19 +42,12 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and().authorizeHttpRequests() - .requestMatchers(HttpMethod.POST, "/users").permitAll() + .requestMatchers(HttpMethod.POST,"/users").permitAll() .requestMatchers("/users/signin").permitAll() - .requestMatchers("/users/**").permitAll() .anyRequest().permitAll() .and() - .apply(new JwtSecurityConfig(accessTokenManager)) - - .and() - .oauth2Login() - .defaultSuccessUrl("/users/authorization/success") - .userInfoEndpoint() - .userService(principalOauth2UserService); + .apply(new JwtSecurityConfig(accessTokenManager)); return http.build(); } diff --git a/src/main/java/site/moasis/monolithicbe/controller/article/ArticleController.java b/src/main/java/site/moasis/monolithicbe/controller/article/ArticleController.java deleted file mode 100644 index 015410e..0000000 --- a/src/main/java/site/moasis/monolithicbe/controller/article/ArticleController.java +++ /dev/null @@ -1,4 +0,0 @@ -package site.moasis.monolithicbe.controller.article; - -public class ArticleController { -} diff --git a/src/main/java/site/moasis/monolithicbe/controller/article/ArticleReadController.java b/src/main/java/site/moasis/monolithicbe/controller/article/ArticleReadController.java new file mode 100644 index 0000000..e266298 --- /dev/null +++ b/src/main/java/site/moasis/monolithicbe/controller/article/ArticleReadController.java @@ -0,0 +1,73 @@ +package site.moasis.monolithicbe.controller.article; + + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import site.moasis.monolithicbe.controller.common.CommonResponse; +import site.moasis.monolithicbe.domain.article.service.ArticleReadService; + +import java.util.UUID; + + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1") + +@Tag(name = "ArticleReadController", description = "게시글을 각 속성 값으로 조회 가능하다") +public class ArticleReadController { + + private final ArticleReadService articleReadService; + + @GetMapping("/articles") + @Operation(summary = "게시글 전체 조회") + public ResponseEntity> searchAll() { + var articleInfo = articleReadService.searchArticles(); + return ResponseEntity + .status(HttpStatus.OK) + .body(CommonResponse.success(articleInfo, "게시글 검색 결과")); + } + + @GetMapping("/articles/{articleId}") + @Operation(summary = "article_id로 게시글 단건 조회") + public ResponseEntity> searchOne(@PathVariable UUID articleId) { + var articleInfo = articleReadService.searchOne(articleId); + return ResponseEntity + .status(HttpStatus.OK) + .body(CommonResponse.success(articleInfo, "게시글 검색 결과")); + } + + @GetMapping("/articles/userId/{userId}") + @Operation(summary = "user_id로 게시글 조회") + public ResponseEntity> searchByUserId(@PathVariable UUID userId) { + var articleInfo = articleReadService.searchByUserId(userId); + return ResponseEntity + .status(HttpStatus.OK) + .body(CommonResponse.success(articleInfo, userId + "검색 결과")); + } + + @GetMapping("/articles/title/{title}") + @Operation(summary = "제목으로 게시글 조회") + public ResponseEntity> searchByTitle(@PathVariable String title) { + var articleInfo = articleReadService.searchBytitle(title); + return ResponseEntity + .status(HttpStatus.OK) + .body(CommonResponse.success(articleInfo, title + "검색 결과")); + } + + @GetMapping("/articles/content/{content}") + @Operation(summary = "내용으로 게시글 조회") + public ResponseEntity> searchByContent(@PathVariable String content) { + var articleInfo = articleReadService.searchBycontent(content); + return ResponseEntity + .status(HttpStatus.OK) + .body(CommonResponse.success(articleInfo, content + "검색 결과")); + } + +} diff --git a/src/main/java/site/moasis/monolithicbe/controller/article/ArticleWriteController.java b/src/main/java/site/moasis/monolithicbe/controller/article/ArticleWriteController.java new file mode 100644 index 0000000..a8a2ba5 --- /dev/null +++ b/src/main/java/site/moasis/monolithicbe/controller/article/ArticleWriteController.java @@ -0,0 +1,59 @@ +package site.moasis.monolithicbe.controller.article; + + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import site.moasis.monolithicbe.controller.common.CommonResponse; +import site.moasis.monolithicbe.domain.article.dto.ArticleRequest; +import site.moasis.monolithicbe.domain.article.service.ArticleWriteService; + +import java.util.UUID; + +import static site.moasis.monolithicbe.domain.article.service.ArticleCommand.CreateCommand; + + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1") + +@Tag(name = "ArticleWriteController", description = "게시글을 각 속성 값으로 생성, 삭제, 수정 가능하다") +public class ArticleWriteController { + + private final ArticleWriteService articleWriteService; + + @PostMapping("/article") + @Operation(summary = "게시글 생성") + public ResponseEntity> createArticle( + @RequestBody ArticleRequest articleRequest + ) { + var command = CreateCommand + .builder() + .title(articleRequest.title()) + .content(articleRequest.content()) + .build(); + var articleInfo = articleWriteService.createArticle(command); + + return ResponseEntity.status(HttpStatus.CREATED).body(CommonResponse.success(articleInfo, "게시글 생성 완료")); + } + + @PostMapping("/article/{articleId}") + @Operation(summary = "게시글 업데이트") + public ResponseEntity> updateArticle( + @PathVariable UUID articleId, + @RequestBody ArticleRequest articleRequest + ) { + articleWriteService.updateArticle(articleId, articleRequest); + return ResponseEntity.status(HttpStatus.OK).body(CommonResponse.success("게시글 업데이트 완료")); + } + + @DeleteMapping("/article/{articleId}") + @Operation(summary = "게시글 삭제") + public ResponseEntity> deleteArticle(@PathVariable UUID articleId) { + articleWriteService.deleteOne(articleId); + return ResponseEntity.status(HttpStatus.OK).body(CommonResponse.success("게시글 삭제 완료")); + } +} diff --git a/src/main/java/site/moasis/monolithicbe/controller/comment/CommentReadController.java b/src/main/java/site/moasis/monolithicbe/controller/comment/CommentReadController.java index c962071..7cad640 100644 --- a/src/main/java/site/moasis/monolithicbe/controller/comment/CommentReadController.java +++ b/src/main/java/site/moasis/monolithicbe/controller/comment/CommentReadController.java @@ -11,32 +11,33 @@ import org.springframework.web.bind.annotation.RestController; import site.moasis.monolithicbe.controller.common.CommonResponse; import site.moasis.monolithicbe.service.CommentReadService; - +import site.moasis.monolithicbe.service.CommentWriteService; import java.util.UUID; @RestController @RequiredArgsConstructor -@RequestMapping("/api/v1/articles/{articleId}/comments") +@RequestMapping("/api/v1/users/{userId}/articles/{articleId}") // todo: 스프링 시큐리티 기능 완성 후 유저 정보 가져올 수 있을 때 "/users/{userId}" 삭제 @Tag(name = "CommentController", description = "댓글 조회 기능") public class CommentReadController { private final CommentReadService readService; + private final CommentWriteService writeService; - @GetMapping("/users/{userId}") - @Operation(summary = "user_id를 통한 댓글 조회") - public ResponseEntity> findByUser(@PathVariable UUID userId) { - var commentInfo = readService.selectByUser(userId); + @GetMapping("/comments") + @Operation(summary = "댓글 전체 조회") + public ResponseEntity> findAll() { + var commentInfo = readService.selectAll(); return ResponseEntity .status(HttpStatus.OK) - .body(CommonResponse.success(commentInfo, "Id가 " + userId + "인 유저가 작성한 댓글 조회 성공")); + .body(CommonResponse.success(commentInfo, "전체 댓글 조회 성공")); } - @GetMapping - @Operation(summary = "article_id를 통한 댓글 조회") - public ResponseEntity> findByArticle(@PathVariable UUID articleId) { - var commentInfo = readService.selectByArticle(articleId); + @GetMapping("/comments/{commentId}") + @Operation(summary = "댓글 단건 조회") + public ResponseEntity> findOne(@PathVariable("commentId") UUID commentId) { + var commentInfo = readService.selectOne(commentId); return ResponseEntity .status(HttpStatus.OK) - .body(CommonResponse.success(commentInfo, articleId + "번 게시글 댓글 조회 성공")); + .body(CommonResponse.success(commentInfo, "댓글 조회 성공")); } } diff --git a/src/main/java/site/moasis/monolithicbe/controller/comment/CommentWriteController.java b/src/main/java/site/moasis/monolithicbe/controller/comment/CommentWriteController.java index 7116e0e..b652d12 100644 --- a/src/main/java/site/moasis/monolithicbe/controller/comment/CommentWriteController.java +++ b/src/main/java/site/moasis/monolithicbe/controller/comment/CommentWriteController.java @@ -11,27 +11,31 @@ import org.springframework.web.bind.annotation.*; import site.moasis.monolithicbe.controller.common.CommonResponse; import site.moasis.monolithicbe.service.CommentCommand; +import site.moasis.monolithicbe.service.CommentReadService; import site.moasis.monolithicbe.service.CommentWriteService; - import java.util.UUID; - import static site.moasis.monolithicbe.service.CommentCommand.RegisterCommentCommand; @RestController @RequiredArgsConstructor -@RequestMapping("/api/v1/articles/{articleId}/comments") +@RequestMapping("/api/v1/users/{userId}/articles/{articleId}") // todo: 스프링 시큐리티 기능 완성 후 유저 정보 가져올 수 있을 때 "/users/{userId}" 삭제 @Tag(name = "CommentController", description = "댓글 생성, 삭제 기능") public class CommentWriteController { + private final CommentReadService readService; private final CommentWriteService writeService; - @PostMapping + @PostMapping("/comments") @Operation(summary = "댓글 생성") public ResponseEntity> registerComment( + @PathVariable UUID userId, @PathVariable UUID articleId, @RequestBody RegisterCommentRequest registerCommentRequest) { + UUID loginUserId = userId; + var command = RegisterCommentCommand .builder() + .userId(loginUserId) .articleId(articleId) .content(registerCommentRequest.getContent()) .build(); @@ -43,13 +47,17 @@ public ResponseEntity> registerComment( .body(CommonResponse.success(commentInfo, "댓글 생성 완료")); } - @DeleteMapping("/{commentId}") + @DeleteMapping("/comments/{commentId}") @Operation(summary = "댓글 삭제") public ResponseEntity> deleteComment( + @PathVariable("userId") UUID userId, @PathVariable("articleId") UUID articleId, @PathVariable("commentId") UUID commentId) { + UUID loginUserId = userId; + CommentCommand.DeleteCommentCommand command = CommentCommand.DeleteCommentCommand.builder() + .userId(loginUserId) .articleId(articleId) .commentId(commentId) .build(); @@ -60,18 +68,6 @@ public ResponseEntity> deleteComment( .body(CommonResponse.success(command, command.getCommentId() + "댓글 삭제 성공")); } - @PostMapping("/{commentId}") - @Operation(summary = "댓글 좋아요 또는 취소") - public ResponseEntity> likeComment( - @PathVariable("articleId") UUID articleId, - @PathVariable("commentId") UUID commentId - ) { - Boolean commentInfo = writeService.likeComment(articleId, commentId); - return ResponseEntity - .status(HttpStatus.OK) - .body(CommonResponse.success(commentInfo, "현재 상태 : " + commentInfo)); - } - @Getter @EqualsAndHashCode @NoArgsConstructor diff --git a/src/main/java/site/moasis/monolithicbe/controller/useraccount/UserAccountController.java b/src/main/java/site/moasis/monolithicbe/controller/useraccount/UserAccountController.java index afae3aa..c36ef04 100644 --- a/src/main/java/site/moasis/monolithicbe/controller/useraccount/UserAccountController.java +++ b/src/main/java/site/moasis/monolithicbe/controller/useraccount/UserAccountController.java @@ -8,7 +8,6 @@ import org.springframework.http.ResponseCookie; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import org.springframework.web.servlet.ModelAndView; import site.moasis.monolithicbe.controller.common.CommonResponse; import site.moasis.monolithicbe.domain.useraccount.TokenManager; import site.moasis.monolithicbe.domain.useraccount.entity.UserAccount; @@ -95,17 +94,4 @@ public ResponseEntity> reIssueToken(@CookieValue(name = "refre .header(HttpHeaders.SET_COOKIE, responseCookie.toString()) .body(CommonResponse.success(null, "로그인 완료")); } - - @GetMapping("/login-form") - public ModelAndView loginForm(){ - ModelAndView loginPage = new ModelAndView(); - loginPage.setViewName("login.html"); - return loginPage; - } - - @GetMapping("/authorization/success") - public boolean loginCallBack(){ - System.out.println("로그인 성공"); - return true; - } } \ No newline at end of file diff --git a/src/main/java/site/moasis/monolithicbe/domain/article/dto/ArticleDto.java b/src/main/java/site/moasis/monolithicbe/domain/article/dto/ArticleDto.java index d2f4f05..ea4116c 100644 --- a/src/main/java/site/moasis/monolithicbe/domain/article/dto/ArticleDto.java +++ b/src/main/java/site/moasis/monolithicbe/domain/article/dto/ArticleDto.java @@ -1,4 +1,25 @@ package site.moasis.monolithicbe.domain.article.dto; -public record ArticleDto() { +import site.moasis.monolithicbe.domain.article.entity.Article; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; + +public record ArticleDto( + UUID id, + UUID userId, + String title, + String content, + Long view, + LocalDateTime createdAt, + LocalDateTime updateAt +) { + public record ArticleOneDto(Article article) { + } + + public record ArticleResponseDto(List
articles) { + } + + } diff --git a/src/main/java/site/moasis/monolithicbe/domain/article/dto/ArticleRequest.java b/src/main/java/site/moasis/monolithicbe/domain/article/dto/ArticleRequest.java new file mode 100644 index 0000000..3cbc0fb --- /dev/null +++ b/src/main/java/site/moasis/monolithicbe/domain/article/dto/ArticleRequest.java @@ -0,0 +1,9 @@ +package site.moasis.monolithicbe.domain.article.dto; + +public record ArticleRequest( + + String title, + String content +){ + +} diff --git a/src/main/java/site/moasis/monolithicbe/domain/article/entity/Article.java b/src/main/java/site/moasis/monolithicbe/domain/article/entity/Article.java index 1a474bf..b535db2 100644 --- a/src/main/java/site/moasis/monolithicbe/domain/article/entity/Article.java +++ b/src/main/java/site/moasis/monolithicbe/domain/article/entity/Article.java @@ -1,27 +1,58 @@ package site.moasis.monolithicbe.domain.article.entity; import jakarta.persistence.*; -import lombok.*; -import org.hibernate.annotations.SQLDelete; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import site.moasis.monolithicbe.domain.common.DateTimeEntity; + import java.util.UUID; -@Entity + @Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false) -@SQLDelete(sql = "UPDATE article SET is_deleted=true WHERE article_id = ?") -public class Article { +@ToString(callSuper = true) +@Entity +public class Article extends DateTimeEntity { @Id - @EqualsAndHashCode.Include - @Column(name = "article_id") @GeneratedValue(strategy = GenerationType.UUID) private UUID id; + @Column + @Setter + private UUID userId; + @Column(nullable = false) + @Setter + private String title; // 제목 - private String content; + @Column(nullable = false, length = 10000) + @Setter + private String content; // 본문 + @Column(nullable = false) + private Long view; // 조회수 + + + protected Article() { + } @Builder - public Article(String content) { + public Article(UUID userId, String title, String content) { + this.userId = userId; + this.title = title; this.content = content; + this.view = 0L; + + } + + public static Article of(UUID userId, String title, String content) { + return new Article(userId, title, content); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Article that)) return false; + return this.getId() != null && this.getId().equals(that.getId()); + } + } diff --git a/src/main/java/site/moasis/monolithicbe/domain/article/entity/AuditingFields.java b/src/main/java/site/moasis/monolithicbe/domain/article/entity/AuditingFields.java new file mode 100644 index 0000000..95324f9 --- /dev/null +++ b/src/main/java/site/moasis/monolithicbe/domain/article/entity/AuditingFields.java @@ -0,0 +1,45 @@ +package site.moasis.monolithicbe.domain.article.entity; + + +import jakarta.persistence.Column; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; +import lombok.Getter; +import lombok.ToString; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +@Getter +@ToString +@EntityListeners(AuditingEntityListener.class) +@MappedSuperclass +public abstract class AuditingFields { + + + + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + @CreatedDate + @Column(nullable = false, updatable = false) + protected LocalDateTime createdAt; // 생성일시 + + @CreatedBy + @Column(nullable = true, updatable = false, length = 100) + protected String createdBy; // 생성자 + + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + @LastModifiedDate + @Column(nullable = false) + protected LocalDateTime modifiedAt; // 수정일시 + + @LastModifiedBy + @Column(nullable = true, length = 100) + protected String modifiedBy; // 수정자 + +} + diff --git a/src/main/java/site/moasis/monolithicbe/domain/article/repository/ArticleRepository.java b/src/main/java/site/moasis/monolithicbe/domain/article/repository/ArticleRepository.java index 3e1597a..68b7077 100644 --- a/src/main/java/site/moasis/monolithicbe/domain/article/repository/ArticleRepository.java +++ b/src/main/java/site/moasis/monolithicbe/domain/article/repository/ArticleRepository.java @@ -1,4 +1,27 @@ package site.moasis.monolithicbe.domain.article.repository; -public class ArticleRepository { +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import site.moasis.monolithicbe.domain.article.entity.Article; + +import java.util.List; +import java.util.UUID; + +public interface ArticleRepository extends JpaRepository { + + List
findByUserIdContaining(UUID userId); + + List
findByTitleContaining(String title); + + List
findByContentContaining(String content); + + @Query(value = "select c from Article as c ORDER BY c.createdAt DESC,c.updatedAt DESC") + List
findAll(); + + @Modifying + @Query("update Article q set q.view = q.view + 1 where q.id = :id") + void updateView(@Param("id") UUID id); + } diff --git a/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleCommand.java b/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleCommand.java new file mode 100644 index 0000000..15bffd4 --- /dev/null +++ b/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleCommand.java @@ -0,0 +1,27 @@ +package site.moasis.monolithicbe.domain.article.service; + +import jakarta.validation.constraints.NotBlank; +import lombok.Builder; +import org.hibernate.validator.constraints.Length; +import site.moasis.monolithicbe.common.exception.SelfValidating; + +import java.util.UUID; + +public class ArticleCommand { + + + public static class CreateCommand extends SelfValidating { + + public UUID userId; + @NotBlank String title; + @NotBlank + @Length(min = 3, max = 10000) String content; + + @Builder + public CreateCommand(String title, String content) { + this.title = title; + this.content = content; + validateSelf(); + } + } +} diff --git a/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleInfo.java b/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleInfo.java new file mode 100644 index 0000000..3782e84 --- /dev/null +++ b/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleInfo.java @@ -0,0 +1,24 @@ +package site.moasis.monolithicbe.domain.article.service; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.LocalDateTime; +import java.util.UUID; + +@Getter +@Setter +@EqualsAndHashCode +@NoArgsConstructor +public class ArticleInfo { + + private UUID articleId; + private String title; + private String content; + private LocalDateTime createdAt; + private LocalDateTime createdBy; + private String nickname; + +} diff --git a/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleInfoMapper.java b/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleInfoMapper.java new file mode 100644 index 0000000..572d40b --- /dev/null +++ b/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleInfoMapper.java @@ -0,0 +1,15 @@ +package site.moasis.monolithicbe.domain.article.service; + +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; +import site.moasis.monolithicbe.domain.article.entity.Article; + +public interface ArticleInfoMapper { + + ArticleInfoMapper INSTANCE = Mappers.getMapper(ArticleInfoMapper.class); + + @Mapping(target = "articleId", source = "article.id") + @Mapping(target = "userId", source = "user.id") + @Mapping(target = "createdAt", source = "article.createdAt") + ArticleInfo toArticleInfo(Article article); +} diff --git a/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleReadService.java b/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleReadService.java index 3322bc7..f9859b7 100644 --- a/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleReadService.java +++ b/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleReadService.java @@ -1,4 +1,54 @@ package site.moasis.monolithicbe.domain.article.service; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import site.moasis.monolithicbe.common.exception.BusinessException; +import site.moasis.monolithicbe.common.exception.ErrorCode; +import site.moasis.monolithicbe.domain.article.entity.Article; +import site.moasis.monolithicbe.domain.article.repository.ArticleRepository; + +import java.util.List; +import java.util.UUID; + +import static site.moasis.monolithicbe.domain.article.dto.ArticleDto.ArticleOneDto; +import static site.moasis.monolithicbe.domain.article.dto.ArticleDto.ArticleResponseDto; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) public class ArticleReadService { + private final ArticleRepository articleRepository; + + public List
searchArticles() { + + return articleRepository.findAll(); + } + + private ArticleResponseDto toDto(List
articles) { + return new ArticleResponseDto(articles); + } + + public ArticleOneDto searchOne(UUID articleId) { + Article article = articleRepository.findById(articleId). + orElseThrow(() -> new BusinessException(ErrorCode.NOT_FOUND, + "article.byId", List.of(articleId.toString()))); + articleRepository.updateView(articleId); + return new ArticleOneDto(article); + } + + public ArticleResponseDto searchByUserId(UUID userId) { + return toDto(articleRepository.findByUserIdContaining(userId)); + } + + public ArticleResponseDto searchBytitle(String title) { + return toDto(articleRepository.findByTitleContaining(title)); + } + + public ArticleResponseDto searchBycontent(String content) { + return toDto(articleRepository.findByContentContaining(content)); + } } + + + diff --git a/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleWriteService.java b/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleWriteService.java index fc87423..e54b572 100644 --- a/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleWriteService.java +++ b/src/main/java/site/moasis/monolithicbe/domain/article/service/ArticleWriteService.java @@ -1,4 +1,51 @@ package site.moasis.monolithicbe.domain.article.service; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import site.moasis.monolithicbe.common.exception.BusinessException; +import site.moasis.monolithicbe.common.exception.ErrorCode; +import site.moasis.monolithicbe.domain.article.dto.ArticleRequest; +import site.moasis.monolithicbe.domain.article.entity.Article; +import site.moasis.monolithicbe.domain.article.repository.ArticleRepository; +import site.moasis.monolithicbe.domain.article.service.ArticleCommand.CreateCommand; + +import java.util.List; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +@Transactional public class ArticleWriteService { + + private final ArticleRepository articleRepository; + + + public Article createArticle(CreateCommand createCommand) { + var article = Article.builder() + .userId(createCommand.userId) + .title(createCommand.title) + .content(createCommand.content) + .build(); + return articleRepository.save(article); + + } + + public UUID deleteOne(UUID articleId) { + articleRepository.findById(articleId).orElseThrow(() -> new BusinessException(ErrorCode.NOT_FOUND, + "article.byId", List.of(articleId.toString()))); + articleRepository.deleteById(articleId); + return articleId; + } + + public void updateArticle(UUID articleId, ArticleRequest articleRequest) { + var article = articleRepository.findById(articleId).orElseThrow(() -> new BusinessException(ErrorCode.NOT_FOUND, + "article.byId", List.of(articleId.toString()))); + article.setTitle(articleRequest.title()); + article.setContent(articleRequest.content()); + } + } + + + diff --git a/src/main/java/site/moasis/monolithicbe/domain/comment/Comment.java b/src/main/java/site/moasis/monolithicbe/domain/comment/Comment.java index 8fa42cc..501d9e9 100644 --- a/src/main/java/site/moasis/monolithicbe/domain/comment/Comment.java +++ b/src/main/java/site/moasis/monolithicbe/domain/comment/Comment.java @@ -2,6 +2,7 @@ import jakarta.persistence.*; import lombok.*; +import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.SQLDelete; import site.moasis.monolithicbe.domain.common.DateTimeEntity; @@ -32,27 +33,14 @@ public class Comment extends DateTimeEntity { @Column private Boolean isDeleted = false; - @Transient - private Boolean isLiked; - - @Transient - private Long likes; - @Column private String userName; @Builder - public Comment(String content, UUID articleId, String userName) { + public Comment(String content, UUID articleId, UUID userId, String userName) { this.content = content; this.articleId = articleId; + this.userId = userId; this.userName = userName; } - - public void setIsLiked(Boolean liked) { - isLiked = liked; - } - - public void setLikes(Long likes) { - this.likes = likes; - } } \ No newline at end of file diff --git a/src/main/java/site/moasis/monolithicbe/domain/comment/CommentDto.java b/src/main/java/site/moasis/monolithicbe/domain/comment/CommentDto.java index 9c37bd5..93e3d2e 100644 --- a/src/main/java/site/moasis/monolithicbe/domain/comment/CommentDto.java +++ b/src/main/java/site/moasis/monolithicbe/domain/comment/CommentDto.java @@ -1,13 +1,11 @@ package site.moasis.monolithicbe.domain.comment; -import lombok.Getter; - import java.util.*; public record CommentDto (){ public record CommentOneDto( - Comment comment) { + Optional comment) { } public record CommentResponseDto( diff --git a/src/main/java/site/moasis/monolithicbe/domain/comment/CommentLike.java b/src/main/java/site/moasis/monolithicbe/domain/comment/CommentLike.java deleted file mode 100644 index 3dc7d48..0000000 --- a/src/main/java/site/moasis/monolithicbe/domain/comment/CommentLike.java +++ /dev/null @@ -1,35 +0,0 @@ -package site.moasis.monolithicbe.domain.comment; - -import jakarta.persistence.*; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.util.UUID; - -@Entity -@Getter -@NoArgsConstructor -@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false) -public class CommentLike { - - @Id @GeneratedValue(generator = "UUID") - private UUID id; - - @Column - private UUID commentId; - - @Column - private UUID articleId; - - @Column - private String createBy; - - @Builder - public CommentLike(UUID commentId, UUID articleId, String createBy) { - this.commentId = commentId; - this.articleId = articleId; - this.createBy = createBy; - } -} diff --git a/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/GoogleUserInfo.java b/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/GoogleUserInfo.java deleted file mode 100644 index a704736..0000000 --- a/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/GoogleUserInfo.java +++ /dev/null @@ -1,36 +0,0 @@ -package site.moasis.monolithicbe.domain.useraccount.entity; - -import java.util.Map; - -public class GoogleUserInfo implements OAuth2UserInfo{ - private Map attributes; - - public GoogleUserInfo(Map attributes) { - this.attributes = attributes; - } - - @Override - public Map getAttributes() { - return attributes; - } - - @Override - public String getProviderId() { - return attributes.get("sub").toString(); - } - - @Override - public String getProvider() { - return "google"; - } - - @Override - public String getEmail() { - return attributes.get("email").toString(); - } - - @Override - public String getName() { - return attributes.get("name").toString(); - } -} diff --git a/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/KakaoUserInfo.java b/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/KakaoUserInfo.java deleted file mode 100644 index c977a84..0000000 --- a/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/KakaoUserInfo.java +++ /dev/null @@ -1,40 +0,0 @@ -package site.moasis.monolithicbe.domain.useraccount.entity; - -import java.util.Map; - -public class KakaoUserInfo implements OAuth2UserInfo{ - private Map attributes; - private Map attributesAccount; - private Map attributesProfile; - - public KakaoUserInfo(Map attributes) { - this.attributes = attributes; - this.attributesAccount = (Map) attributes.get("kakao_account"); - this.attributesProfile = (Map) attributesAccount.get("profile"); - } - - @Override - public Map getAttributes() { - return attributes; - } - - @Override - public String getProviderId() { - return attributes.get("id").toString(); - } - - @Override - public String getProvider() { - return "Kakao"; - } - - @Override - public String getEmail() { - return attributesAccount.get("email").toString(); - } - - @Override - public String getName() { - return attributesProfile.get("nickname").toString(); - } -} \ No newline at end of file diff --git a/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/NaverUserInfo.java b/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/NaverUserInfo.java deleted file mode 100644 index d62731b..0000000 --- a/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/NaverUserInfo.java +++ /dev/null @@ -1,38 +0,0 @@ -package site.moasis.monolithicbe.domain.useraccount.entity; - -import java.util.Map; - -public class NaverUserInfo implements OAuth2UserInfo { - private final Map attributes; - private final Map attributesResponse; - - public NaverUserInfo(Map attributes) { - this.attributes = (Map) attributes.get("response"); - this.attributesResponse = (Map) attributes.get("response"); - } - - @Override - public Map getAttributes() { - return attributes; - } - - @Override - public String getProviderId() { - return attributesResponse.get("id").toString(); - } - - @Override - public String getProvider() { - return "naver"; - } - - @Override - public String getEmail() { - return attributesResponse.get("email").toString(); - } - - @Override - public String getName() { - return attributesResponse.get("name").toString(); - } -} \ No newline at end of file diff --git a/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/OAuth2UserInfo.java b/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/OAuth2UserInfo.java deleted file mode 100644 index f5b0b91..0000000 --- a/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/OAuth2UserInfo.java +++ /dev/null @@ -1,11 +0,0 @@ -package site.moasis.monolithicbe.domain.useraccount.entity; - -import java.util.Map; - -public interface OAuth2UserInfo { - Map getAttributes(); - String getProviderId(); - String getProvider(); - String getEmail(); - String getName(); -} \ No newline at end of file diff --git a/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/UserAccount.java b/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/UserAccount.java index 1c2dd25..dd5a0ed 100644 --- a/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/UserAccount.java +++ b/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/UserAccount.java @@ -1,10 +1,8 @@ package site.moasis.monolithicbe.domain.useraccount.entity; import jakarta.persistence.*; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; +import org.hibernate.annotations.GenericGenerator; import site.moasis.monolithicbe.domain.useraccount.UserRole; import java.util.UUID; @@ -27,8 +25,6 @@ public class UserAccount { @Enumerated(EnumType.STRING) private UserRole role; private String refreshToken; - private String provider; - private String providerId; @Builder private UserAccount(String email, String password, String name, String phoneNumber, UserRole role) { @@ -38,15 +34,6 @@ private UserAccount(String email, String password, String name, String phoneNumb this.phoneNumber = phoneNumber; this.role = role; } - public UserAccount(String email, String password, String name, UserRole role, String provider, String providerId) { - this.email = email; - this.password = password; - this.name = name; - this.phoneNumber = phoneNumber; - this.role = role; - this.provider = provider; - this.providerId = providerId; - } public static UserAccount create(String email, String password, String name, String phoneNumber, UserRole role) { return new UserAccount(email, password, name, phoneNumber, role); diff --git a/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/UserDetailsImpl.java b/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/UserDetailsImpl.java index d8099e8..eed065a 100644 --- a/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/UserDetailsImpl.java +++ b/src/main/java/site/moasis/monolithicbe/domain/useraccount/entity/UserDetailsImpl.java @@ -5,19 +5,16 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.oauth2.core.user.OAuth2User; import java.util.Collection; import java.util.List; -import java.util.Map; @NoArgsConstructor @AllArgsConstructor -public class UserDetailsImpl implements UserDetails, OAuth2User { +public class UserDetailsImpl implements UserDetails { - private Map attributes; private UserAccount userAccount; - private OAuth2UserInfo oAuth2UserInfo; + @Override public Collection getAuthorities() { return List.of(new SimpleGrantedAuthority(userAccount.getRole().name())); @@ -52,19 +49,4 @@ public boolean isCredentialsNonExpired() { public boolean isEnabled() { return true; } - - public UserDetailsImpl(UserAccount userAccount, OAuth2UserInfo oAuth2UserInfo) { - this.userAccount = userAccount; - this.oAuth2UserInfo = oAuth2UserInfo; - } - - @Override - public Map getAttributes() { - return attributes; - } - - @Override - public String getName() { - return attributes.get("sub").toString(); - } } \ No newline at end of file diff --git a/src/main/java/site/moasis/monolithicbe/domain/useraccount/repository/UserAccountRepository.java b/src/main/java/site/moasis/monolithicbe/domain/useraccount/repository/UserAccountRepository.java index 2aff44a..fb26dbd 100644 --- a/src/main/java/site/moasis/monolithicbe/domain/useraccount/repository/UserAccountRepository.java +++ b/src/main/java/site/moasis/monolithicbe/domain/useraccount/repository/UserAccountRepository.java @@ -1,8 +1,6 @@ package site.moasis.monolithicbe.domain.useraccount.repository; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; import site.moasis.monolithicbe.domain.useraccount.entity.UserAccount; import java.util.Optional; @@ -10,10 +8,6 @@ public interface UserAccountRepository extends JpaRepository { Optional findByEmail(String email); - - @Query(value = "select u.id from UserAccount u where u.email = :email") - Optional selectIdByEmail(@Param("email") String email); boolean existsByEmail(String email); Optional findByRefreshToken(String refreshToken); - Optional findByName(String name); } \ No newline at end of file diff --git a/src/main/java/site/moasis/monolithicbe/domain/useraccount/service/PrincipalOauth2UserService.java b/src/main/java/site/moasis/monolithicbe/domain/useraccount/service/PrincipalOauth2UserService.java deleted file mode 100644 index d81b38c..0000000 --- a/src/main/java/site/moasis/monolithicbe/domain/useraccount/service/PrincipalOauth2UserService.java +++ /dev/null @@ -1,57 +0,0 @@ -package site.moasis.monolithicbe.domain.useraccount.service; - -import lombok.RequiredArgsConstructor; -import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; -import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; -import org.springframework.security.oauth2.core.OAuth2AuthenticationException; -import org.springframework.security.oauth2.core.user.OAuth2User; -import org.springframework.stereotype.Service; -import site.moasis.monolithicbe.domain.useraccount.UserRole; -import site.moasis.monolithicbe.domain.useraccount.entity.*; -import site.moasis.monolithicbe.domain.useraccount.repository.UserAccountRepository; - -import java.util.Optional; -import java.util.UUID; - -@RequiredArgsConstructor -@Service -public class PrincipalOauth2UserService extends DefaultOAuth2UserService { - - private final UserAccountRepository userAccountRepository; - - @Override - public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { - - OAuth2User oAuth2User = super.loadUser(userRequest); - - OAuth2UserInfo oAuth2UserInfo = null; - String provider = userRequest.getClientRegistration().getRegistrationId(); - - if (provider.equals("naver")) { - oAuth2UserInfo = new NaverUserInfo(oAuth2User.getAttributes()); - } else if(provider.equals("google")){ - oAuth2UserInfo = new GoogleUserInfo(oAuth2User.getAttributes()); - }else if(provider.equals("kakao")){ - oAuth2UserInfo = new KakaoUserInfo(oAuth2User.getAttributes()); - } - - String providerId = oAuth2UserInfo.getProviderId(); - String username = provider + "_" + providerId; - String uuid = UUID.randomUUID().toString().substring(0, 10); - String password = "패스워드" + uuid; - String email = oAuth2UserInfo.getEmail(); - UserRole role = UserRole.ROLE_USER; - - Optional userAccountOptional = userAccountRepository.findByName(username); - UserAccount userAccount; - if (userAccountOptional.isPresent()) { - userAccount = userAccountOptional.get(); - } else { - userAccount = new UserAccount(email, password, username, role, provider, providerId); - userAccountRepository.save(userAccount); - } - - return new UserDetailsImpl(userAccount, oAuth2UserInfo); - } -} - diff --git a/src/main/java/site/moasis/monolithicbe/domain/useraccount/service/UserAccountWriteService.java b/src/main/java/site/moasis/monolithicbe/domain/useraccount/service/UserAccountWriteService.java index 0d5c28f..5c7a405 100644 --- a/src/main/java/site/moasis/monolithicbe/domain/useraccount/service/UserAccountWriteService.java +++ b/src/main/java/site/moasis/monolithicbe/domain/useraccount/service/UserAccountWriteService.java @@ -19,7 +19,6 @@ import site.moasis.monolithicbe.domain.useraccount.entity.UserAccount; import site.moasis.monolithicbe.domain.useraccount.repository.UserAccountRepository; -import java.util.List; import java.util.Optional; import static site.moasis.monolithicbe.domain.useraccount.dto.UserAccountDto.*; @@ -28,7 +27,7 @@ @Transactional @Service public class UserAccountWriteService { -// private final Logger logger = LoggerFactory.getLogger(UserAccountWriteService.class); + private final Logger logger = LoggerFactory.getLogger(UserAccountWriteService.class); private final AccessTokenManager accessTokenManager; private final UserAccountRepository userAccountRepository; @@ -38,7 +37,7 @@ public class UserAccountWriteService { private void checkDuplicatedEmail(String email){ if(userAccountRepository.existsByEmail(email)){ - throw new BusinessException(ErrorCode.DUPLICATE, "user.byEmail", List.of(email)); + throw new BusinessException(ErrorCode.DUPLICATE); }; } public UserAccount signUp(UserAccountJoinRequestDto userAccountJoinRequestDto) { @@ -65,7 +64,7 @@ public UserAccountSignInResponseDto signIn(String email, String password) { authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken); SecurityContextHolder.getContext().setAuthentication(authentication); } catch (BadCredentialsException e) { - throw new BusinessException(ErrorCode.INVALID_PARAMETER, "user.byCredential", null); + throw new BusinessException(ErrorCode.INVALID_PARAMETER); } String refreshToken = refreshTokenManager.createToken(authentication); @@ -86,12 +85,12 @@ public UserAccountSignInResponseDto signIn(String email, String password) { public ReissueTokenResponseDto reissueToken(String accessToken, String refreshToken){ if(accessTokenManager.validateToken(accessToken)){ -// logger.info("아직 엑세스토큰이 유효합니다"); - throw new BusinessException(ErrorCode.FORBIDDEN, "user.byValidAccessToken", null); + logger.info("아직 엑세스토큰이 유효합니다"); + throw new BusinessException(ErrorCode.FORBIDDEN); } if(!refreshTokenManager.validateToken(refreshToken)){ -// logger.info("리프레쉬 토큰이 유효하지 않습니다"); - throw new BusinessException(ErrorCode.FORBIDDEN, "user.byInvalidRefreshToken", null); + logger.info("리프레쉬 토큰이 유효하지 않습니다"); + throw new BusinessException(ErrorCode.FORBIDDEN); } Optional userAccountOptional = this.userAccountRepository.findByRefreshToken(refreshToken); diff --git a/src/main/java/site/moasis/monolithicbe/domain/useraccount/service/UserEmailService.java b/src/main/java/site/moasis/monolithicbe/domain/useraccount/service/UserEmailService.java index 078872d..f6aa0cd 100644 --- a/src/main/java/site/moasis/monolithicbe/domain/useraccount/service/UserEmailService.java +++ b/src/main/java/site/moasis/monolithicbe/domain/useraccount/service/UserEmailService.java @@ -11,7 +11,6 @@ import site.moasis.monolithicbe.common.exception.ErrorCode; import site.moasis.monolithicbe.configuration.AppProperties; -import java.util.List; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; @@ -37,7 +36,7 @@ public void sendCode(String email) { mimeMessageHelper.setText(EMAIL_CERTIFICATION_MAIL_CONTENT_PREFIX + code + EMAIL_CERTIFICATION_MAIL_CONTENT_POSTFIX, true); javaMailSender.send(mimeMessage); } catch (Exception e) { - throw new BusinessException(ErrorCode.INTERNAL_SERVER_ERROR, "user.byEmail", List.of(email)); + throw new BusinessException(ErrorCode.INTERNAL_SERVER_ERROR); } log.info("사용자 이메일={}, 발급된 코드={}", email, code); codeMap.put(email, code); @@ -45,7 +44,7 @@ public void sendCode(String email) { public void certificate(String email, int code) { if (!codeMap.get(email).equals(code)) { - throw new BusinessException(ErrorCode.CODE_MISMATCH, "user.byCode", List.of(email)); + throw new BusinessException(ErrorCode.CODE_MISMATCH); } } diff --git a/src/main/java/site/moasis/monolithicbe/infrastructure/CommentLikesRepository.java b/src/main/java/site/moasis/monolithicbe/infrastructure/CommentLikesRepository.java deleted file mode 100644 index db2459d..0000000 --- a/src/main/java/site/moasis/monolithicbe/infrastructure/CommentLikesRepository.java +++ /dev/null @@ -1,21 +0,0 @@ -package site.moasis.monolithicbe.infrastructure; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import site.moasis.monolithicbe.domain.comment.CommentLike; - -import java.util.UUID; - -public interface CommentLikesRepository extends JpaRepository { - -// @Lock(LockModeType.PESSIMISTIC_READ) - @Query(value = "select count(c) from CommentLike as c where c.commentId = :commentId") - Long countByCommentId(@Param("commentId") UUID commentId); - - @Modifying @Query(value = "delete from CommentLike as c where c.commentId = :commentId and c.createBy = :userEmail") - void deleteLikes(@Param("commentId") UUID commentId, @Param("userEmail") String userEmail); - - Boolean existsByCommentIdAndCreateBy(UUID commentId, String email); -} diff --git a/src/main/java/site/moasis/monolithicbe/infrastructure/article/ArticleRepository.java b/src/main/java/site/moasis/monolithicbe/infrastructure/article/ArticleRepository.java deleted file mode 100644 index 9bb0d3e..0000000 --- a/src/main/java/site/moasis/monolithicbe/infrastructure/article/ArticleRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package site.moasis.monolithicbe.infrastructure.article; - -import org.springframework.data.jpa.repository.JpaRepository; -import site.moasis.monolithicbe.domain.article.entity.Article; - -import java.util.UUID; - -public interface ArticleRepository extends JpaRepository { -} diff --git a/src/main/java/site/moasis/monolithicbe/service/CommentCommand.java b/src/main/java/site/moasis/monolithicbe/service/CommentCommand.java index 0ea3a79..93c6758 100644 --- a/src/main/java/site/moasis/monolithicbe/service/CommentCommand.java +++ b/src/main/java/site/moasis/monolithicbe/service/CommentCommand.java @@ -15,6 +15,8 @@ public class CommentCommand { @Getter @EqualsAndHashCode(callSuper = false) public static class RegisterCommentCommand extends SelfValidating { + @NotNull + private UUID userId; @NotNull private UUID articleId; @@ -24,7 +26,8 @@ public static class RegisterCommentCommand extends SelfValidatingnew BusinessException(ErrorCode.NOT_FOUND, "comment.byId", List.of(commentId.toString()))); - comment.setLikes(getLikes(commentId)); - setUserLikes(commentId, comment); - return new CommentOneDto(comment); + return new CommentOneDto( + Optional.ofNullable(commentRepository.selectById(commentId) + .orElseThrow(() -> new BusinessException(ErrorCode.NOT_FOUND)))); } public CommentResponseDto selectByArticle(UUID articleId){ - List comments = commentRepository.selectByArticleId(articleId); - comments.forEach(c -> c.setLikes(getLikes(c.getId()))); - comments.forEach(c->setUserLikes(c.getId(), c)); - return new CommentResponseDto(comments); + return new CommentResponseDto( + commentRepository.selectByArticleId(articleId)); } public CommentResponseDto selectByUser(UUID userId){ - List comments = commentRepository.selectByUserId(userId); - comments.forEach(c -> c.setLikes(getLikes(c.getId()))); - comments.forEach(c->setUserLikes(c.getId(), c)); - return new CommentResponseDto(comments); - } - - public Long getLikes(UUID commentId){ - return commentLikesRepository.countByCommentId(commentId); - } - - private void setUserLikes(UUID commentId, Comment comment) { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if (authentication.getClass().equals(AnonymousAuthenticationToken.class)) - comment.setIsLiked(null); - else { - Boolean exist = commentLikesRepository.existsByCommentIdAndCreateBy(commentId, authentication.getName()); - comment.setIsLiked(exist); - } + return new CommentResponseDto( + commentRepository.selectByUserId(userId)); } } diff --git a/src/main/java/site/moasis/monolithicbe/service/CommentWriteService.java b/src/main/java/site/moasis/monolithicbe/service/CommentWriteService.java index e66b315..e9aaf8d 100644 --- a/src/main/java/site/moasis/monolithicbe/service/CommentWriteService.java +++ b/src/main/java/site/moasis/monolithicbe/service/CommentWriteService.java @@ -2,27 +2,20 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.security.authentication.AnonymousAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import site.moasis.monolithicbe.common.exception.BusinessException; import site.moasis.monolithicbe.common.exception.ErrorCode; import site.moasis.monolithicbe.domain.article.entity.Article; +import site.moasis.monolithicbe.domain.article.repository.ArticleRepository; import site.moasis.monolithicbe.domain.comment.Comment; -import site.moasis.monolithicbe.domain.comment.CommentLike; import site.moasis.monolithicbe.domain.useraccount.entity.UserAccount; import site.moasis.monolithicbe.domain.useraccount.repository.UserAccountRepository; -import site.moasis.monolithicbe.infrastructure.CommentLikesRepository; -import site.moasis.monolithicbe.infrastructure.article.ArticleRepository; import site.moasis.monolithicbe.infrastructure.comment.CommentRepository; import java.util.List; import java.util.UUID; -import static site.moasis.monolithicbe.service.CommentCommand.RegisterCommentCommand; - @Slf4j @Service @Transactional @@ -30,20 +23,18 @@ public class CommentWriteService{ private final CommentRepository commentRepository; - - private final CommentLikesRepository commentLikesRepository; private final UserAccountRepository userAccountRepository; private final ArticleRepository articleRepository; - public CommentInfo registerComment(RegisterCommentCommand registerCommentCommand){ - - UUID userId = userAccountRepository.selectIdByEmail(getUserEmail()).orElseThrow(()-> - new BusinessException(ErrorCode.UNAUTHORIZED, "user.byEmail", null)); + public CommentInfo registerComment(CommentCommand.RegisterCommentCommand registerCommentCommand){ + UserAccount userAccount = getUserById(registerCommentCommand.getUserId()); + Article article = getArticleById(registerCommentCommand.getArticleId()); - var comment = Comment.builder() + Comment comment = Comment.builder() .content(registerCommentCommand.getContent()) - .articleId(registerCommentCommand.getArticleId()) - .userName(getUserEmail()) + .articleId(article.getId()) + .userId(userAccount.getId()) + .userName(userAccount.getName()) .build(); return CommentInfoMapper.INSTANCE.toCommentInfo(commentRepository.save(comment)); @@ -76,26 +67,4 @@ private Comment getCommentById(UUID commentId) { .orElseThrow( () -> new BusinessException(ErrorCode.NOT_FOUND, "comment.byId", List.of(commentId.toString()))); } - - public Boolean likeComment(UUID articleId, UUID commentId) { - String userEmail = getUserEmail(); - Comment comment = commentRepository.selectById(commentId).orElseThrow(()-> - new BusinessException(ErrorCode.NOT_FOUND, "comment.byId", List.of(commentId.toString()))); - Boolean exist = commentLikesRepository.existsByCommentIdAndCreateBy(commentId, userEmail); - - if (exist) - commentLikesRepository.deleteLikes(commentId, userEmail); - else - commentLikesRepository.save(new CommentLike(commentId, articleId, userEmail)); - - comment.setIsLiked(!exist); - return comment.getIsLiked(); - } - - private String getUserEmail() { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if (authentication.getClass().equals(AnonymousAuthenticationToken.class)) - throw new BusinessException(ErrorCode.UNAUTHORIZED, "user.byEmail", null); - return authentication.getName(); - } } diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index e3f4ec8..bd6e48b 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -13,46 +13,6 @@ spring: hibernate: jdbc: time_zone: ${TIME_ZONE} - - security: - oauth2: - client: - provider: - naver: - authorization-uri: https://nid.naver.com/oauth2.0/authorize - token-uri: https://nid.naver.com/oauth2.0/token - user-info-uri: https://openapi.naver.com/v1/nid/me - user-name-attribute: response - - kakao: - authorization-uri: https://kauth.kakao.com/oauth/authorize - token-uri: https://kauth.kakao.com/oauth/token - user-info-uri: https://kapi.kakao.com/v2/user/me - user-name-attribute: id - - registration: - naver: - client-id: ${NAVER_CLIENT_ID} - client-secret: ${NAVER_CLIENT_SECRET} - scope: name, email - client-name: Naver - authorization-grant-type: authorization_code - redirect-uri: ${NAVER_REDIRECT_URI} - - google: - client-id: ${GOOGLE_CLIENT_ID} - client-secret: ${GOOGLE_CLIENT_SECRET} - scope: profile, email - - kakao: - client-id: ${KAKAO_CLIENT_ID} - client-secret: ${KAKAO_CLIENT_SECRET} - client-name: Kakao - scope: profile_nickname, account_email - authorization-grant-type: authorization_code - redirect-uri: ${KAKAO_REDIRECT_URI} - client-authentication-method: POST - app: mail: protocol: ${MAIL_PROTOCOL} diff --git a/src/main/resources/business-errors.properties b/src/main/resources/business-errors.properties index 985320d..4353422 100644 --- a/src/main/resources/business-errors.properties +++ b/src/main/resources/business-errors.properties @@ -10,6 +10,7 @@ forbidden.user.byInvalidRefreshToken=리프레쉬 토큰이 유효하지 않습 # 404 notFound.comment.byId=[{0}] 댓글은 존재하지 않습니다. +notFound.article.byId=[{0}] 게시글은 존재하지 않습니다. notFound.user.byId=[{0}] 유저가 존재하지 않습니다. notFound.user.byEmail=[{0}] 로 가입된 이메일이 존재하지 않습니다. diff --git a/src/main/resources/static/users/login.html b/src/main/resources/static/users/login.html deleted file mode 100644 index 4a3b016..0000000 --- a/src/main/resources/static/users/login.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - 로그인 페이지 - - -

로그인 페이지

-
- -

로그인 유저 :

-

- - - - - -

-유저
-매니저
-어드민
- -

-Form 로그인 정보 -OAuth2 로그인 정보 -로그인 정보 - - - \ No newline at end of file diff --git a/src/test/java/site/moasis/monolithicbe/integration/user/UserRepositoryTest.java b/src/test/java/site/moasis/monolithicbe/integration/user/UserRepositoryTest.java index 9b41d96..8af7cfe 100644 --- a/src/test/java/site/moasis/monolithicbe/integration/user/UserRepositoryTest.java +++ b/src/test/java/site/moasis/monolithicbe/integration/user/UserRepositoryTest.java @@ -4,28 +4,19 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.TestComponent; -import site.moasis.monolithicbe.controller.useraccount.UserAccountController; -import site.moasis.monolithicbe.domain.useraccount.dto.UserAccountDto; +import site.moasis.monolithicbe.domain.useraccount.entity.UserAccount; import site.moasis.monolithicbe.domain.useraccount.repository.UserAccountRepository; @SpringBootTest @Transactional -@TestComponent public class UserRepositoryTest { @Autowired UserAccountRepository userAccountRepository; - @Autowired - UserAccountController userAccountController; @Test - void 회원가입(){ - // given - var joinUser = new UserAccountDto.UserAccountJoinRequestDto( - "csw1111@moasis.com","1234","1234","1234"); - userAccountController.join(joinUser); - // when - userAccountRepository.findByEmail("csw1111@moasis.com").orElseThrow(); + void 유저정보조회() { + UserAccount userAccount = userAccountRepository.findByEmail("jhj13062004@naver.com").orElseThrow(); + System.out.println("userAccount id = " + userAccount.getId()); } } diff --git a/src/test/java/site/moasis/monolithicbe/service/CommentReadServiceTest.java b/src/test/java/site/moasis/monolithicbe/service/CommentReadServiceTest.java deleted file mode 100644 index f569766..0000000 --- a/src/test/java/site/moasis/monolithicbe/service/CommentReadServiceTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package site.moasis.monolithicbe.service; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.transaction.annotation.Transactional; -import site.moasis.monolithicbe.domain.comment.Comment; -import site.moasis.monolithicbe.domain.useraccount.repository.UserAccountRepository; -import site.moasis.monolithicbe.infrastructure.comment.CommentRepository; - -import java.util.UUID; - -import static org.assertj.core.api.Assertions.assertThat; - -@Transactional -@SpringBootTest -class CommentReadServiceTest { - - @Autowired - CommentReadService commentReadService; - @Autowired - CommentWriteService commentWriteService; - @Autowired - CommentRepository commentRepository; - @Autowired - UserAccountRepository userAccountRepository; - - UUID randomUUID; - UUID commentId; - - @BeforeEach - void beforeEach() { - randomUUID = UUID.randomUUID(); - Comment newComment = Comment.builder() - .articleId(randomUUID) - .content(randomUUID.toString()) - .build(); - Comment storedComment = commentRepository.save(newComment); - commentId = storedComment.getId(); - } - - @Test - void 좋아요_기능이_정상적으로_작동하는지_확인한다() { - - // given - authentication(); - - // when - for (int i = 0; i < 101; i++) - commentWriteService.likeComment(randomUUID, commentId); - // then - assertThat(commentReadService.selectOne(commentId).comment().getLikes()).isEqualTo(1L); - } - - @Test - void 취소_기능이_정상적으로_작동하는지_확인한다() { - - // given - authentication(); - // when - for (int i = 0; i < 100; i++) - commentWriteService.likeComment(randomUUID, commentId); - // then - assertThat(commentReadService.selectOne(commentId).comment().getLikes()).isEqualTo(0L); - } - - private void authentication() { - SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(null, null)); - } -} \ No newline at end of file diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml deleted file mode 100644 index 1d1d8aa..0000000 --- a/src/test/resources/application.yml +++ /dev/null @@ -1,54 +0,0 @@ -spring: - datasource: - driver-class-name: org.h2.Driver - url: jdbc:h2:../junit-test - username: sa - password: - h2: - console: - enabled: true - path: /h2-console - jpa: - show-sql: true - hibernate: - ddl-auto: 'create-drop' - output: - ansi: - enabled: always - properties: - hibernate: - jdbc: - time_zone: UTC - messages: - basename: business-errors, validation-errors, test-validation-errors - encoding: UTF-8 - mvc: - pathmatch: - matching-strategy: ant_path_matcher - servlet: - multipart: - max-file-size: 50MB - max-request-size: 50MB -logging: - level: - org: - hibernate: - SQL: trace - type: - descriptor: - sql: trace - -app: - mail: - protocol: smtp - value: true - host: smtp.naver.com - username: moasis@moasis.com - password: moasis@moasis.com - port: 465 - jwt: - header: Authorization - access_token_secret: cnV0eXdlb3JpdHV3eWVyb3RpdXdleXJ0b2l1d2V5cnRvd2VpdXJ0eXdhaXNkamZvaWF6eGNpdm5xd2Vpb2lhZHNmCg== - access_token_validity_in_seconds: 600 - refresh_token_secret: cnV0eXdlb3JpdHV3eWVyb3RpdXdleXJ0b2l1d2V5cnRvd2VpdXJ0eXdhaXNkamZvaWF6eGNpdm5xd2Vpb2lhZHNmCg== - refresh_token_validity_in_seconds: 6000 \ No newline at end of file diff --git a/src/test/resources/business-errors.properties b/src/test/resources/business-errors.properties deleted file mode 100644 index 985320d..0000000 --- a/src/test/resources/business-errors.properties +++ /dev/null @@ -1,20 +0,0 @@ -# 400 -invalidParameter.user.byCredential=잘못된 계정정보 입니다. - -# 401 -code_mismatch.user.byCode=[{0}] 로 보낸 코드와 일치하지 않습니다. -unauthorized.user.byEmail=로그인이 필요합니다. -# 403 -forbidden.user.byValidAccessToken=아직 엑세스토큰이 유효합니다 -forbidden.user.byInvalidRefreshToken=리프레쉬 토큰이 유효하지 않습니다 - -# 404 -notFound.comment.byId=[{0}] 댓글은 존재하지 않습니다. -notFound.user.byId=[{0}] 유저가 존재하지 않습니다. -notFound.user.byEmail=[{0}] 로 가입된 이메일이 존재하지 않습니다. - -# 409 -duplicate.user.byEmail=[{0}] 이메일이 존재합니다. - -# 500 -internalServerError.user.byEmail=[{0}] 로 이메일 전송이 실패했습니다.