From 6a92fcf7d39e505c88a9c9fccb21d4fff00fa571 Mon Sep 17 00:00:00 2001 From: Maxim Shestakov Date: Wed, 2 Aug 2017 15:45:25 +0300 Subject: [PATCH] admin_deily_report --- src/main/java/ru/mystamps/web/Url.java | 4 +- .../web/config/ControllersConfig.java | 8 +++ .../web/controller/ReportController.java | 48 ++++++++++++++ .../ru/mystamps/web/service/CronService.java | 3 + .../mystamps/web/service/CronServiceImpl.java | 11 +++- .../ru/mystamps/web/service/MailService.java | 1 + .../mystamps/web/service/MailServiceImpl.java | 63 ++++++++++--------- .../support/spring/security/Authority.java | 1 + .../security/CustomUserDetailsService.java | 1 + .../support/spring/security/HasAuthority.java | 1 + .../spring/security/SecurityConfig.java | 1 + .../spring/security/StringAuthority.java | 1 + .../ru/mystamps/i18n/Messages.properties | 1 + .../ru/mystamps/i18n/Messages_ru.properties | 1 + src/main/webapp/WEB-INF/views/site/index.html | 3 + 15 files changed, 117 insertions(+), 31 deletions(-) create mode 100644 src/main/java/ru/mystamps/web/controller/ReportController.java diff --git a/src/main/java/ru/mystamps/web/Url.java b/src/main/java/ru/mystamps/web/Url.java index beda726feb..1ccf61b213 100644 --- a/src/main/java/ru/mystamps/web/Url.java +++ b/src/main/java/ru/mystamps/web/Url.java @@ -37,7 +37,8 @@ public final class Url { public static final String INDEX_PAGE = "/"; public static final String ROBOTS_TXT = "/robots.txt"; public static final String SITEMAP_XML = "/sitemap.xml"; - + + public static final String DAILY_STATISTICS = "/report/daily"; public static final String SITE_EVENTS_PAGE = "/site/events"; public static final String REGISTRATION_PAGE = "/account/register"; @@ -141,6 +142,7 @@ public static Map asMap(boolean serveContentFromSingleHost) { map.put("INFO_COLLECTION_PAGE", INFO_COLLECTION_PAGE); map.put("SITE_EVENTS_PAGE", SITE_EVENTS_PAGE); map.put("BOOTSTRAP_LANGUAGE", BOOTSTRAP_LANGUAGE); + map.put("DAILY_STATISTICS", DAILY_STATISTICS); if (serveContentFromSingleHost) { map.put("BOOTSTRAP_CSS", BOOTSTRAP_CSS); diff --git a/src/main/java/ru/mystamps/web/config/ControllersConfig.java b/src/main/java/ru/mystamps/web/config/ControllersConfig.java index 297d9a6b5c..45178ed849 100644 --- a/src/main/java/ru/mystamps/web/config/ControllersConfig.java +++ b/src/main/java/ru/mystamps/web/config/ControllersConfig.java @@ -87,6 +87,14 @@ public ParticipantController getParticipantController() { public RobotsTxtController getRobotsTxtController() { return new RobotsTxtController(); } + + @Bean + public ReportController getReportController() { + return new ReportController( + servicesConfig.getMailService(), + servicesConfig.getCronService() + ); + } @Bean public SeriesController getSeriesController() { diff --git a/src/main/java/ru/mystamps/web/controller/ReportController.java b/src/main/java/ru/mystamps/web/controller/ReportController.java new file mode 100644 index 0000000000..d2835de780 --- /dev/null +++ b/src/main/java/ru/mystamps/web/controller/ReportController.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2009-2017 Slava Semushin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package ru.mystamps.web.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import lombok.RequiredArgsConstructor; + +import ru.mystamps.web.Url; +import ru.mystamps.web.service.CronService; +import ru.mystamps.web.service.MailService; + +/** + * @author Maxim Shestakov + */ +@Controller +@RequiredArgsConstructor +public class ReportController { + + private final MailService mailService; + private final CronService cronService; + + @GetMapping(path = Url.DAILY_STATISTICS, produces = "text/plain; charset=UTF-8") + @ResponseBody + public String showDailyReport() { + return mailService.prepareDailyStatistics( + cronService.getDailyReport() + ); + } + +} diff --git a/src/main/java/ru/mystamps/web/service/CronService.java b/src/main/java/ru/mystamps/web/service/CronService.java index 795c75d015..1dc6737cc7 100644 --- a/src/main/java/ru/mystamps/web/service/CronService.java +++ b/src/main/java/ru/mystamps/web/service/CronService.java @@ -17,9 +17,12 @@ */ package ru.mystamps.web.service; +import ru.mystamps.web.service.dto.AdminDailyReport; + public interface CronService { int PURGE_AFTER_DAYS = 3; void sendDailyStatistics(); + AdminDailyReport getDailyReport(); void purgeUsersActivations(); } diff --git a/src/main/java/ru/mystamps/web/service/CronServiceImpl.java b/src/main/java/ru/mystamps/web/service/CronServiceImpl.java index 729cbc501c..6dee608c75 100644 --- a/src/main/java/ru/mystamps/web/service/CronServiceImpl.java +++ b/src/main/java/ru/mystamps/web/service/CronServiceImpl.java @@ -30,10 +30,13 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.transaction.annotation.Transactional; +import org.springframework.security.access.prepost.PreAuthorize; + import lombok.RequiredArgsConstructor; import ru.mystamps.web.dao.dto.UsersActivationFullDto; import ru.mystamps.web.service.dto.AdminDailyReport; +import ru.mystamps.web.support.spring.security.HasAuthority; @RequiredArgsConstructor public class CronServiceImpl implements CronService { @@ -55,6 +58,12 @@ public class CronServiceImpl implements CronService { @Scheduled(cron = EVERY_DAY_AT_00_00) @Transactional(readOnly = true) public void sendDailyStatistics() { + mailService.sendDailyStatisticsToAdmin(getDailyReport()); + } + + @Override + @PreAuthorize(HasAuthority.VIEW_DAILY_STATS) + public AdminDailyReport getDailyReport() { Date today = DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH); Date yesterday = DateUtils.addDays(today, -1); @@ -100,7 +109,7 @@ public void sendDailyStatistics() { ); report.setInvalidCsrfCounter(invalidCsrfCounter); - mailService.sendDailyStatisticsToAdmin(report); + return report; } @Override diff --git a/src/main/java/ru/mystamps/web/service/MailService.java b/src/main/java/ru/mystamps/web/service/MailService.java index 10b90db247..add8d93ede 100644 --- a/src/main/java/ru/mystamps/web/service/MailService.java +++ b/src/main/java/ru/mystamps/web/service/MailService.java @@ -23,4 +23,5 @@ public interface MailService { void sendActivationKeyToUser(SendUsersActivationDto activation); void sendDailyStatisticsToAdmin(AdminDailyReport report); + String prepareDailyStatistics(AdminDailyReport report); } diff --git a/src/main/java/ru/mystamps/web/service/MailServiceImpl.java b/src/main/java/ru/mystamps/web/service/MailServiceImpl.java index cdf95f9594..190bc1d798 100644 --- a/src/main/java/ru/mystamps/web/service/MailServiceImpl.java +++ b/src/main/java/ru/mystamps/web/service/MailServiceImpl.java @@ -39,10 +39,13 @@ import org.springframework.mail.javamail.MimeMessagePreparator; import org.springframework.scheduling.annotation.Async; +import org.springframework.security.access.prepost.PreAuthorize; + import ru.mystamps.web.Url; import ru.mystamps.web.service.dto.AdminDailyReport; import ru.mystamps.web.service.dto.SendUsersActivationDto; import ru.mystamps.web.service.exception.EmailSendingException; +import ru.mystamps.web.support.spring.security.HasAuthority; public class MailServiceImpl implements MailService { private static final Logger LOG = LoggerFactory.getLogger(MailServiceImpl.class); @@ -101,7 +104,7 @@ public void sendDailyStatisticsToAdmin(AdminDailyReport report) { sendMail( adminEmail, getSubjectOfDailyStatisticsMail(report), - getTextOfDailyStatisticsMail(report), + prepareDailyStatistics(report), "daily_statistics" ); @@ -114,7 +117,37 @@ public void sendDailyStatisticsToAdmin(AdminDailyReport report) { adminLang ); } + + @Override + @PreAuthorize(HasAuthority.VIEW_DAILY_STATS) + public String prepareDailyStatistics(AdminDailyReport report) { + String template = messageSource.getMessage("daily_stat.text", null, adminLang); + String fromDate = shortDatePrinter.format(report.getStartDate()); + String tillDate = shortDatePrinter.format(report.getEndDate()); + + Map ctx = new HashMap<>(); + ctx.put("from_date", fromDate); + ctx.put("to_date", tillDate); + + put(ctx, "added_countries_cnt", report.getAddedCountriesCounter()); + put(ctx, "untranslated_countries_cnt", report.getUntranslatedCountriesCounter()); + put(ctx, "added_categories_cnt", report.getAddedCategoriesCounter()); + put(ctx, "untranslated_categories_cnt", report.getUntranslatedCategoriesCounter()); + put(ctx, "added_series_cnt", report.getAddedSeriesCounter()); + put(ctx, "updated_series_cnt", report.getUpdatedSeriesCounter()); + put(ctx, "updated_collections_cnt", report.getUpdatedCollectionsCounter()); + put(ctx, "registration_requests_cnt", report.getRegistrationRequestsCounter()); + put(ctx, "registered_users_cnt", report.getRegisteredUsersCounter()); + put(ctx, "events_cnt", report.countEvents()); + put(ctx, "not_found_cnt", report.getNotFoundCounter()); + put(ctx, "failed_auth_cnt", report.getFailedAuthCounter()); + put(ctx, "missing_csrf_cnt", report.getMissingCsrfCounter()); + put(ctx, "invalid_csrf_cnt", report.getInvalidCsrfCounter()); + put(ctx, "bad_request_cnt", -1L); // TODO: #122 + return new StrSubstitutor(ctx).replace(template); + } + @SuppressWarnings("PMD.UseObjectForClearerAPI") private void sendMail( final String email, @@ -183,34 +216,6 @@ private String getSubjectOfDailyStatisticsMail(AdminDailyReport report) { StrSubstitutor substitutor = new StrSubstitutor(ctx); return substitutor.replace(template); } - - private String getTextOfDailyStatisticsMail(AdminDailyReport report) { - String template = messageSource.getMessage("daily_stat.text", null, adminLang); - String fromDate = shortDatePrinter.format(report.getStartDate()); - String tillDate = shortDatePrinter.format(report.getEndDate()); - - Map ctx = new HashMap<>(); - ctx.put("from_date", fromDate); - ctx.put("to_date", tillDate); - - put(ctx, "added_countries_cnt", report.getAddedCountriesCounter()); - put(ctx, "untranslated_countries_cnt", report.getUntranslatedCountriesCounter()); - put(ctx, "added_categories_cnt", report.getAddedCategoriesCounter()); - put(ctx, "untranslated_categories_cnt", report.getUntranslatedCategoriesCounter()); - put(ctx, "added_series_cnt", report.getAddedSeriesCounter()); - put(ctx, "updated_series_cnt", report.getUpdatedSeriesCounter()); - put(ctx, "updated_collections_cnt", report.getUpdatedCollectionsCounter()); - put(ctx, "registration_requests_cnt", report.getRegistrationRequestsCounter()); - put(ctx, "registered_users_cnt", report.getRegisteredUsersCounter()); - put(ctx, "events_cnt", report.countEvents()); - put(ctx, "not_found_cnt", report.getNotFoundCounter()); - put(ctx, "failed_auth_cnt", report.getFailedAuthCounter()); - put(ctx, "missing_csrf_cnt", report.getMissingCsrfCounter()); - put(ctx, "invalid_csrf_cnt", report.getInvalidCsrfCounter()); - put(ctx, "bad_request_cnt", -1L); // TODO: #122 - - return new StrSubstitutor(ctx).replace(template); - } private static void put(Map ctx, String key, long value) { ctx.put(key, String.valueOf(value)); diff --git a/src/main/java/ru/mystamps/web/support/spring/security/Authority.java b/src/main/java/ru/mystamps/web/support/spring/security/Authority.java index b96ef0eede..f3313a7c09 100644 --- a/src/main/java/ru/mystamps/web/support/spring/security/Authority.java +++ b/src/main/java/ru/mystamps/web/support/spring/security/Authority.java @@ -33,6 +33,7 @@ public final class Authority { public static final GrantedAuthority UPDATE_COLLECTION = new SimpleGrantedAuthority(StringAuthority.UPDATE_COLLECTION); public static final GrantedAuthority VIEW_SITE_EVENTS = new SimpleGrantedAuthority(StringAuthority.VIEW_SITE_EVENTS); public static final GrantedAuthority VIEW_SERIES_SALES = new SimpleGrantedAuthority(StringAuthority.VIEW_SERIES_SALES); + public static final GrantedAuthority VIEW_DAILY_STATS = new SimpleGrantedAuthority(StringAuthority.VIEW_DAILY_STATS); private Authority() { } diff --git a/src/main/java/ru/mystamps/web/support/spring/security/CustomUserDetailsService.java b/src/main/java/ru/mystamps/web/support/spring/security/CustomUserDetailsService.java index 6faca3e817..cf72ec4551 100644 --- a/src/main/java/ru/mystamps/web/support/spring/security/CustomUserDetailsService.java +++ b/src/main/java/ru/mystamps/web/support/spring/security/CustomUserDetailsService.java @@ -81,6 +81,7 @@ private static Collection getAuthorities(UserDetails authorities.add(Authority.ADD_SERIES_SALES); authorities.add(Authority.VIEW_SERIES_SALES); authorities.add(Authority.MANAGE_TOGGLZ); + authorities.add(Authority.VIEW_DAILY_STATS); } return authorities; diff --git a/src/main/java/ru/mystamps/web/support/spring/security/HasAuthority.java b/src/main/java/ru/mystamps/web/support/spring/security/HasAuthority.java index 9bae50010f..a6f54248eb 100644 --- a/src/main/java/ru/mystamps/web/support/spring/security/HasAuthority.java +++ b/src/main/java/ru/mystamps/web/support/spring/security/HasAuthority.java @@ -24,6 +24,7 @@ public final class HasAuthority { public static final String CREATE_SERIES = "hasAuthority('" + StringAuthority.CREATE_SERIES + "')"; public static final String CREATE_CATEGORY = "hasAuthority('" + StringAuthority.CREATE_CATEGORY + "')"; public static final String CREATE_COUNTRY = "hasAuthority('" + StringAuthority.CREATE_COUNTRY + "')"; + public static final String VIEW_DAILY_STATS = "hasAuthority('" + StringAuthority.VIEW_DAILY_STATS + "')"; public static final String UPDATE_COLLECTION = "hasAuthority('" + StringAuthority.UPDATE_COLLECTION + "')"; public static final String VIEW_SITE_EVENTS = "hasAuthority('" + StringAuthority.VIEW_SITE_EVENTS + "')"; public static final String VIEW_SERIES_SALES = "hasAuthority('" + StringAuthority.VIEW_SERIES_SALES + "')"; diff --git a/src/main/java/ru/mystamps/web/support/spring/security/SecurityConfig.java b/src/main/java/ru/mystamps/web/support/spring/security/SecurityConfig.java index 36a024dddd..88ef4296ca 100644 --- a/src/main/java/ru/mystamps/web/support/spring/security/SecurityConfig.java +++ b/src/main/java/ru/mystamps/web/support/spring/security/SecurityConfig.java @@ -77,6 +77,7 @@ protected void configure(HttpSecurity http) throws Exception { .mvcMatchers(Url.ADD_SERIES_PAGE).hasAuthority(StringAuthority.CREATE_SERIES) .mvcMatchers(Url.SITE_EVENTS_PAGE).hasAuthority(StringAuthority.VIEW_SITE_EVENTS) .mvcMatchers(Url.SUGGEST_SERIES_COUNTRY).hasAuthority(StringAuthority.CREATE_SERIES) + .mvcMatchers(Url.DAILY_STATISTICS).hasAuthority(StringAuthority.VIEW_DAILY_STATS) .regexMatchers(HttpMethod.POST, "/series/[0-9]+") .hasAnyAuthority( StringAuthority.UPDATE_COLLECTION, diff --git a/src/main/java/ru/mystamps/web/support/spring/security/StringAuthority.java b/src/main/java/ru/mystamps/web/support/spring/security/StringAuthority.java index c049f38206..3c1f4be77b 100644 --- a/src/main/java/ru/mystamps/web/support/spring/security/StringAuthority.java +++ b/src/main/java/ru/mystamps/web/support/spring/security/StringAuthority.java @@ -29,6 +29,7 @@ public final class StringAuthority { public static final String UPDATE_COLLECTION = "UPDATE_COLLECTION"; public static final String VIEW_SITE_EVENTS = "VIEW_SITE_EVENTS"; public static final String VIEW_SERIES_SALES = "VIEW_SERIES_SALES"; + public static final String VIEW_DAILY_STATS = "VIEW_DAILY_STATS"; private StringAuthority() { } diff --git a/src/main/resources/ru/mystamps/i18n/Messages.properties b/src/main/resources/ru/mystamps/i18n/Messages.properties index 19466ab226..3c3e44b038 100644 --- a/src/main/resources/ru/mystamps/i18n/Messages.properties +++ b/src/main/resources/ru/mystamps/i18n/Messages.properties @@ -67,6 +67,7 @@ t_example = Example t_catalog = Catalog t_search = Search t_view_suspicious_activities = view suspicious activities +t_view_daily_statistics = view daily statistics # account/register.html t_registration_on_site = Register on site diff --git a/src/main/resources/ru/mystamps/i18n/Messages_ru.properties b/src/main/resources/ru/mystamps/i18n/Messages_ru.properties index 86a12b7378..fdd474dc89 100644 --- a/src/main/resources/ru/mystamps/i18n/Messages_ru.properties +++ b/src/main/resources/ru/mystamps/i18n/Messages_ru.properties @@ -67,6 +67,7 @@ t_example = Пример t_catalog = Каталог t_search = Найти t_view_suspicious_activities = посмотреть подозрительные события +t_view_daily_statistics = посмотреть дневную статистику # account/register.html t_registration_on_site = Регистрация на сайте diff --git a/src/main/webapp/WEB-INF/views/site/index.html b/src/main/webapp/WEB-INF/views/site/index.html index 7955ca06b8..af6f42cd24 100644 --- a/src/main/webapp/WEB-INF/views/site/index.html +++ b/src/main/webapp/WEB-INF/views/site/index.html @@ -117,6 +117,9 @@
  • view suspicious activities
  • +
  • + view daily statistics +