diff --git a/src/main/java/com/example/springsecuritystudy/common/AlreadyRegisteredUserException.java b/src/main/java/com/example/springsecuritystudy/common/AlreadyRegisteredUserException.java new file mode 100644 index 0000000..bb4024f --- /dev/null +++ b/src/main/java/com/example/springsecuritystudy/common/AlreadyRegisteredUserException.java @@ -0,0 +1,12 @@ +package com.example.springsecuritystudy.common; + +public class AlreadyRegisteredUserException extends RuntimeException { + + public AlreadyRegisteredUserException(String message) { + super(message); + } + + public AlreadyRegisteredUserException() { + super("이미 등록된 유저입니다."); + } +} diff --git a/src/main/java/com/example/springsecuritystudy/config/InitializeConfig.java b/src/main/java/com/example/springsecuritystudy/config/InitializeConfig.java new file mode 100644 index 0000000..5a785b9 --- /dev/null +++ b/src/main/java/com/example/springsecuritystudy/config/InitializeConfig.java @@ -0,0 +1,32 @@ +package com.example.springsecuritystudy.config; + +import javax.annotation.PostConstruct; + +import org.springframework.context.annotation.Configuration; + +import com.example.springsecuritystudy.notice.NoticeService; +import com.example.springsecuritystudy.post.PostService; +import com.example.springsecuritystudy.user.User; +import com.example.springsecuritystudy.user.UserService; + +import lombok.RequiredArgsConstructor; + +@Configuration +@RequiredArgsConstructor +public class InitializeConfig { + + private final UserService userService; + private final PostService postService; + private final NoticeService noticeService; + + @PostConstruct + public void adminAccount() { + User user = userService.signup("user", "user"); + userService.signupAdmin("admin", "admin"); + postService.savePost(user, "테스트", "테스트입니다."); + postService.savePost(user, "테스트2", "테스트2입니다."); + postService.savePost(user, "테스트3", "테스트3입니다."); + postService.savePost(user, "여름 여행계획", "여름 여행계획 작성중..."); + noticeService.saveNotice("환영합니다", "환영합니다 여러분"); + } +} diff --git a/src/main/java/com/example/springsecuritystudy/config/MvcConfig.java b/src/main/java/com/example/springsecuritystudy/config/MvcConfig.java index f4fa6fe..c2323a2 100644 --- a/src/main/java/com/example/springsecuritystudy/config/MvcConfig.java +++ b/src/main/java/com/example/springsecuritystudy/config/MvcConfig.java @@ -3,18 +3,9 @@ package com.example.springsecuritystudy.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.filter.HiddenHttpMethodFilter; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration -public class MvcConfig implements WebMvcConfigurer { - - public void addViewControllers(ViewControllerRegistry registry) { - registry.addViewController("/").setViewName("index"); - registry.addViewController("/home").setViewName("index"); - registry.addViewController("/admin").setViewName("admin/index"); - registry.addViewController("/login").setViewName("login"); - } +public class MvcConfig { @Bean public HiddenHttpMethodFilter hiddenHttpMethodFilter(){ diff --git a/src/main/java/com/example/springsecuritystudy/config/SecurityConfig.java b/src/main/java/com/example/springsecuritystudy/config/SecurityConfig.java index 5155e6c..d259eb5 100644 --- a/src/main/java/com/example/springsecuritystudy/config/SecurityConfig.java +++ b/src/main/java/com/example/springsecuritystudy/config/SecurityConfig.java @@ -4,28 +4,21 @@ import org.springframework.context.annotation.Bean; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import com.example.springsecuritystudy.user.UserRepository; - import lombok.RequiredArgsConstructor; @EnableWebSecurity @RequiredArgsConstructor public class SecurityConfig { - private final UserRepository userRepository; - @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .antMatchers("/", "/home", "/signup", "/example", - "/css/**", "/js/**", "/h2-console/**").permitAll() + "/css/**", "/h2-console/**").permitAll() .antMatchers("/post").hasRole("USER") .antMatchers("/admin").hasRole("ADMIN") .antMatchers(HttpMethod.POST, "/notice").hasRole("ADMIN") @@ -48,14 +41,4 @@ public class SecurityConfig { return http.build(); } - @Bean - public WebSecurityCustomizer webSecurityCustomizer() { - return web -> web.ignoring().antMatchers("/css/**", "/js/**", "/h2-console/**"); - } - - @Bean - public UserDetailsService userDetailsService() { - return username -> userRepository.findByUsername(username) - .orElseThrow(() -> new UsernameNotFoundException("유저를 찾지 못 했습니다.")); - } } diff --git a/src/main/java/com/example/springsecuritystudy/config/UserDetailServiceImpl.java b/src/main/java/com/example/springsecuritystudy/config/UserDetailServiceImpl.java new file mode 100644 index 0000000..9fb175f --- /dev/null +++ b/src/main/java/com/example/springsecuritystudy/config/UserDetailServiceImpl.java @@ -0,0 +1,26 @@ +package com.example.springsecuritystudy.config; + +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.example.springsecuritystudy.common.UserNotFoundException; +import com.example.springsecuritystudy.user.UserRepository; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class UserDetailServiceImpl implements UserDetailsService { + + private final UserRepository userRepository; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + return userRepository.findByUsername(username) + .orElseThrow(UserNotFoundException::new); + } +} diff --git a/src/main/java/com/example/springsecuritystudy/controller/SampleController.java b/src/main/java/com/example/springsecuritystudy/controller/SampleController.java index 9e75637..3ecb971 100644 --- a/src/main/java/com/example/springsecuritystudy/controller/SampleController.java +++ b/src/main/java/com/example/springsecuritystudy/controller/SampleController.java @@ -7,6 +7,11 @@ import org.springframework.web.bind.annotation.GetMapping; @Controller public class SampleController { + @GetMapping({"/", "/home"}) + public String index() { + return "index"; + } + @GetMapping("/example") public String example(Model model) { model.addAttribute("name", "정우성"); diff --git a/src/main/java/com/example/springsecuritystudy/notice/NoticeService.java b/src/main/java/com/example/springsecuritystudy/notice/NoticeService.java index 417cb98..5f7aed7 100644 --- a/src/main/java/com/example/springsecuritystudy/notice/NoticeService.java +++ b/src/main/java/com/example/springsecuritystudy/notice/NoticeService.java @@ -2,6 +2,7 @@ package com.example.springsecuritystudy.notice; import java.util.List; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -16,7 +17,7 @@ public class NoticeService { @Transactional(readOnly = true) public List findAll() { - return noticeRepository.findAll(); + return noticeRepository.findAll(Sort.by(Sort.Direction.DESC, "id")); } public Notice saveNotice(String title, String content) { diff --git a/src/main/java/com/example/springsecuritystudy/post/AdminController.java b/src/main/java/com/example/springsecuritystudy/post/AdminController.java new file mode 100644 index 0000000..f1c47b2 --- /dev/null +++ b/src/main/java/com/example/springsecuritystudy/post/AdminController.java @@ -0,0 +1,29 @@ +package com.example.springsecuritystudy.post; + +import java.util.List; + +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import com.example.springsecuritystudy.user.User; + +import lombok.RequiredArgsConstructor; + +@Controller +@RequiredArgsConstructor +@RequestMapping("/admin") +public class AdminController { + + private final PostService postService; + + @GetMapping + public String getPostForAdmin(Authentication authentication, Model model) { + User user = (User) authentication.getPrincipal(); + List posts = postService.findByUser(user); + model.addAttribute("posts", posts); + return "admin/index"; + } +} diff --git a/src/main/java/com/example/springsecuritystudy/post/Post.java b/src/main/java/com/example/springsecuritystudy/post/Post.java index 8719a38..b7ce2f8 100644 --- a/src/main/java/com/example/springsecuritystudy/post/Post.java +++ b/src/main/java/com/example/springsecuritystudy/post/Post.java @@ -43,4 +43,9 @@ public class Post extends BaseTimeEntity { this.status = PostStatus.Y; this.user = user; } + + public void updatePost(String title, String content) { + this.title = title; + this.content = content; + } } diff --git a/src/main/java/com/example/springsecuritystudy/post/PostController.java b/src/main/java/com/example/springsecuritystudy/post/PostController.java index 31e9f97..eae9569 100644 --- a/src/main/java/com/example/springsecuritystudy/post/PostController.java +++ b/src/main/java/com/example/springsecuritystudy/post/PostController.java @@ -24,7 +24,7 @@ public class PostController { private final PostService postService; @GetMapping - public String findByPost(Authentication authentication, Model model) { + public String getPost(Authentication authentication, Model model) { User user = (User) authentication.getPrincipal(); List posts = postService.findByUser(user); model.addAttribute("posts", posts); diff --git a/src/main/java/com/example/springsecuritystudy/post/PostRepository.java b/src/main/java/com/example/springsecuritystudy/post/PostRepository.java index b63bb9f..59ed973 100644 --- a/src/main/java/com/example/springsecuritystudy/post/PostRepository.java +++ b/src/main/java/com/example/springsecuritystudy/post/PostRepository.java @@ -8,7 +8,9 @@ import com.example.springsecuritystudy.user.User; public interface PostRepository extends JpaRepository { - List findByUserAndStatus(User user, PostStatus status); + List findByUserAndStatusOrderByIdDesc(User user, PostStatus status); Post findByIdAndUser(Long id, User user); + + List findByStatusOrderByIdDesc(PostStatus status); } diff --git a/src/main/java/com/example/springsecuritystudy/post/PostService.java b/src/main/java/com/example/springsecuritystudy/post/PostService.java index 50bb189..03231bd 100644 --- a/src/main/java/com/example/springsecuritystudy/post/PostService.java +++ b/src/main/java/com/example/springsecuritystudy/post/PostService.java @@ -5,8 +5,8 @@ import java.util.List; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.example.springsecuritystudy.common.UserNotFoundException; import com.example.springsecuritystudy.user.User; -import com.example.springsecuritystudy.user.UserRepository; import lombok.RequiredArgsConstructor; @@ -15,18 +15,20 @@ import lombok.RequiredArgsConstructor; @Transactional public class PostService { - private final UserRepository userRepository; private final PostRepository postRepository; @Transactional(readOnly = true) public List findByUser(User user) { userNullCheck(user); - return postRepository.findByUserAndStatus(user, PostStatus.Y); + if (Boolean.TRUE.equals(user.isAdmin())) { + return postRepository.findByStatusOrderByIdDesc(PostStatus.Y); + } + return postRepository.findByUserAndStatusOrderByIdDesc(user, PostStatus.Y); } private static void userNullCheck(User user) { if (user == null) { - throw new RuntimeException("유저가 없습니다."); + throw new UserNotFoundException(); } } diff --git a/src/main/java/com/example/springsecuritystudy/user/UserController.java b/src/main/java/com/example/springsecuritystudy/user/UserController.java index 182dcba..40f2265 100644 --- a/src/main/java/com/example/springsecuritystudy/user/UserController.java +++ b/src/main/java/com/example/springsecuritystudy/user/UserController.java @@ -4,18 +4,21 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; import lombok.RequiredArgsConstructor; @Controller @RequiredArgsConstructor -@RequestMapping("/signup") public class UserController { private final UserService userService; - @GetMapping + @GetMapping("/login") + public String loginView() { + return "login"; + } + + @GetMapping("/signup") public String signupView() { return "signup"; } diff --git a/src/main/java/com/example/springsecuritystudy/user/UserService.java b/src/main/java/com/example/springsecuritystudy/user/UserService.java index b36f9c7..23115fa 100644 --- a/src/main/java/com/example/springsecuritystudy/user/UserService.java +++ b/src/main/java/com/example/springsecuritystudy/user/UserService.java @@ -1,9 +1,11 @@ package com.example.springsecuritystudy.user; -import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import com.example.springsecuritystudy.common.AlreadyRegisteredUserException; +import com.example.springsecuritystudy.common.UserNotFoundException; + import lombok.RequiredArgsConstructor; @Service @@ -14,22 +16,24 @@ public class UserService { private final PasswordEncoder passwordEncoder; public User signup(String username, String password) { - if (userRepository.findByUsername(username).isPresent()) { - throw new RuntimeException("이미 등록된 유저입니다."); - } + alreadyRegisteredUser(username); return userRepository.save(new User(username, passwordEncoder.encode(password), "ROLE_USER")); } public User signupAdmin(String username, String password) { - if (userRepository.findByUsername(username).isPresent()) { - throw new RuntimeException("이미 등록된 Admin유저입니다."); - } + alreadyRegisteredUser(username); return userRepository.save(new User(username, passwordEncoder.encode(password), "ROLE_ADMIN")); } public User findByUsername(String username) { return userRepository.findByUsername(username) - .orElseThrow(() -> new UsernameNotFoundException("존재하지 않는 유저입니다.")); + .orElseThrow(UserNotFoundException::new); + } + + private void alreadyRegisteredUser(String username) { + if (userRepository.findByUsername(username).isPresent()) { + throw new AlreadyRegisteredUserException(); + } } } diff --git a/src/main/resources/templates/admin/index.html b/src/main/resources/templates/admin/index.html index 6a4e202..f078bf4 100644 --- a/src/main/resources/templates/admin/index.html +++ b/src/main/resources/templates/admin/index.html @@ -8,7 +8,19 @@

관리자 페이지

-

당신은 관리자입니다.

+

게시글 내역

+
+
+
+

+ + Posted by + on + +

+
+
+