-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Jwt choi #12
base: main
Are you sure you want to change the base?
Jwt choi #12
Changes from all commits
c342327
9b151c5
ff5d1f5
68a2ca9
8eb7b80
192cf2c
1b54fa2
335b439
f2738fa
8c3837a
a942884
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package com.gdsc.blog.article.controller; | ||
|
||
import com.gdsc.blog.article.dto.CreateDto; | ||
import com.gdsc.blog.article.dto.UpdateDto; | ||
import com.gdsc.blog.article.entity.Article; | ||
import com.gdsc.blog.article.service.ArticleService; | ||
import com.gdsc.blog.user.entity.User; | ||
import com.gdsc.blog.user.service.UserService; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.data.crossstore.ChangeSetPersister; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.access.prepost.PreAuthorize; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.nio.file.AccessDeniedException; | ||
import java.util.List; | ||
|
||
@RestController | ||
@Slf4j | ||
@Tag(name = "Article", description = "Article API") | ||
@RequestMapping("/api/article") | ||
public class ArticleController { | ||
private final ArticleService articleService; //private final로 안넣은 이유?? | ||
private final UserService userService; | ||
|
||
public ArticleController(ArticleService articleService, UserService userService){ | ||
this.articleService = articleService; | ||
this.userService = userService; | ||
} | ||
|
||
@PostMapping("/create") | ||
@Operation(summary = "게시글 생성") | ||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") | ||
|
||
public Article create(@RequestBody CreateDto article) { | ||
|
||
Article article1 = Article.builder().subject(article.getSubject()).content(article.getContent()).build(); | ||
|
||
//현재 인증된 사용자 가져오기 | ||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | ||
String username = authentication.getName(); // 현재 인증된 사용자의 이름(아이디)를 가져온다. | ||
|
||
User user = userService.getUserByName(username); // DB에서 사용자를 조회합니다. | ||
return articleService.create(article1, user); | ||
} | ||
@GetMapping("/myallarticle") //내 게시글 목록 | ||
@Operation(summary = "내 게시글 목록") | ||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") | ||
public List<Article> myallarticle(HttpServletRequest req) { | ||
User user = userService.whoami(req); | ||
return articleService.myAllArticle(user); | ||
} | ||
|
||
@GetMapping("article/{id}") // 특정 게시글 | ||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") | ||
@Operation(summary = "특정 게시글") | ||
public Article getarticle(HttpServletRequest req, @PathVariable("id") Long id){ | ||
return articleService.getArticle(id); | ||
} | ||
|
||
@GetMapping("/allarticle") // 모든 게시글 조회 | ||
@Operation(summary = "모든 게시글 조회 ") | ||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") | ||
public List<Article> allarticle(HttpServletRequest req) { | ||
return articleService.getAllAriticle(); | ||
} | ||
|
||
@PutMapping("/update/{id}") | ||
@Operation(summary = "게시글 업데이트") | ||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") | ||
public Article updateArticle(@PathVariable("id") Long id, @RequestBody UpdateDto article, HttpServletRequest req) throws ChangeSetPersister.NotFoundException, AccessDeniedException { | ||
// 현재 인증된 사용자 가져오기 | ||
User user = userService.whoami(req); | ||
Article updatedArticle = articleService.updateArticle(id, article, user); | ||
return updatedArticle; | ||
} | ||
|
||
@DeleteMapping("/delete/{id}") | ||
@Operation(summary = "게시글 삭제") | ||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") | ||
public ResponseEntity<?> deleteArticle(@PathVariable("id") Long id, HttpServletRequest req) throws ChangeSetPersister.NotFoundException, AccessDeniedException { | ||
// 현재 인증된 사용자 가져오기 | ||
User user = userService.whoami(req); | ||
articleService.deleteArticle(id, user); | ||
return ResponseEntity.ok().build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.gdsc.blog.article.dto; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Data; | ||
import lombok.NoArgsConstructor; | ||
@Data | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
@Builder | ||
public class CreateDto { | ||
@Schema(description = "제목", example = "첫 게시글 입니다.") | ||
public String subject; | ||
|
||
@Schema(description = "내용", example = "안녕하세요.") | ||
public String content; | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Article CreateDto와 UpdateDto가 코드가 일치하는것 같은데, 차라리 Article Form Dto 로 통일하는건 어떨까요? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.gdsc.blog.article.dto; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Data; | ||
import lombok.NoArgsConstructor; | ||
@Data | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
@Builder | ||
public class UpdateDto { | ||
@Schema(description = "제목", example = "수정될 제목") | ||
public String subject; | ||
|
||
@Schema(description = "내용", example = "수정될 내용") | ||
public String content; | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. DB(SQL)에 시간을 저장할 때는 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.gdsc.blog.article.entity; | ||
|
||
import com.fasterxml.jackson.annotation.JsonBackReference; | ||
import com.gdsc.blog.user.entity.User; | ||
import jakarta.persistence.*; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Data; | ||
import lombok.NoArgsConstructor; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
@Entity | ||
@Data | ||
@Builder //빌더 패턴을 사용 | ||
@AllArgsConstructor //모든 필드를 매개변수로 받는 생성자 | ||
@NoArgsConstructor //매개변수가 없는 기본 생성자 | ||
public class Article { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long idx; | ||
|
||
private String subject; | ||
|
||
private String content; | ||
|
||
private LocalDateTime createDate; | ||
|
||
@JsonBackReference | ||
@ManyToOne | ||
private User user; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.gdsc.blog.article.repository; | ||
|
||
import com.gdsc.blog.article.entity.Article; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
|
||
public interface ArticleRepository extends JpaRepository<Article, Long> { | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. public Article getArticle(Long id){
List<Article> Allarticle = articleRepository.findAll();
for(Article article: Allarticle){
if(article.getIdx() == id){
return article;
}
}
throw new RuntimeException("No article");
} 위와 같은 코드는 Repository에 findbyUserIdx 메소드를 생성해주세요 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package com.gdsc.blog.article.service; | ||
|
||
import com.gdsc.blog.article.dto.UpdateDto; | ||
import com.gdsc.blog.article.entity.Article; | ||
import com.gdsc.blog.article.repository.ArticleRepository; | ||
import com.gdsc.blog.user.entity.User; | ||
import com.gdsc.blog.user.service.UserService; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
|
||
@RequiredArgsConstructor | ||
@Service | ||
@Slf4j | ||
public class ArticleService { | ||
|
||
private final ArticleRepository articleRepository; | ||
|
||
public Article create(Article article, User user){ | ||
article.setCreateDate(LocalDateTime.now()); | ||
article.setUser(user); | ||
return articleRepository.save(article); | ||
} | ||
|
||
public Article getArticle(Long id){ | ||
List<Article> Allarticle = articleRepository.findAll(); | ||
|
||
for(Article article: Allarticle){ | ||
if(article.getIdx() == id){ | ||
return article; | ||
} | ||
} | ||
throw new RuntimeException("No article"); | ||
} | ||
|
||
public List<Article> myAllArticle(User user){ | ||
return user.getArticleList(); | ||
} | ||
|
||
public List<Article> getAllAriticle(){ | ||
return articleRepository.findAll(); | ||
} | ||
|
||
public Article updateArticle(Long idx, UpdateDto newarticle, User user){ | ||
List<Article> Allarticle = articleRepository.findAll(); | ||
|
||
for(Article article: Allarticle){ | ||
if(article.getIdx() == idx){ | ||
article.setSubject(newarticle.getSubject()); | ||
article.setContent(newarticle.getContent()); | ||
return articleRepository.save(article); | ||
} | ||
} | ||
throw new RuntimeException("No article"); | ||
} | ||
|
||
public void deleteArticle(Long id, User user){ | ||
// find article by id | ||
Article article = articleRepository.findById(id) | ||
.orElseThrow(() -> new RuntimeException("Article not found")); | ||
|
||
// check if the logged-in user is the owner of the article | ||
if (!article.getUser().getIdx().equals(user.getIdx())) { | ||
throw new RuntimeException("Permission denied"); | ||
} | ||
|
||
// delete the article | ||
articleRepository.delete(article); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
컨트룰러에서는 최대한 서비스 로직을 제거해주세요
단일 책임 원칙에 위반됩니다..!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Entity를 그대로 반환하는 것은 좋지 않아요!
아래에 User Class를 보니
@JsonManagedReference
가 있던데 이를 사용하는것 보다 DTO를 생성하는게 좋아요