diff --git a/README.md b/README.md index 345bc166c..117a0c060 100644 --- a/README.md +++ b/README.md @@ -143,3 +143,29 @@ - 로그아웃은 `GET` 요청으로도 구현 가능하나 로그아웃은 상태를 바꾸는 행위이므로 `POST`가 더 적절하다고 판단하였다. a 태그는 `POST` 요청을 보낼 수 없기 때문에 JS 함수를 onclick 이벤트로 삽입하여 구현하였다. - 에러 페이지를 표시할 때 적절한 HTTP status code를 응답에 포함시키면 더 좋겠다. - 지금은 로그인되지 않은 경우(401)와 로그인되어 있지만 다른 사용자의 회원정보수정 페이지에 접근하는 경우(403)를 구분하여 처리하기 어려워 생략하였다. + +## 미션 5 - 게시글 권한부여 + +### 요구사항 + +- [x] 로그인한 사용자만 게시글의 세부내용을 볼 수 있다. + - 로그인하지 않은 사용자는 게시글의 목록만 볼 수 있다. + - 로그인하지 않은 사용자가 게시글의 내용에 접근하면 로그인 페이지로 이동한다. +- [x] 로그인한 사용자만 게시글을 작성할 수 있다. + - 게시물의 글쓴이 정보는 사용자 이름(name)을 사용한다. 게시물 작성 양식에서 글쓴이 필드는 제거한다. + - 로그인하지 않은 사용자가 게시물 작성 페이지에 접근하면 로그인 페이지로 이동한다. +- [x] 로그인한 사용자는 자신의 글을 수정할 수 있다. + - 글 수정 요청은 @PutMapping으로 매핑한다. + - 수정하기 폼 과 수정하기 기능은 로그인 사용자와 글쓴이의 사용자 아이디가 같은 경우에만 가능하다. + - 상황에 따라 "다른 사람의 글을 수정할 수 없다."와 같은 에러 메시지를 출력하는 페이지로 이동하도록 구현한다. +- [x] 로그인한 사용자는 자신의 글을 삭제할 수 있다. + - 글 삭제 요청은 @DeleteMapping으로 매핑한다. + - 삭제하기는 로그인 사용자와 글쓴이의 사용자 아이디가 같은 경우에만 가능하다. + - 상황에 따라 "다른 사람의 글을 수정할 수 없다."와 같은 에러 메시지를 출력하는 페이지로 이동하도록 구현한다. +- [x] 스프링 부트, 웹 MVC로 구현한다. + - API로 구현하지 않고, 템플릿 기반으로 구현한다. + - HttpSession을 활용해서 구현한다. + +### 전 단계 피드백 반영 + +- [x] login 및 logout을 처리할 때 HttpSession 객체를 UserService 계층까지 전달하지 않도록 한다. diff --git a/build.gradle b/build.gradle index 6a97e22ee..0acad6a3c 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { id 'java' } -group = 'com.kakao' +group = 'kr.codesquad' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' diff --git a/src/main/java/kr/codesquad/cafe/article/Article.java b/src/main/java/kr/codesquad/cafe/article/Article.java index 2aa22cc4f..03aab161f 100644 --- a/src/main/java/kr/codesquad/cafe/article/Article.java +++ b/src/main/java/kr/codesquad/cafe/article/Article.java @@ -8,7 +8,8 @@ public class Article { private Long id; private LocalDateTime timestamp; - private String writer; + private String writerUserId; + private String writerName; private String title; private String contents; @@ -28,13 +29,21 @@ public void setTimestamp(LocalDateTime timestamp) { this.timestamp = timestamp; } - public String getWriter() { - return writer; + public String getWriterUserId() { + return writerUserId; } - public void setWriter(String writer) { - Assert.hasText(writer, "작성자는 공백이어선 안 됩니다."); - this.writer = writer; + public String getWriterName() { + return writerName; + } + + public void setWriterName(String writerName) { + this.writerName = writerName; + } + + public void setWriterUserId(String writerUserId) { + Assert.hasText(writerUserId, "작성자는 공백이어선 안 됩니다."); + this.writerUserId = writerUserId; } public String getTitle() { @@ -54,4 +63,8 @@ public void setContents(String contents) { Assert.hasText(contents, "글 내용은 공백이어선 안 됩니다."); this.contents = contents; } + + public boolean hasId() { + return id != null; + } } diff --git a/src/main/java/kr/codesquad/cafe/article/ArticleController.java b/src/main/java/kr/codesquad/cafe/article/ArticleController.java index f3d9cb3df..342cfea9a 100644 --- a/src/main/java/kr/codesquad/cafe/article/ArticleController.java +++ b/src/main/java/kr/codesquad/cafe/article/ArticleController.java @@ -1,11 +1,12 @@ package kr.codesquad.cafe.article; +import kr.codesquad.cafe.user.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpSession; @Controller public class ArticleController { @@ -25,9 +26,11 @@ public String viewQuestions(Model model) { } @PostMapping("/questions") - public String processCreationForm(ArticleCreationForm form) { + public String processCreationForm(ArticleCreationForm form, HttpSession session) { Article article = new Article(); - article.setWriter(form.getWriter()); + User writer = (User) session.getAttribute("currentUser"); + article.setWriterUserId(writer.getUserId()); + article.setWriterName(writer.getName()); article.setTitle(form.getTitle()); article.setContents(form.getContents()); service.post(article); @@ -42,4 +45,43 @@ public String viewQuestion(@PathVariable("id") long id, Model model) { return "qna/show"; } + @GetMapping("/questions/{id}/form") + public String viewUpdateForm(@PathVariable("id") long id, Model model) { + model.addAttribute("article", service.retrieve(id)); + + return "qna/updateForm"; + } + + @PutMapping("/questions/{id}/update") + public String processUpdateForm(@PathVariable("id") long id, ArticleCreationForm form, HttpSession session) { + User currentUser = (User) session.getAttribute("currentUser"); + String writerUserId = service.retrieve(id).getWriterUserId(); + + if (!currentUser.userIdIs(writerUserId)) { + return "redirect:/badRequest"; + } + + Article article = new Article(); + article.setId(id); + article.setWriterName(currentUser.getName()); + article.setTitle(form.getTitle()); + article.setContents(form.getContents()); + service.update(article); + + return "redirect:/questions/{id}"; + } + + @DeleteMapping("/questions/{id}") + public String deleteArticle(@PathVariable("id") long id, HttpSession session) { + User currentUser = (User) session.getAttribute("currentUser"); + String writerUserId = service.retrieve(id).getWriterUserId(); + + if (!currentUser.userIdIs(writerUserId)) { + return "redirect:/badRequest"; + } + + service.deleteById(id); + + return "redirect:/"; + } } diff --git a/src/main/java/kr/codesquad/cafe/article/ArticleCreationForm.java b/src/main/java/kr/codesquad/cafe/article/ArticleCreationForm.java index ab533d751..40abab24f 100644 --- a/src/main/java/kr/codesquad/cafe/article/ArticleCreationForm.java +++ b/src/main/java/kr/codesquad/cafe/article/ArticleCreationForm.java @@ -2,18 +2,9 @@ public class ArticleCreationForm { - private String writer; private String title; private String contents; - public String getWriter() { - return writer; - } - - public void setWriter(String writer) { - this.writer = writer; - } - public String getTitle() { return title; } diff --git a/src/main/java/kr/codesquad/cafe/article/ArticleRepository.java b/src/main/java/kr/codesquad/cafe/article/ArticleRepository.java index 65ff8a761..87b89c950 100644 --- a/src/main/java/kr/codesquad/cafe/article/ArticleRepository.java +++ b/src/main/java/kr/codesquad/cafe/article/ArticleRepository.java @@ -12,9 +12,13 @@ @Repository public class ArticleRepository { - private static final String SQL_SAVE_ARTICLE = "INSERT INTO ARTICLE(WRITER, TITLE, CONTENTS) VALUES(?, ?, ?)"; + private static final String SQL_SAVE_ARTICLE = + "INSERT INTO ARTICLE(WRITER_USERID, WRITER_NAME, TITLE, CONTENTS) VALUES(?, ?, ?, ?)"; + private static final String SQL_UPDATE_ARTICLE = + "UPDATE ARTICLE SET WRITER_NAME=?, TITLE=?, CONTENTS=? WHERE ID=?"; private static final String SQL_FIND_ARTICLE = "SELECT * FROM ARTICLE WHERE ID = ?"; private static final String SQL_FIND_ARTICLE_ALL = "SELECT * FROM ARTICLE"; + private static final String SQL_DELETE_ARTICLE = "DELETE FROM ARTICLE WHERE ID=?"; private final JdbcTemplate jdbcTemplate; @Autowired @@ -23,8 +27,13 @@ public ArticleRepository(JdbcTemplate jdbcTemplate) { } public void save(Article article) { + if (article.hasId()) { + jdbcTemplate.update(SQL_UPDATE_ARTICLE, + article.getWriterName(), article.getTitle(), article.getContents(), article.getId()); + return; + } jdbcTemplate.update(SQL_SAVE_ARTICLE, - article.getWriter(), article.getTitle(), article.getContents()); + article.getWriterUserId(), article.getWriterName(), article.getTitle(), article.getContents()); } public Optional
findOne(long id) { @@ -40,11 +49,16 @@ private RowMapper
articleRowMapper() { Article article = new Article(); article.setId(rs.getLong("id")); article.setTimestamp(rs.getTimestamp("timestamp").toLocalDateTime()); - article.setWriter(rs.getString("writer")); + article.setWriterUserId(rs.getString("writer_userid")); + article.setWriterName(rs.getString("writer_name")); article.setTitle(rs.getString("title")); article.setContents(rs.getString("contents")); return article; }); } + + public void deleteById(long id) { + jdbcTemplate.update(SQL_DELETE_ARTICLE, id); + } } diff --git a/src/main/java/kr/codesquad/cafe/article/ArticleService.java b/src/main/java/kr/codesquad/cafe/article/ArticleService.java index 24531ca72..b3072cbb7 100644 --- a/src/main/java/kr/codesquad/cafe/article/ArticleService.java +++ b/src/main/java/kr/codesquad/cafe/article/ArticleService.java @@ -20,6 +20,10 @@ public void post(Article article) { repository.save(article); } + public void update(Article article) { + repository.save(article); + } + public Article retrieve(long id) { return repository.findOne(id) .orElseThrow(() -> new NoSuchElementException("존재하지 않는 게시물입니다.")); @@ -28,4 +32,8 @@ public Article retrieve(long id) { public List
retrieveAll() { return repository.findAll(); } + + public void deleteById(long id) { + repository.deleteById(id); + } } diff --git a/src/main/java/kr/codesquad/cafe/system/MvcConfig.java b/src/main/java/kr/codesquad/cafe/system/MvcConfig.java index cffaa4aae..3d116955b 100644 --- a/src/main/java/kr/codesquad/cafe/system/MvcConfig.java +++ b/src/main/java/kr/codesquad/cafe/system/MvcConfig.java @@ -1,7 +1,12 @@ package kr.codesquad.cafe.system; +import kr.codesquad.cafe.system.intercepter.LoginRequiredInterceptor; +import kr.codesquad.cafe.system.intercepter.UserAuthenticationInterceptor; +import kr.codesquad.cafe.system.intercepter.WriterAuthenticationInterceptor; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -15,5 +20,34 @@ public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/join").setViewName("users/form"); registry.addViewController("/questions/new").setViewName("qna/form"); + registry.addViewController("/badRequest").setViewName("badRequest"); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(loginRequiredInterceptor()) + .addPathPatterns("/questions/**") + .addPathPatterns("/users/**"); + + registry.addInterceptor(userAuthenticationInterceptor()) + .addPathPatterns("/users/*/form"); + + registry.addInterceptor(writerAuthenticationInterceptor()) + .addPathPatterns("/questions/*/form"); + } + + @Bean + public LoginRequiredInterceptor loginRequiredInterceptor() { + return new LoginRequiredInterceptor(); + } + + @Bean + public UserAuthenticationInterceptor userAuthenticationInterceptor() { + return new UserAuthenticationInterceptor(); + } + + @Bean + public WriterAuthenticationInterceptor writerAuthenticationInterceptor() { + return new WriterAuthenticationInterceptor(); } } diff --git a/src/main/java/kr/codesquad/cafe/system/intercepter/LoginRequiredInterceptor.java b/src/main/java/kr/codesquad/cafe/system/intercepter/LoginRequiredInterceptor.java new file mode 100644 index 000000000..b050922a5 --- /dev/null +++ b/src/main/java/kr/codesquad/cafe/system/intercepter/LoginRequiredInterceptor.java @@ -0,0 +1,28 @@ +package kr.codesquad.cafe.system.intercepter; + +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +public class LoginRequiredInterceptor implements HandlerInterceptor { + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + HttpSession session = request.getSession(); + + if (session.getAttribute("currentUser") == null) { + if ("POST".equals(request.getMethod())) { + return true; + } + + session.setAttribute("destinationAfterLogin", request.getRequestURI()); + response.sendRedirect("/login"); + + return false; + } + + return true; + } +} diff --git a/src/main/java/kr/codesquad/cafe/system/intercepter/UserAuthenticationInterceptor.java b/src/main/java/kr/codesquad/cafe/system/intercepter/UserAuthenticationInterceptor.java new file mode 100644 index 000000000..12e498305 --- /dev/null +++ b/src/main/java/kr/codesquad/cafe/system/intercepter/UserAuthenticationInterceptor.java @@ -0,0 +1,27 @@ +package kr.codesquad.cafe.system.intercepter; + +import kr.codesquad.cafe.user.User; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.HandlerMapping; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Map; + +public class UserAuthenticationInterceptor implements HandlerInterceptor { + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + Map pathVariable = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); + String targetUserId = (String) pathVariable.get("userId"); + User currentUser = (User) request.getSession().getAttribute("currentUser"); + + if (currentUser.userIdIs(targetUserId)) { + return true; + } + + response.sendRedirect("/badRequest"); + + return false; + } +} diff --git a/src/main/java/kr/codesquad/cafe/system/intercepter/WriterAuthenticationInterceptor.java b/src/main/java/kr/codesquad/cafe/system/intercepter/WriterAuthenticationInterceptor.java new file mode 100644 index 000000000..249920ee3 --- /dev/null +++ b/src/main/java/kr/codesquad/cafe/system/intercepter/WriterAuthenticationInterceptor.java @@ -0,0 +1,23 @@ +package kr.codesquad.cafe.system.intercepter; + +import kr.codesquad.cafe.article.Article; +import kr.codesquad.cafe.user.User; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class WriterAuthenticationInterceptor implements HandlerInterceptor { + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + Article article = (Article) modelAndView.getModelMap().getAttribute("article"); + String writerUserId = article.getWriterUserId(); + User currentUser = (User) request.getSession().getAttribute("currentUser"); + + if (!currentUser.userIdIs(writerUserId)) { + response.sendRedirect("/badRequest"); + } + } +} diff --git a/src/main/java/kr/codesquad/cafe/user/LoginController.java b/src/main/java/kr/codesquad/cafe/user/LoginController.java index df1d0c8f9..782d4e438 100644 --- a/src/main/java/kr/codesquad/cafe/user/LoginController.java +++ b/src/main/java/kr/codesquad/cafe/user/LoginController.java @@ -10,6 +10,7 @@ @Controller public class LoginController { + private static final String CURRENT_USER = "currentUser"; private final UserService userService; @Autowired @@ -25,17 +26,32 @@ public String viewLogin() { @PostMapping("/login") public String processLogin(String userId, String password, HttpSession session) { try { - userService.login(userId, password, session); + User user = userService.findByUserId(userId); + userService.validatePassword(user, password); + session.setAttribute(CURRENT_USER, user); - return "redirect:/"; + String destination = getDestination(session); + return "redirect:" + destination; } catch (Exception e) { return "users/login_failed"; } } + private String getDestination(HttpSession session) { + String destination = (String) session.getAttribute("destinationAfterLogin"); + + if (destination == null) { + return "/"; + } + + session.removeAttribute("destinationAfterLogin"); + + return destination; + } + @PostMapping("/logout") public String processLogout(HttpSession session) { - userService.logout(session); + session.removeAttribute(CURRENT_USER); return "redirect:/"; } diff --git a/src/main/java/kr/codesquad/cafe/user/UserController.java b/src/main/java/kr/codesquad/cafe/user/UserController.java index 3876be94e..ee02f0c4e 100644 --- a/src/main/java/kr/codesquad/cafe/user/UserController.java +++ b/src/main/java/kr/codesquad/cafe/user/UserController.java @@ -61,15 +61,11 @@ public String viewUserProfile(@PathVariable("userId") String userId, Model model } @GetMapping("/users/{userId}/form") - public String viewUpdateForm(@PathVariable("userId") String userId, Model model, HttpSession session) { + public String viewUpdateForm(@PathVariable("userId") String userId, Model model) { try { - service.validateCurrentUser(userId, session); model.addAttribute("user", service.findByUserId(userId)); return "users/updateForm"; - } catch (IllegalStateException e) { - - return "badRequest"; } catch (NoSuchElementException e) { //noinspection SpringMVCViewInspection diff --git a/src/main/java/kr/codesquad/cafe/user/UserRepository.java b/src/main/java/kr/codesquad/cafe/user/UserRepository.java index 83dd5a5ee..d77b90425 100644 --- a/src/main/java/kr/codesquad/cafe/user/UserRepository.java +++ b/src/main/java/kr/codesquad/cafe/user/UserRepository.java @@ -13,7 +13,8 @@ @Repository public class UserRepository { - private static final String SQL_SAVE_USER = "INSERT INTO CAFE_USER VALUES (?, ?, ?, ?)"; + private static final String SQL_SAVE_USER = + "MERGE INTO CAFE_USER (USERID, PASSWORD, NAME, EMAIL) VALUES (?, ?, ?, ?)"; private static final String SQL_FIND_USER_BY = "SELECT * FROM CAFE_USER WHERE %s = ?"; private static final String SQL_FIND_USER_BY_USERID = String.format(SQL_FIND_USER_BY, "USERID"); private static final String SQL_FIND_USER_BY_NAME = String.format(SQL_FIND_USER_BY, "NAME"); diff --git a/src/main/java/kr/codesquad/cafe/user/UserService.java b/src/main/java/kr/codesquad/cafe/user/UserService.java index e4d1a8c0e..0089e6bdb 100644 --- a/src/main/java/kr/codesquad/cafe/user/UserService.java +++ b/src/main/java/kr/codesquad/cafe/user/UserService.java @@ -3,15 +3,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import javax.servlet.http.HttpSession; import java.util.List; import java.util.NoSuchElementException; -import java.util.Optional; @Service public class UserService { - private static final String CURRENT_USER = "currentUser"; private final UserRepository repository; @Autowired @@ -36,17 +33,7 @@ public void update(User user, String oldPassword) { repository.save(user); } - public void login(String userId, String password, HttpSession session) { - User user = findByUserId(userId); - validatePassword(user, password); - session.setAttribute(CURRENT_USER, user); - } - - public void logout(HttpSession session) { - session.removeAttribute(CURRENT_USER); - } - - private void validatePassword(User user, String oldPassword) { + public void validatePassword(User user, String oldPassword) { if (findByUserId(user.getUserId()).passwordIs(oldPassword)) { return; } @@ -93,21 +80,4 @@ public User findByUserId(String userId) { return repository.findByUserId(userId) .orElseThrow(() -> new NoSuchElementException("존재하지 않는 회원입니다.")); } - - public void validateCurrentUser(String userId, HttpSession session) { - if (getCurrentUser(session).userIdIs(userId)) { - return; - } - - throw new IllegalStateException("사용자 ID가 일치하지 않습니다."); - } - - public User getCurrentUser(HttpSession session) { - return (User) Optional.ofNullable(session.getAttribute(CURRENT_USER)).orElseThrow( - () -> { - throw new IllegalStateException("로그인 상태가 아닙니다."); - } - ); - } - } diff --git a/src/main/resources/sql/sample_data.sql b/src/main/resources/sql/sample_data.sql index 3a3377635..d6e8b82ff 100644 --- a/src/main/resources/sql/sample_data.sql +++ b/src/main/resources/sql/sample_data.sql @@ -1,6 +1,11 @@ -- noinspection SqlResolveForFile -INSERT INTO ARTICLE(writer, title, contents) VALUES ('테스터', '샘플 게시물', '이 게시물은 샘플입니다.'); -INSERT INTO ARTICLE(writer, title, contents) VALUES ('테스터', '샘플 게시물 두번째', '이 게시물은 두번째 샘플입니다.'); +INSERT INTO ARTICLE(writer_userId, writer_name, title, contents) +VALUES ('tester', '테스터', '샘플 게시물', '이 게시물은 샘플입니다.'); + +INSERT INTO ARTICLE(writer_userId, writer_name, title, contents) +VALUES ('dorayaki', '도라에몽', '샘플 게시물 두번째', '이 게시물은 두번째 샘플입니다.'); + INSERT INTO CAFE_USER(userid, password, name, email) VALUES ('tester', 'aaa', '테스터', 'tester@testers.com'); + INSERT INTO CAFE_USER(userid, password, name, email) VALUES ('dorayaki', 'aaa', '도라에몽', 'help-me@dorae.mon'); diff --git a/src/main/resources/sql/schema.sql b/src/main/resources/sql/schema.sql index 909aa46ca..23f65e090 100644 --- a/src/main/resources/sql/schema.sql +++ b/src/main/resources/sql/schema.sql @@ -3,11 +3,12 @@ DROP TABLE IF EXISTS CAFE_USER; CREATE TABLE ARTICLE ( - id BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY, - timestamp TIMESTAMP DEFAULT NOW(), - writer VARCHAR(255), - title VARCHAR(255), - contents VARCHAR(65535) + id BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY, + timestamp TIMESTAMP DEFAULT NOW(), + writer_userid VARCHAR(255), + writer_name VARCHAR(255), + title VARCHAR(255), + contents VARCHAR(65535) ); CREATE TABLE CAFE_USER diff --git a/src/main/resources/templates/badRequest.html b/src/main/resources/templates/badRequest.html index a40186b2b..c0d57135a 100644 --- a/src/main/resources/templates/badRequest.html +++ b/src/main/resources/templates/badRequest.html @@ -14,7 +14,7 @@
에러 이미지 -

"다른 사람의 정보를 수정하려고 하잖아요."

+

"다른 사람의 권한을 침범하려고 하잖아요."

diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index 927120da2..193f8ddf0 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -26,7 +26,7 @@ {{#formattedAsArticleTimestamp}} {{timestamp}} {{/formattedAsArticleTimestamp}} - {{writer}} + {{writerName}}
diff --git a/src/main/resources/templates/qna/form.html b/src/main/resources/templates/qna/form.html index be6128c80..596a74f2e 100644 --- a/src/main/resources/templates/qna/form.html +++ b/src/main/resources/templates/qna/form.html @@ -13,10 +13,6 @@