diff --git a/src/main/java/run/halo/app/controller/admin/api/AdminController.java b/src/main/java/run/halo/app/controller/admin/api/AdminController.java index ed6ddb456..09a67d49f 100644 --- a/src/main/java/run/halo/app/controller/admin/api/AdminController.java +++ b/src/main/java/run/halo/app/controller/admin/api/AdminController.java @@ -6,13 +6,11 @@ import org.springframework.web.bind.annotation.*; import run.halo.app.cache.lock.CacheLock; import run.halo.app.exception.BadRequestException; import run.halo.app.model.dto.CountDTO; -import run.halo.app.model.dto.UserDTO; -import run.halo.app.model.enums.PostStatus; import run.halo.app.model.params.LoginParam; -import run.halo.app.model.properties.PrimaryProperties; import run.halo.app.security.context.SecurityContextHolder; import run.halo.app.security.filter.AdminAuthenticationFilter; -import run.halo.app.service.*; +import run.halo.app.security.token.AuthToken; +import run.halo.app.service.AdminService; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; @@ -28,30 +26,10 @@ import javax.validation.Valid; @RequestMapping("/api/admin") public class AdminController { - private final PostService postService; + private final AdminService adminService; - private final AttachmentService attachmentService; - - private final PostCommentService postCommentService; - - private final OptionService optionService; - - private final UserService userService; - - private final LinkService linkService; - - public AdminController(PostService postService, - AttachmentService attachmentService, - PostCommentService postCommentService, - OptionService optionService, - UserService userService, - LinkService linkService) { - this.postService = postService; - this.attachmentService = attachmentService; - this.postCommentService = postCommentService; - this.optionService = optionService; - this.userService = userService; - this.linkService = linkService; + public AdminController(AdminService adminService) { + this.adminService = adminService; } /** @@ -62,36 +40,20 @@ public class AdminController { @GetMapping("counts") @ApiOperation("Gets count info") public CountDTO getCount() { - CountDTO countDTO = new CountDTO(); - countDTO.setPostCount(postService.countByStatus(PostStatus.PUBLISHED)); - countDTO.setAttachmentCount(attachmentService.count()); - countDTO.setCommentCount(postCommentService.count()); - - long currentTimeMillis = System.currentTimeMillis(); - - // Calculate birthday - // TODO Initialize the birthday if absent - Long birthday = optionService.getByPropertyOrDefault(PrimaryProperties.BIRTHDAY, Long.class, currentTimeMillis); - long days = (currentTimeMillis - birthday) / (1000 * 24 * 3600); - countDTO.setEstablishDays(days); - - countDTO.setLinkCount(linkService.count()); - countDTO.setVisitCount(postService.countVisit()); - countDTO.setLikeCount(postService.countLike()); - return countDTO; + return adminService.getCount(); } - @PostMapping("login") - @ApiOperation("Login with session") - @CacheLock(autoDelete = false, traceRequest = true) - public UserDTO login(@Valid @RequestBody LoginParam loginParam, HttpServletRequest request) { - return new UserDTO().convertFrom(userService.login(loginParam.getUsername(), loginParam.getPassword(), request.getSession())); + @PostMapping("auth/login") + @ApiOperation("Login") + public AuthToken auth(@RequestBody @Valid LoginParam loginParam) { + return adminService.authenticate(loginParam); } @PostMapping("logout") @ApiOperation("Logs out (Clear session)") @CacheLock public void logout(HttpServletRequest request) { + adminService.clearAuthentication(); // Check if the current is logging in boolean authenticated = SecurityContextHolder.getContext().isAuthenticated(); diff --git a/src/main/java/run/halo/app/repository/base/BaseCommentRepository.java b/src/main/java/run/halo/app/repository/base/BaseCommentRepository.java index bb9721be3..09429b537 100644 --- a/src/main/java/run/halo/app/repository/base/BaseCommentRepository.java +++ b/src/main/java/run/halo/app/repository/base/BaseCommentRepository.java @@ -61,6 +61,14 @@ public interface BaseCommentRepository extends Base @NonNull List countByPostIds(@NonNull Iterable postIds); + /** + * Counts by comment status. + * + * @param status comment status must not be null + * @return comment count + */ + long countByStatus(@NonNull CommentStatus status); + /** * Finds comments by post id, comment status. * diff --git a/src/main/java/run/halo/app/service/AdminService.java b/src/main/java/run/halo/app/service/AdminService.java new file mode 100644 index 000000000..bc9272409 --- /dev/null +++ b/src/main/java/run/halo/app/service/AdminService.java @@ -0,0 +1,37 @@ +package run.halo.app.service; + +import org.springframework.lang.NonNull; +import run.halo.app.model.dto.CountDTO; +import run.halo.app.model.params.LoginParam; +import run.halo.app.security.token.AuthToken; + +/** + * Admin service. + * + * @author johnniang + * @date 19-4-29 + */ +public interface AdminService { + + /** + * Authenticates. + * + * @param loginParam login param must not be null + * @return authentication token + */ + @NonNull + AuthToken authenticate(@NonNull LoginParam loginParam); + + /** + * Clears authentication. + */ + void clearAuthentication(); + + /** + * Get system counts. + * + * @return count dto + */ + @NonNull + CountDTO getCount(); +} diff --git a/src/main/java/run/halo/app/service/OptionService.java b/src/main/java/run/halo/app/service/OptionService.java index 636bb6636..4653de673 100755 --- a/src/main/java/run/halo/app/service/OptionService.java +++ b/src/main/java/run/halo/app/service/OptionService.java @@ -288,4 +288,11 @@ public interface OptionService extends CrudService { @NonNull String getBlogBaseUrl(); + /** + * Gets blog birthday. + * + * @return birthday timestamp + */ + long getBirthday(); + } diff --git a/src/main/java/run/halo/app/service/UserService.java b/src/main/java/run/halo/app/service/UserService.java index 8a8f140b0..1dda68976 100755 --- a/src/main/java/run/halo/app/service/UserService.java +++ b/src/main/java/run/halo/app/service/UserService.java @@ -1,10 +1,10 @@ package run.halo.app.service; +import org.springframework.lang.NonNull; import run.halo.app.exception.NotFoundException; import run.halo.app.model.entity.User; import run.halo.app.model.params.UserParam; import run.halo.app.service.base.CrudService; -import org.springframework.lang.NonNull; import javax.servlet.http.HttpSession; import java.util.Optional; @@ -82,11 +82,11 @@ public interface UserService extends CrudService { * * @param key username or email must not be blank * @param password password must not be blank - * @param httpSession http session must not be null * @return user info */ @NonNull - User login(@NonNull String key, @NonNull String password, @NonNull HttpSession httpSession); + @Deprecated + User login(@NonNull String key, @NonNull String password); /** * Updates user password. diff --git a/src/main/java/run/halo/app/service/base/BaseCommentService.java b/src/main/java/run/halo/app/service/base/BaseCommentService.java index 6c53b6db2..7e4cb8788 100644 --- a/src/main/java/run/halo/app/service/base/BaseCommentService.java +++ b/src/main/java/run/halo/app/service/base/BaseCommentService.java @@ -99,6 +99,14 @@ public interface BaseCommentService extends CrudSer @NonNull Map countByPostIds(@Nullable Collection postIds); + /** + * Counts by comment status. + * + * @param status comment status must not be null + * @return comment count + */ + long countByStatus(@NonNull CommentStatus status); + /** * Creates a comment by comment. * diff --git a/src/main/java/run/halo/app/service/impl/AdminServiceImpl.java b/src/main/java/run/halo/app/service/impl/AdminServiceImpl.java new file mode 100644 index 000000000..a5199bb23 --- /dev/null +++ b/src/main/java/run/halo/app/service/impl/AdminServiceImpl.java @@ -0,0 +1,110 @@ +package run.halo.app.service.impl; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.util.Assert; +import run.halo.app.cache.StringCacheStore; +import run.halo.app.exception.BadRequestException; +import run.halo.app.model.dto.CountDTO; +import run.halo.app.model.enums.CommentStatus; +import run.halo.app.model.enums.PostStatus; +import run.halo.app.model.params.LoginParam; +import run.halo.app.security.context.SecurityContextHolder; +import run.halo.app.security.token.AuthToken; +import run.halo.app.service.*; + +/** + * Admin service implementation. + * + * @author johnniang + * @date 19-4-29 + */ +@Slf4j +@Service +public class AdminServiceImpl implements AdminService { + + private final PostService postService; + + private final SheetService sheetService; + + private final AttachmentService attachmentService; + + private final PostCommentService postCommentService; + + private final SheetCommentService sheetCommentService; + + private final JournalCommentService journalCommentService; + + private final OptionService optionService; + + private final UserService userService; + + private final LinkService linkService; + + private final StringCacheStore cacheStore; + + public AdminServiceImpl(PostService postService, + SheetService sheetService, + AttachmentService attachmentService, + PostCommentService postCommentService, + SheetCommentService sheetCommentService, + JournalCommentService journalCommentService, + OptionService optionService, + UserService userService, + LinkService linkService, + StringCacheStore cacheStore) { + this.postService = postService; + this.sheetService = sheetService; + this.attachmentService = attachmentService; + this.postCommentService = postCommentService; + this.sheetCommentService = sheetCommentService; + this.journalCommentService = journalCommentService; + this.optionService = optionService; + this.userService = userService; + this.linkService = linkService; + this.cacheStore = cacheStore; + } + + @Override + public AuthToken authenticate(LoginParam loginParam) { + Assert.notNull(loginParam, "Login param must not be null"); + + return null; + } + + @Override + public void clearAuthentication() { + // Check if the current is logging in + boolean authenticated = SecurityContextHolder.getContext().isAuthenticated(); + + if (!authenticated) { + throw new BadRequestException("You haven't logged in yet, so you can't log out"); + } + + log.info("You have been logged out, looking forward to your next visit!"); + } + + @Override + public CountDTO getCount() { + CountDTO countDTO = new CountDTO(); + countDTO.setPostCount(postService.countByStatus(PostStatus.PUBLISHED)); + countDTO.setAttachmentCount(attachmentService.count()); + + // Handle comment count + long postCommentCount = postCommentService.countByStatus(CommentStatus.PUBLISHED); + long sheetCommentCount = sheetCommentService.countByStatus(CommentStatus.PUBLISHED); + long journalCommentCount = journalCommentService.countByStatus(CommentStatus.PUBLISHED); + + countDTO.setCommentCount(postCommentCount + sheetCommentCount + journalCommentCount); + + long birthday = optionService.getBirthday(); + long days = (System.currentTimeMillis() - birthday) / (1000 * 24 * 3600); + countDTO.setEstablishDays(days); + + countDTO.setLinkCount(linkService.count()); + + countDTO.setVisitCount(postService.countVisit() + sheetService.countVisit()); + countDTO.setLikeCount(postService.countLike() + sheetService.countLike()); + return countDTO; + } +} diff --git a/src/main/java/run/halo/app/service/impl/BaseCommentServiceImpl.java b/src/main/java/run/halo/app/service/impl/BaseCommentServiceImpl.java index 7473feb8e..1fade9883 100644 --- a/src/main/java/run/halo/app/service/impl/BaseCommentServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/BaseCommentServiceImpl.java @@ -196,6 +196,11 @@ public abstract class BaseCommentServiceImpl extend return ServiceUtils.convertToMap(commentCountProjections, CommentCountProjection::getPostId, CommentCountProjection::getCount); } + @Override + public long countByStatus(CommentStatus status) { + return baseCommentRepository.countByStatus(status); + } + @Override public COMMENT create(COMMENT comment) { Assert.notNull(comment, "Domain must not be null"); diff --git a/src/main/java/run/halo/app/service/impl/OptionServiceImpl.java b/src/main/java/run/halo/app/service/impl/OptionServiceImpl.java index 4b4146559..5e5980afd 100644 --- a/src/main/java/run/halo/app/service/impl/OptionServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/OptionServiceImpl.java @@ -20,6 +20,7 @@ import run.halo.app.model.properties.*; import run.halo.app.repository.OptionRepository; import run.halo.app.service.OptionService; import run.halo.app.service.base.AbstractCrudService; +import run.halo.app.utils.DateUtils; import run.halo.app.utils.HaloUtils; import run.halo.app.utils.ServiceUtils; @@ -380,6 +381,15 @@ public class OptionServiceImpl extends AbstractCrudService impl return blogUrl; } + @Override + public long getBirthday() { + return getByProperty(PrimaryProperties.BIRTHDAY, Long.class).orElseGet(() -> { + long currentTime = DateUtils.now().getTime(); + saveProperty(PrimaryProperties.BIRTHDAY, String.valueOf(currentTime)); + return currentTime; + }); + } + private void publishOptionUpdatedEvent() { eventPublisher.publishEvent(new OptionUpdatedEvent(this)); } diff --git a/src/main/java/run/halo/app/service/impl/UserServiceImpl.java b/src/main/java/run/halo/app/service/impl/UserServiceImpl.java index 201a228d2..bd9b119c9 100644 --- a/src/main/java/run/halo/app/service/impl/UserServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/UserServiceImpl.java @@ -24,8 +24,8 @@ import run.halo.app.service.UserService; import run.halo.app.service.base.AbstractCrudService; import run.halo.app.utils.DateUtils; import run.halo.app.utils.HaloUtils; +import run.halo.app.utils.ServletUtils; -import javax.servlet.http.HttpSession; import java.util.Date; import java.util.List; import java.util.Optional; @@ -103,10 +103,9 @@ public class UserServiceImpl extends AbstractCrudService implemen } @Override - public User login(String key, String password, HttpSession httpSession) { + public User login(String key, String password) { Assert.hasText(key, "Username or email must not be blank"); Assert.hasText(password, "Password must not be blank"); - Assert.notNull(httpSession, "Http session must not be null"); // Check login status if (SecurityContextHolder.getContext().isAuthenticated()) { @@ -155,7 +154,9 @@ public class UserServiceImpl extends AbstractCrudService implemen stringCacheStore.delete(LOGIN_FAILURE_COUNT_KEY); // Set session - httpSession.setAttribute(AdminAuthenticationFilter.ADMIN_SESSION_KEY, new UserDetail(user)); + ServletUtils.getCurrentRequest().ifPresent(request -> { + request.getSession().setAttribute(AdminAuthenticationFilter.ADMIN_SESSION_KEY, new UserDetail(user)); + }); // Log it eventPublisher.publishEvent(new LogEvent(this, user.getId().toString(), LogType.LOGGED_IN, user.getUsername()));