From 72b25686df1e736e636e321fe4ac0c676ae95ee7 Mon Sep 17 00:00:00 2001 From: Robert Goldmann <deadlocker@gmx.de> Date: Thu, 14 Jun 2018 19:15:10 +0200 Subject: [PATCH] #256 - implemented database delete with verification code --- .../controller/SettingsController.java | 29 +++++++++ .../budgetmaster/services/AccountService.java | 28 ++++++--- .../services/CategoryService.java | 36 +++++++---- .../services/DatabaseService.java | 63 +++++++++++++++++++ .../budgetmaster/services/PaymentService.java | 13 +++- .../budgetmaster/services/Resetable.java | 8 +++ .../services/SettingsService.java | 5 ++ .../budgetmaster/services/TagService.java | 31 +++++++++ src/main/resources/languages/_de.properties | 3 +- src/main/resources/languages/_en.properties | 3 +- src/main/resources/static/js/settings.js | 6 ++ src/main/resources/templates/settings.ftl | 29 +++++++++ 12 files changed, 231 insertions(+), 23 deletions(-) create mode 100644 src/main/java/de/deadlocker8/budgetmaster/services/DatabaseService.java create mode 100644 src/main/java/de/deadlocker8/budgetmaster/services/Resetable.java create mode 100644 src/main/java/de/deadlocker8/budgetmaster/services/TagService.java create mode 100644 src/main/resources/static/js/settings.js diff --git a/src/main/java/de/deadlocker8/budgetmaster/controller/SettingsController.java b/src/main/java/de/deadlocker8/budgetmaster/controller/SettingsController.java index 38b2e6c02..723b05dfc 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/controller/SettingsController.java +++ b/src/main/java/de/deadlocker8/budgetmaster/controller/SettingsController.java @@ -4,6 +4,7 @@ import de.deadlocker8.budgetmaster.authentication.User; import de.deadlocker8.budgetmaster.authentication.UserRepository; import de.deadlocker8.budgetmaster.entities.Settings; import de.deadlocker8.budgetmaster.repositories.SettingsRepository; +import de.deadlocker8.budgetmaster.services.DatabaseService; import de.deadlocker8.budgetmaster.services.HelpersService; import de.deadlocker8.budgetmaster.utils.LanguageType; import de.deadlocker8.budgetmaster.utils.Strings; @@ -18,6 +19,9 @@ import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; +import tools.BASE58Type; +import tools.ConvertTo; +import tools.RandomCreations; @Controller @@ -32,6 +36,9 @@ public class SettingsController extends BaseController @Autowired private HelpersService helpers; + @Autowired + private DatabaseService databaseService; + @RequestMapping("/settings") public String settings(Model model) { @@ -94,6 +101,28 @@ public class SettingsController extends BaseController @RequestMapping("/settings/database/requestDelete") public String requestDeleteDatabase(Model model) { + String verificationCode = ConvertTo.toBase58(RandomCreations.generateRandomMixedCaseString(4, true), true, BASE58Type.UPPER); + model.addAttribute("deleteDatabase", true); + model.addAttribute("verificationCode", verificationCode); + return "settings"; + } + + @RequestMapping(value = "/settings/database/delete", method = RequestMethod.POST) + public String deleteDatabase(Model model, + @RequestParam("verificationCode") String verificationCode, + @RequestParam("verificationUserInput") String verificationUserInput) + { + if(verificationUserInput.equals(verificationCode)) + { + LOGGER.info("Deleting database..."); + databaseService.reset(); + LOGGER.info("Deleting database DONE."); + } + else + { + return "redirect:/settings/database/requestDelete"; + } + return "settings"; } } \ No newline at end of file diff --git a/src/main/java/de/deadlocker8/budgetmaster/services/AccountService.java b/src/main/java/de/deadlocker8/budgetmaster/services/AccountService.java index 5c7340030..a143ce171 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/services/AccountService.java +++ b/src/main/java/de/deadlocker8/budgetmaster/services/AccountService.java @@ -12,7 +12,7 @@ import org.springframework.stereotype.Service; import tools.Localization; @Service -public class AccountService +public class AccountService implements Resetable { private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); private AccountRepository accountRepository; @@ -24,13 +24,7 @@ public class AccountService this.accountRepository = accountRepository; this.paymentRepository = paymentRepository; - if(accountRepository.findAll().size() == 0) - { - Account account = new Account(Localization.getString(Strings.ACCOUNT_DEFAULT_NAME)); - account.setSelected(true); - accountRepository.save(account); - LOGGER.debug("Created default account"); - } + createDefaults(); } public void deleteAccount(int ID) @@ -39,4 +33,22 @@ public class AccountService paymentRepository.delete(accountToDelete.getReferringPayments()); accountRepository.delete(ID); } + + @Override + public void deleteAll() + { + accountRepository.deleteAll(); + } + + @Override + public void createDefaults() + { + if(accountRepository.findAll().size() == 0) + { + Account account = new Account(Localization.getString(Strings.ACCOUNT_DEFAULT_NAME)); + account.setSelected(true); + accountRepository.save(account); + LOGGER.debug("Created default account"); + } + } } diff --git a/src/main/java/de/deadlocker8/budgetmaster/services/CategoryService.java b/src/main/java/de/deadlocker8/budgetmaster/services/CategoryService.java index 8d971c542..6ed5f137c 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/services/CategoryService.java +++ b/src/main/java/de/deadlocker8/budgetmaster/services/CategoryService.java @@ -10,7 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service -public class CategoryService +public class CategoryService implements Resetable { private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); private CategoryRepository categoryRepository; @@ -20,17 +20,7 @@ public class CategoryService { this.categoryRepository = categoryRepository; - if(categoryRepository.findByType(CategoryType.NONE) == null) - { - categoryRepository.save(new Category("Keine Kategorie", "#FFFFFF", CategoryType.NONE)); - LOGGER.debug("Created default category NONE"); - } - - if(categoryRepository.findByType(CategoryType.REST) == null) - { - categoryRepository.save(new Category("Übertrag", "#FFFF00", CategoryType.REST)); - LOGGER.debug("Created default category REST"); - } + createDefaults(); } public void deleteCategory(int ID) @@ -43,4 +33,26 @@ public class CategoryService categoryRepository.delete(ID); } + + @Override + public void deleteAll() + { + categoryRepository.deleteAll(); + } + + @Override + public void createDefaults() + { + if(categoryRepository.findByType(CategoryType.NONE) == null) + { + categoryRepository.save(new Category("Keine Kategorie", "#FFFFFF", CategoryType.NONE)); + LOGGER.debug("Created default category NONE"); + } + + if(categoryRepository.findByType(CategoryType.REST) == null) + { + categoryRepository.save(new Category("Übertrag", "#FFFF00", CategoryType.REST)); + LOGGER.debug("Created default category REST"); + } + } } diff --git a/src/main/java/de/deadlocker8/budgetmaster/services/DatabaseService.java b/src/main/java/de/deadlocker8/budgetmaster/services/DatabaseService.java new file mode 100644 index 000000000..b803c1c3f --- /dev/null +++ b/src/main/java/de/deadlocker8/budgetmaster/services/DatabaseService.java @@ -0,0 +1,63 @@ +package de.deadlocker8.budgetmaster.services; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class DatabaseService +{ + private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); + private AccountService accountService; + private CategoryService categoryService; + private PaymentService paymentService; + + @Autowired + public DatabaseService(AccountService accountService, CategoryService categoryService, PaymentService paymentService) + { + this.accountService = accountService; + this.categoryService = categoryService; + this.paymentService = paymentService; + } + + public void reset() + { + resetPayments(); + resetCategories(); + resetAccounts(); + resetTags(); + } + + private void resetAccounts() + { + LOGGER.info("Resetting accounts..."); + accountService.deleteAll(); + accountService.createDefaults(); + LOGGER.info("All accounts reset."); + } + + private void resetCategories() + { + LOGGER.info("Resetting categories..."); + categoryService.deleteAll(); + categoryService.createDefaults(); + LOGGER.info("All categories reset."); + } + + private void resetPayments() + { + LOGGER.info("Resetting payments..."); + paymentService.deleteAll(); + paymentService.createDefaults(); + LOGGER.info("All payments reset."); + } + + private void resetTags() + { + LOGGER.info("Resetting tags..."); + paymentService.deleteAll(); + paymentService.createDefaults(); + LOGGER.info("All tags reset."); + } +} diff --git a/src/main/java/de/deadlocker8/budgetmaster/services/PaymentService.java b/src/main/java/de/deadlocker8/budgetmaster/services/PaymentService.java index 5506d89ed..ba3907ddb 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/services/PaymentService.java +++ b/src/main/java/de/deadlocker8/budgetmaster/services/PaymentService.java @@ -14,7 +14,7 @@ import org.springframework.stereotype.Service; import java.util.List; @Service -public class PaymentService +public class PaymentService implements Resetable { private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); private PaymentRepository paymentRepository; @@ -56,4 +56,15 @@ public class PaymentService Payment paymentToDelete = paymentRepository.getOne(ID); return paymentToDelete != null && paymentToDelete.getCategory().getType() != CategoryType.REST; } + + @Override + public void deleteAll() + { + paymentRepository.deleteAll(); + } + + @Override + public void createDefaults() + { + } } diff --git a/src/main/java/de/deadlocker8/budgetmaster/services/Resetable.java b/src/main/java/de/deadlocker8/budgetmaster/services/Resetable.java new file mode 100644 index 000000000..4809c4c66 --- /dev/null +++ b/src/main/java/de/deadlocker8/budgetmaster/services/Resetable.java @@ -0,0 +1,8 @@ +package de.deadlocker8.budgetmaster.services; + +public interface Resetable +{ + public void deleteAll(); + + public void createDefaults(); +} diff --git a/src/main/java/de/deadlocker8/budgetmaster/services/SettingsService.java b/src/main/java/de/deadlocker8/budgetmaster/services/SettingsService.java index f28e203b1..9c9609b14 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/services/SettingsService.java +++ b/src/main/java/de/deadlocker8/budgetmaster/services/SettingsService.java @@ -20,6 +20,11 @@ public class SettingsService public SettingsService(SettingsRepository settingsRepository) { this.settingsRepository = settingsRepository; + createDefaultSettingsIfNotExists(); + } + + public void createDefaultSettingsIfNotExists() + { if(settingsRepository.findOne(0) == null) { settingsRepository.save(Settings.getDefault()); diff --git a/src/main/java/de/deadlocker8/budgetmaster/services/TagService.java b/src/main/java/de/deadlocker8/budgetmaster/services/TagService.java new file mode 100644 index 000000000..7e806c13f --- /dev/null +++ b/src/main/java/de/deadlocker8/budgetmaster/services/TagService.java @@ -0,0 +1,31 @@ +package de.deadlocker8.budgetmaster.services; + +import de.deadlocker8.budgetmaster.repositories.TagRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class TagService implements Resetable +{ + private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); + private TagRepository tagRepository; + + @Autowired + public TagService(TagRepository tagRepository) + { + this.tagRepository = tagRepository; + } + + @Override + public void deleteAll() + { + tagRepository.deleteAll(); + } + + @Override + public void createDefaults() + { + } +} diff --git a/src/main/resources/languages/_de.properties b/src/main/resources/languages/_de.properties index 5abbea017..8b473187b 100644 --- a/src/main/resources/languages/_de.properties +++ b/src/main/resources/languages/_de.properties @@ -174,7 +174,7 @@ info.text.database.import.dialog=Soll die Datenbank vor dem Importieren gel info.text.database.import.dialog.delete=Ja, Datenbank l�schen info.text.database.import.dialog.append=Nein, Daten hinzuf�gen info.title.database.delete=Datenbank l�schen -info.header.text.database.delete=Soll die Datenbank wirklich gel�scht werden? +info.header.text.database.delete=Soll die Datenbank wirklich unwiderruflich gel�scht werden? info.text.database.delete=Zur Best�tigung gib folgenden Code ein:\t{0} info.title.welcome=Willkommen info.header.text.welcome=Willkommen beim BudgetMaster @@ -335,6 +335,7 @@ settings.updates.latest.version=Verf settings.database.import=Importieren settings.database.export=Exportieren settings.database.delete=L�schen +settings.database.delete.verification=Best�tigungscode account.new.label.name=Name account.default.name=Standardkonto diff --git a/src/main/resources/languages/_en.properties b/src/main/resources/languages/_en.properties index 2e62291e1..ad840213b 100644 --- a/src/main/resources/languages/_en.properties +++ b/src/main/resources/languages/_en.properties @@ -174,7 +174,7 @@ info.text.database.import.dialog=Do you want to delete the database before impor info.text.database.import.dialog.delete=Yes, delete database info.text.database.import.dialog.append=No, append data info.title.database.delete=Delete Database -info.header.text.database.delete=Do you really want to delete this entry? This can''t be undone. +info.header.text.database.delete=Do you really want to delete the database? This can''t be undone. info.text.database.delete=Please enter the following code for verification:\t{0} info.title.welcome=Welcome info.header.text.welcome=Welcome to BudgetMaster @@ -335,6 +335,7 @@ settings.updates.latest.version=Available: settings.database.import=Import settings.database.export=Export settings.database.delete=Delete +settings.database.delete.verification=Verification Code account.new.label.name=Name account.default.name=Default Account diff --git a/src/main/resources/static/js/settings.js b/src/main/resources/static/js/settings.js new file mode 100644 index 000000000..1992f4d0e --- /dev/null +++ b/src/main/resources/static/js/settings.js @@ -0,0 +1,6 @@ +$( document ).ready(function() { + $('#button-confirm-database-delete').click(function() + { + document.getElementById("form-confirm-database-delete").submit(); + }); +}); \ No newline at end of file diff --git a/src/main/resources/templates/settings.ftl b/src/main/resources/templates/settings.ftl index 02da49cce..12771797b 100644 --- a/src/main/resources/templates/settings.ftl +++ b/src/main/resources/templates/settings.ftl @@ -174,10 +174,39 @@ </div> </main> + <#if deleteDatabase??> + <!-- confirm delete modal --> + <div id="modalConfirmDelete" class="modal"> + <div class="modal-content"> + <h4>${locale.getString("info.title.database.delete")}</h4> + <p>${locale.getString("info.header.text.database.delete")}</p> + <p>${locale.getString("info.text.database.delete", verificationCode)}</p> + + <form id="form-confirm-database-delete" action="/settings/database/delete" method="post"> + <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> + <input type="hidden" name="verificationCode" value="${verificationCode}"/> + + <div class="row"> + <div class="input-field col s12 m8 l6"> + <input id="verification" type="text" name="verificationUserInput"> + <label for="verification">${locale.getString("settings.database.delete.verification")}</label> + </div> + </div> + </form> + + </div> + <div class="modal-footer"> + <a href="/settings" class="modal-action modal-close waves-effect waves-red btn-flat ">${locale.getString("cancel")}</a> + <a class="modal-action modal-close waves-effect waves-green btn-flat" id="button-confirm-database-delete">${locale.getString("delete")}</a> + </div> + </div> + </#if> + <!-- Scripts--> <#import "scripts.ftl" as scripts> <@scripts.scripts/> <script src="/js/spectrum.js"></script> <script src="/js/categories.js"></script> + <script src="/js/settings.js"></script> </body> </html> \ No newline at end of file -- GitLab