From 15616e05f34ab2d2069f4f45bcf7a573bead36f7 Mon Sep 17 00:00:00 2001 From: CodeSteak Date: Sun, 14 Jun 2020 15:54:56 +0200 Subject: [PATCH 01/25] [HOTFIX] Prevent path directory traversal attack for deploy --- .../controller/shop/ShopArticleController.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopArticleController.java b/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopArticleController.java index 18144f7..bca16ab 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopArticleController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopArticleController.java @@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; @@ -102,9 +103,14 @@ public class ShopArticleController { Article article = articleRepository.findArticleById(id); if(article.image != null) { - InputStream in = new FileInputStream(article.image.path); - response.setContentType(MediaType.IMAGE_JPEG_VALUE); - IOUtils.copy(in, response.getOutputStream()); + File file = new File(article.image.path); + if (file.getCanonicalPath().startsWith("./data/img/")) { + InputStream in = new FileInputStream(file); + response.setContentType(MediaType.IMAGE_JPEG_VALUE); + IOUtils.copy(in, response.getOutputStream()); + } else { + throw new RuntimeException("Got illegal file path. DB was modified."); + } } } } \ No newline at end of file From 3bb3c5b513ad64841ecbaea05095a221f3c47174 Mon Sep 17 00:00:00 2001 From: CodeSteak Date: Sun, 14 Jun 2020 16:51:59 +0200 Subject: [PATCH 02/25] [HOTFIX] of HOTFIX: Use CanonicalPath for check --- .../ecommerce/controller/shop/ShopArticleController.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopArticleController.java b/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopArticleController.java index bca16ab..b1df109 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopArticleController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopArticleController.java @@ -101,10 +101,12 @@ public class ShopArticleController { @PathVariable("id") Long id ) throws IOException { Article article = articleRepository.findArticleById(id); - + if(article.image != null) { File file = new File(article.image.path); - if (file.getCanonicalPath().startsWith("./data/img/")) { + File allowedPath = new File("./data/img/"); + + if (file.getCanonicalPath().startsWith(allowedPath.getCanonicalPath())) { InputStream in = new FileInputStream(file); response.setContentType(MediaType.IMAGE_JPEG_VALUE); IOUtils.copy(in, response.getOutputStream()); From fa610cae3b5594cc289648cd90618883e24465fb Mon Sep 17 00:00:00 2001 From: Hannes Date: Sun, 14 Jun 2020 17:56:09 +0200 Subject: [PATCH 03/25] if no orders show hint --- .../src/main/resources/templates/user/orders/index.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/prototype/src/main/resources/templates/user/orders/index.html b/prototype/src/main/resources/templates/user/orders/index.html index 023910d..35187bd 100644 --- a/prototype/src/main/resources/templates/user/orders/index.html +++ b/prototype/src/main/resources/templates/user/orders/index.html @@ -21,7 +21,10 @@
-
+
+

Mit diesem Account wurden noch keine Bestellungen getätigt.

+
+

From 985169117dd1f1b8afcbaa34558108875d251ac6 Mon Sep 17 00:00:00 2001 From: Hannes Date: Sun, 14 Jun 2020 18:19:59 +0200 Subject: [PATCH 04/25] fix nullpointer in settings --- .../java/org/hso/ecommerce/controller/UserController.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/UserController.java b/prototype/src/main/java/org/hso/ecommerce/controller/UserController.java index 8a90d43..97c5bf6 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/UserController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/UserController.java @@ -1,6 +1,7 @@ package org.hso.ecommerce.controller; import org.hso.ecommerce.action.user.UpdateUserSettingsAction; +import org.hso.ecommerce.entities.shop.Address; import org.hso.ecommerce.entities.shop.CustomerOrder; import org.hso.ecommerce.entities.user.User; import org.hso.ecommerce.repos.shop.CustomerOrderRepository; @@ -38,6 +39,9 @@ public class UserController { ) { long userId = (long) session.getAttribute("userId"); User user = userRepository.findById(userId).get(); + if(user.defaultDeliveryAddress == null){ + user.defaultDeliveryAddress = new Address(); + } model.addAttribute("user", user); return "user/settings"; From 0a7722d612989a581e81126623dced896b416a00 Mon Sep 17 00:00:00 2001 From: localhorst Date: Mon, 15 Jun 2020 09:40:32 +0200 Subject: [PATCH 05/25] removed register user type and ad --- .../controller/RegisterController.java | 2 -- .../src/main/resources/templates/register.html | 17 ----------------- 2 files changed, 19 deletions(-) diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/RegisterController.java b/prototype/src/main/java/org/hso/ecommerce/controller/RegisterController.java index 36fcdef..008cd0b 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/RegisterController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/RegisterController.java @@ -26,8 +26,6 @@ public class RegisterController { @RequestParam("username") String username, @RequestParam("password") String password, @RequestParam("password2") String password2, @RequestParam("salutation") String salutation, @RequestParam("name") String name, @RequestParam("address") String address, - @RequestParam("type") String type, // TODO store - @RequestParam("ad") String ad, // TODO store HttpSession session) { Optional user = userRepository.findByEmail(username); if (user.isPresent()) { diff --git a/prototype/src/main/resources/templates/register.html b/prototype/src/main/resources/templates/register.html index de4b839..3920e65 100644 --- a/prototype/src/main/resources/templates/register.html +++ b/prototype/src/main/resources/templates/register.html @@ -54,23 +54,6 @@ -
- -
- -
-
-
-

Werbung

-
-
-
- -
- -
-
-
From b6eb66e348d590a784b8202ea312070996b30a19 Mon Sep 17 00:00:00 2001 From: Hannes Huber Date: Mon, 15 Jun 2020 10:19:16 +0200 Subject: [PATCH 06/25] =?UTF-8?q?Dateien=20hochladen=20nach=20=E2=80=9Esup?= =?UTF-8?q?plier/config=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- supplier/config/mda.json | 50 ++++++++++++++++++++++++++++ supplier/config/outtel.json | 42 ++++++++++++++++++++++++ supplier/config/pear.json | 50 ++++++++++++++++++++++++++++ supplier/config/sumsang.json | 42 ++++++++++++++++++++++++ supplier/config/techdealer.json | 58 +++++++++++++++++++++++++++++++++ 5 files changed, 242 insertions(+) create mode 100644 supplier/config/mda.json create mode 100644 supplier/config/outtel.json create mode 100644 supplier/config/pear.json create mode 100644 supplier/config/sumsang.json create mode 100644 supplier/config/techdealer.json diff --git a/supplier/config/mda.json b/supplier/config/mda.json new file mode 100644 index 0000000..de2d9f6 --- /dev/null +++ b/supplier/config/mda.json @@ -0,0 +1,50 @@ +{ + "id" : "mda", + "name" : "MDA", + "discount" : { + "minimumDailySalesVolumeNetCent": 20, + "percentDiscount": 3 + }, + "articles": [ + { + "title": "MDA Nezyr 7", + "manufacturer": "MDA", + "articleNumber": "n7", + "vatPercent": 19, + "pricePerUnitNet": 29990, + "shouldBeAdvertised": true + }, + { + "title": "MDA Nezyr 5", + "manufacturer": "MDA", + "articleNumber": "n5", + "vatPercent": 19, + "pricePerUnitNet": 19700, + "shouldBeAdvertised": true + }, + { + "title": "MDA Nezyr 3", + "manufacturer": "MDA", + "articleNumber": "n3", + "vatPercent": 19, + "pricePerUnitNet": 8990, + "shouldBeAdvertised": false + }, + { + "title": "MDA Nezyr Threadcracker 3990", + "manufacturer": "MDA", + "articleNumber": "ntc3990", + "vatPercent": 19, + "pricePerUnitNet": 404900, + "shouldBeAdvertised": true + }, + { + "title": "MDA Radon RX 5700", + "manufacturer": "MDA", + "articleNumber": "rrx5700", + "vatPercent": 19, + "pricePerUnitNet": 43624, + "shouldBeAdvertised": true + } + ] +} \ No newline at end of file diff --git a/supplier/config/outtel.json b/supplier/config/outtel.json new file mode 100644 index 0000000..10c14b7 --- /dev/null +++ b/supplier/config/outtel.json @@ -0,0 +1,42 @@ +{ + "id" : "outtel", + "name" : "Outtel", + "discount" : { + "minimumDailySalesVolumeNetCent": 20, + "percentDiscount": 1 + }, + "articles": [ + { + "title": "Outtel Core o7", + "manufacturer": "Outtel", + "articleNumber": "o7", + "vatPercent": 19, + "pricePerUnitNet": 40000, + "shouldBeAdvertised": true + }, + { + "title": "Outtel Core o5", + "manufacturer": "Outtel", + "articleNumber": "o5", + "vatPercent": 19, + "pricePerUnitNet": 25000, + "shouldBeAdvertised": true + }, + { + "title": "Outtel Core o3", + "manufacturer": "Outtel", + "articleNumber": "o3", + "vatPercent": 7, + "pricePerUnitNet": 8000, + "shouldBeAdvertised": false + }, + { + "title": "Outtel Core o9", + "manufacturer": "Outtel", + "articleNumber": "o9", + "vatPercent": 19, + "pricePerUnitNet": 55000, + "shouldBeAdvertised": true + } + ] +} \ No newline at end of file diff --git a/supplier/config/pear.json b/supplier/config/pear.json new file mode 100644 index 0000000..f0f3dfe --- /dev/null +++ b/supplier/config/pear.json @@ -0,0 +1,50 @@ +{ + "id" : "pear", + "name" : "Pear", + "discount" : { + "minimumDailySalesVolumeNetCent": 100, + "percentDiscount": 2 + }, + "articles": [ + { + "title": "Pear iMobile 10", + "manufacturer": "Pear", + "articleNumber": "iM10", + "vatPercent": 19, + "pricePerUnitNet": 31500, + "shouldBeAdvertised": true + }, + { + "title": "Pear iPlate Plus", + "manufacturer": "Pear", + "articleNumber": "ipp", + "vatPercent": 19, + "pricePerUnitNet": 44900, + "shouldBeAdvertised": true + }, + { + "title": "Pear iDonalds 9", + "manufacturer": "Pear", + "articleNumber": "id9", + "vatPercent": 19, + "pricePerUnitNet": 234800, + "shouldBeAdvertised": true + }, + { + "title": "Pear GroundPods", + "manufacturer": "Pear", + "articleNumber": "gp", + "vatPercent": 7, + "pricePerUnitNet": 13599, + "shouldBeAdvertised": true + }, + { + "title": "Pear Donalsbook Pro", + "manufacturer": "Pear", + "articleNumber": "dbp", + "vatPercent": 7, + "pricePerUnitNet": 145900, + "shouldBeAdvertised": true + } + ] +} \ No newline at end of file diff --git a/supplier/config/sumsang.json b/supplier/config/sumsang.json new file mode 100644 index 0000000..0b024ae --- /dev/null +++ b/supplier/config/sumsang.json @@ -0,0 +1,42 @@ +{ + "id" : "sumsang", + "name" : "Sumsang", + "discount" : { + "minimumDailySalesVolumeNetCent": 300, + "percentDiscount": 2 + }, + "articles": [ + { + "title": "Sumsang Universe S10", + "manufacturer": "Sumsang", + "articleNumber": "us10", + "vatPercent": 19, + "pricePerUnitNet": 59000, + "shouldBeAdvertised": true + }, + { + "title": "Sumsang Universe S10e", + "manufacturer": "Sumsang", + "articleNumber": "us10e", + "vatPercent": 19, + "pricePerUnitNet": 70231, + "shouldBeAdvertised": false + }, + { + "title": "Sumsang DumbTV", + "manufacturer": "Sumsang", + "articleNumber": "dtv", + "vatPercent": 19, + "pricePerUnitNet": 38395, + "shouldBeAdvertised": true + }, + { + "title": "Sumsang UniverseWatch", + "manufacturer": "Sumsang", + "articleNumber": "uw", + "vatPercent": 19, + "pricePerUnitNet": 20494, + "shouldBeAdvertised": true + } + ] +} \ No newline at end of file diff --git a/supplier/config/techdealer.json b/supplier/config/techdealer.json new file mode 100644 index 0000000..ea00422 --- /dev/null +++ b/supplier/config/techdealer.json @@ -0,0 +1,58 @@ +{ + "id" : "techdealer", + "name" : "Tech Dealer", + "discount" : { + "minimumDailySalesVolumeNetCent": 100, + "percentDiscount": 2 + }, + "articles": [ + { + "title": "TROPIC Gehäuselüfter", + "manufacturer": "TROPIC", + "articleNumber": "tgl", + "vatPercent": 19, + "pricePerUnitNet": 459, + "shouldBeAdvertised": true + }, + { + "title": "Pirate PC-Netzteil", + "manufacturer": "Pirate", + "articleNumber": "ppcn", + "vatPercent": 19, + "pricePerUnitNet": 9355, + "shouldBeAdvertised": true + }, + { + "title": "Pirate Void Elite RGB Wireless Gaming Headset", + "manufacturer": "Pirate", + "articleNumber": "pvergbwgh", + "vatPercent": 7, + "pricePerUnitNet": 10999, + "shouldBeAdvertised": false + }, + { + "title": "Aeroheat CYLON PC-Gehäuse", + "manufacturer": "Aeroheat", + "articleNumber": "acpcg", + "vatPercent": 19, + "pricePerUnitNet": 3999, + "shouldBeAdvertised": true + }, + { + "title": "Illogitech C270 Webcam", + "manufacturer": "Illogitech", + "articleNumber": "ic270w", + "vatPercent": 19, + "pricePerUnitNet": 3499, + "shouldBeAdvertised": true + }, + { + "title": "Illogitech Z607 Surround Sound Lautsprecher", + "manufacturer": "Illogitech", + "articleNumber": "iz607ssl", + "vatPercent": 19, + "pricePerUnitNet": 9495, + "shouldBeAdvertised": false + } + ] +} \ No newline at end of file From 87bade71b4e0c0dd53656131400986b65cc67cce Mon Sep 17 00:00:00 2001 From: Hannes Huber Date: Mon, 15 Jun 2020 10:20:40 +0200 Subject: [PATCH 07/25] =?UTF-8?q?Dateien=20hochladen=20nach=20=E2=80=9Esup?= =?UTF-8?q?plier/config=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- supplier/config/nanosoft.json | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 supplier/config/nanosoft.json diff --git a/supplier/config/nanosoft.json b/supplier/config/nanosoft.json new file mode 100644 index 0000000..4d978b7 --- /dev/null +++ b/supplier/config/nanosoft.json @@ -0,0 +1,34 @@ +{ + "id" : "nanosoft", + "name" : "Nanosoft", + "discount" : { + "minimumDailySalesVolumeNetCent": 50, + "percentDiscount": 0.5 + }, + "articles": [ + { + "title": "Nanosoft Doors 10", + "manufacturer": "Nanosoft", + "articleNumber": "d10", + "vatPercent": 7, + "pricePerUnitNet": 2099, + "shouldBeAdvertised": true + }, + { + "title": "Nanosoft Interior Pro 7", + "manufacturer": "Nanosoft", + "articleNumber": "ip7", + "vatPercent": 19, + "pricePerUnitNet": 90780, + "shouldBeAdvertised": false + }, + { + "title": "Nanosoft Ybox Two", + "manufacturer": "Nanosoft", + "articleNumber": "ybox2", + "vatPercent": 19, + "pricePerUnitNet": 23500, + "shouldBeAdvertised": true + } + ] +} \ No newline at end of file From 709c80fa37a7ccbf4c6df70328633ad8166563b1 Mon Sep 17 00:00:00 2001 From: localhorst Date: Mon, 15 Jun 2020 10:43:16 +0200 Subject: [PATCH 08/25] add fist admin user after start --- .../components/AdminInitializer.java | 37 +++++++++++++++++++ .../ecommerce/components/SlotInitializer.java | 32 ++++++++-------- .../ecommerce/repos/user/UserRepository.java | 8 ++++ 3 files changed, 60 insertions(+), 17 deletions(-) create mode 100644 prototype/src/main/java/org/hso/ecommerce/components/AdminInitializer.java diff --git a/prototype/src/main/java/org/hso/ecommerce/components/AdminInitializer.java b/prototype/src/main/java/org/hso/ecommerce/components/AdminInitializer.java new file mode 100644 index 0000000..7b473c0 --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/components/AdminInitializer.java @@ -0,0 +1,37 @@ +package org.hso.ecommerce.components; + +import org.hso.ecommerce.entities.booking.PaymentMethod; +import org.hso.ecommerce.entities.user.User; +import org.hso.ecommerce.repos.user.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.sql.Timestamp; +import java.util.Optional; + +import javax.annotation.PostConstruct; + +@Component +public class AdminInitializer { + + @Autowired + private final UserRepository userRepository = null; + + @PostConstruct + public void init() { + Optional numberOfEmployees = userRepository.numberOfEmployees(); + if (numberOfEmployees.orElse(0) == 0) { + // create first admin user + User firstAdmin = new User(); + firstAdmin.created = new Timestamp(System.currentTimeMillis()); + firstAdmin.name = "admin"; + firstAdmin.defaultPayment = new PaymentMethod(); + firstAdmin.defaultPayment.creditCardNumber = ""; //set empty number + firstAdmin.email = "admin"; + firstAdmin.isActive = true; + firstAdmin.isEmployee = true; + firstAdmin.setPassword("admin"); + userRepository.save(firstAdmin); //save to DB + } + } +} diff --git a/prototype/src/main/java/org/hso/ecommerce/components/SlotInitializer.java b/prototype/src/main/java/org/hso/ecommerce/components/SlotInitializer.java index ce8c39b..72c4f8a 100644 --- a/prototype/src/main/java/org/hso/ecommerce/components/SlotInitializer.java +++ b/prototype/src/main/java/org/hso/ecommerce/components/SlotInitializer.java @@ -10,23 +10,21 @@ import javax.annotation.PostConstruct; @Component public class SlotInitializer { - @Autowired - private final SlotRepository slotRepository = null; + @Autowired + private final SlotRepository slotRepository = null; - // TODO: use values form cfg. - private final int NUM_SLOTS = 50; - - @PostConstruct - public void init() { - for (int i = 1; i <= NUM_SLOTS; i++) { - if (!slotRepository.findBySlotNum(i).isPresent()) { - Slot slotAdded = new Slot(); - slotAdded.slotNum = i; - slotRepository.save(slotAdded); - - System.out.println("Added Slot " + i + " to DB"); - } - } - } + // TODO: use values form cfg. + private final int NUM_SLOTS = 50; + @PostConstruct + public void init() { + for (int i = 1; i <= NUM_SLOTS; i++) { + if (!slotRepository.findBySlotNum(i).isPresent()) { + Slot slotAdded = new Slot(); + slotAdded.slotNum = i; + slotRepository.save(slotAdded); + System.out.println("Added Slot " + i + " to DB"); + } + } + } } diff --git a/prototype/src/main/java/org/hso/ecommerce/repos/user/UserRepository.java b/prototype/src/main/java/org/hso/ecommerce/repos/user/UserRepository.java index 9477763..abfbc9e 100644 --- a/prototype/src/main/java/org/hso/ecommerce/repos/user/UserRepository.java +++ b/prototype/src/main/java/org/hso/ecommerce/repos/user/UserRepository.java @@ -12,7 +12,15 @@ public interface UserRepository extends JpaRepository { @Query("SELECT c FROM User c WHERE c.email = :email") Optional findByEmail(String email); + + /*SELECT count(*) FROM users WHERE is_employee == 1; + */ + + @Query("SELECT count(*) FROM User WHERE isEmployee = true") + Optional numberOfEmployees(); + + } From 18f35c43e7674d72d18ac2ed9ef1b0139ab59004 Mon Sep 17 00:00:00 2001 From: localhorst Date: Mon, 15 Jun 2020 10:46:04 +0200 Subject: [PATCH 09/25] remove spaces --- .../hso/ecommerce/repos/user/UserRepository.java | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/prototype/src/main/java/org/hso/ecommerce/repos/user/UserRepository.java b/prototype/src/main/java/org/hso/ecommerce/repos/user/UserRepository.java index abfbc9e..c48b9af 100644 --- a/prototype/src/main/java/org/hso/ecommerce/repos/user/UserRepository.java +++ b/prototype/src/main/java/org/hso/ecommerce/repos/user/UserRepository.java @@ -10,17 +10,9 @@ import java.util.Optional; @Repository public interface UserRepository extends JpaRepository { - @Query("SELECT c FROM User c WHERE c.email = :email") - Optional findByEmail(String email); - - /*SELECT count(*) FROM users WHERE is_employee == 1; - */ + @Query("SELECT c FROM User c WHERE c.email = :email") + Optional findByEmail(String email); - - @Query("SELECT count(*) FROM User WHERE isEmployee = true") - Optional numberOfEmployees(); - - + @Query("SELECT count(*) FROM User WHERE isEmployee = true") + Optional numberOfEmployees(); } - - From 3b364ae81568529ffe86ba549be091b7ba95a25d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20F=C3=BCrderer?= Date: Mon, 15 Jun 2020 16:23:42 +0200 Subject: [PATCH 10/25] Allow employees to trigger cronjobs manually --- .../controller/cronjob/CronjobController.java | 57 ++++++++++++++++++ .../resources/static/css/manual-cronjobs.css | 35 +++++++++++ .../resources/templates/fragments/intern.html | 2 + .../templates/intern/cronjobs/index.html | 60 +++++++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 prototype/src/main/resources/static/css/manual-cronjobs.css create mode 100644 prototype/src/main/resources/templates/intern/cronjobs/index.html diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/CronjobController.java b/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/CronjobController.java index 0f54221..dbf7c6c 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/CronjobController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/CronjobController.java @@ -1,6 +1,7 @@ package org.hso.ecommerce.controller.cronjob; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.GregorianCalendar; @@ -37,6 +38,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +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.RequestMapping; interface ICronjob { /** @@ -63,10 +69,22 @@ interface ICronjob { * @param controller Back-reference that allows to use repositories. */ void executeAt(Calendar time, CronjobController controller); + + /** + * Get a name for this cronjob, that can be presented to the user in the frontend. + * + * @return A german name of this cronjob. + */ + String getDisplayName(); } @Component class Reorder implements ICronjob { + @Override + public String getDisplayName() { + return "Nachbestellung"; + } + @Override public Calendar nextExecution(Calendar reference) { if (reference.get(Calendar.HOUR_OF_DAY) >= 8) { @@ -215,6 +233,7 @@ class ScheduledCronjob { } @Component +@RequestMapping("intern/cronjobs") class CronjobController { private static final Logger log = LoggerFactory.getLogger(CronjobController.class); @@ -328,4 +347,42 @@ class CronjobController { public void onPostConstruct() { new Thread(this::runCronjobExecutionLoop).start(); } + + class ManualCronjob { + public final String identifier; + public final String visibleName; + + public ManualCronjob(String identifier, String visibleName) { + this.identifier = identifier; + this.visibleName = visibleName; + } + } + + private List listAllCronjobs() { + ArrayList entries = new ArrayList<>(); + for (Entry job : cronjobs.entrySet()) { + entries.add(new ManualCronjob(job.getKey(), job.getValue().getDisplayName())); + } + return entries; + } + + @GetMapping("/") + public String cronjobOverview(Model model) { + model.addAttribute("jobs", listAllCronjobs()); + return "intern/cronjobs/index"; + } + + @PostMapping("/run/{identifier}") + public String runCronjob(Model model, @PathVariable("identifier") String identifier) { + ICronjob jobToExecute = cronjobs.get(identifier); + if (jobToExecute != null) { + jobToExecute.executeAt(new GregorianCalendar(), this); + model.addAttribute("info", + String.format("Der Cronjob \"%s\" wurde ausgeführt.", jobToExecute.getDisplayName())); + } else { + model.addAttribute("error", "Der Cronjob konnte nicht gefunden werden."); + } + model.addAttribute("jobs", listAllCronjobs()); + return "intern/cronjobs/index"; + } } diff --git a/prototype/src/main/resources/static/css/manual-cronjobs.css b/prototype/src/main/resources/static/css/manual-cronjobs.css new file mode 100644 index 0000000..19205d5 --- /dev/null +++ b/prototype/src/main/resources/static/css/manual-cronjobs.css @@ -0,0 +1,35 @@ +.alert { + display: block; + text-transform: uppercase; + background: #c0392b; + color: white; + animation: blinking 1s linear infinite; + overflow: hidden; +} + +.alert > span { + display: inline-block; + padding-left: 100%; + animation: marquee 10s linear infinite; + white-space: nowrap; +} + +@keyframes marquee { + 0% { transform: translateX(0); } + 100% { transform: translateX(-100%); } +} + +@keyframes blinking { + 60% { + color: white; + } + 75% { + color: #c0392b; + } + 85% { + color: #c0392b; + } + 100% { + color: white; + } +} diff --git a/prototype/src/main/resources/templates/fragments/intern.html b/prototype/src/main/resources/templates/fragments/intern.html index 22de534..eee1c8d 100644 --- a/prototype/src/main/resources/templates/fragments/intern.html +++ b/prototype/src/main/resources/templates/fragments/intern.html @@ -47,6 +47,8 @@ +
  • Cronjobs
  • + diff --git a/prototype/src/main/resources/templates/intern/cronjobs/index.html b/prototype/src/main/resources/templates/intern/cronjobs/index.html new file mode 100644 index 0000000..ef7e681 --- /dev/null +++ b/prototype/src/main/resources/templates/intern/cronjobs/index.html @@ -0,0 +1,60 @@ + + + + + + + + Cronjobs + + + + + + + + +
    + +
    +

    Manuelle Ausführung von Cronjobs

    +
    + WARNUNG
    + Manuelles Triggern von Cronjobs kann zu unerwartetem Verhalten führen!
    + Diese Seite ist nur für Debugging-Zwecke gedacht. +
    + +

    +

    + + + + + + + + + + + +
    + +
    Cronjob
    +
    + +
    +
    +

    + +
    +

    +
    + + + From 3b1d3789684acabc77f73415c2f156d7321e4c57 Mon Sep 17 00:00:00 2001 From: CodeSteak Date: Tue, 16 Jun 2020 23:38:35 +0200 Subject: [PATCH 11/25] Fix not creating directory when uploading file --- .../controller/intern/InternArticleController.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/InternArticleController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/InternArticleController.java index e799210..38b2222 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/intern/InternArticleController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/InternArticleController.java @@ -22,6 +22,7 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; @@ -171,15 +172,22 @@ public class InternArticleController { if (imageID.isPresent()) { article.image = imageRepository.findImageById(imageID.get()); // add existing img to article } else { + + Path targetPath = Paths.get("./data/img/"); + if (Files.notExists(targetPath)) { + Files.createDirectories(targetPath); + } + // write new img file to disk - Files.newOutputStream(Paths.get("./data/img/", fileName)).write(imgFile.getBytes()); + Files.newOutputStream(Paths.get(targetPath.toString(), fileName)).write(imgFile.getBytes()); // create new img Image newImage = new Image(); newImage.path = "./data/img/" + fileName; // set new file to new img imageRepository.save(newImage); // save new img article.image = newImage; // set new img to article } - } catch (Exception e) { + } catch (IOException e) { + e.printStackTrace(); setDefaultImage(article); // if upload failed, reset to default img } } From 486f23713576d4d12b092deda8de0919c0c03ab0 Mon Sep 17 00:00:00 2001 From: CodeSteak Date: Tue, 16 Jun 2020 23:50:10 +0200 Subject: [PATCH 12/25] fix creditcard num not being set leading to crash --- prototype/src/main/resources/templates/user/settings.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/prototype/src/main/resources/templates/user/settings.html b/prototype/src/main/resources/templates/user/settings.html index 80bd60e..3e71125 100644 --- a/prototype/src/main/resources/templates/user/settings.html +++ b/prototype/src/main/resources/templates/user/settings.html @@ -91,7 +91,11 @@
    - +
    From 18cbfbf148ad3467b7855b1a0ad035c327bd168c Mon Sep 17 00:00:00 2001 From: CodeSteak Date: Wed, 17 Jun 2020 00:02:46 +0200 Subject: [PATCH 13/25] Fix template strings with a starting "/" --- .../intern/customers/CustomersIndexController.java | 13 +++++-------- .../controller/shop/ShopSearchController.java | 6 ++++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/customers/CustomersIndexController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/customers/CustomersIndexController.java index 3432770..b8fa7cf 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/intern/customers/CustomersIndexController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/customers/CustomersIndexController.java @@ -1,9 +1,5 @@ package org.hso.ecommerce.controller.intern.customers; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; - import org.hso.ecommerce.controller.intern.accounting.AccountingController; import org.hso.ecommerce.controller.intern.accounting.AccountingController.ShortTemplateBookingResult; import org.hso.ecommerce.entities.booking.Booking; @@ -13,12 +9,13 @@ import org.hso.ecommerce.repos.booking.BookingRepository; import org.hso.ecommerce.repos.shop.CustomerOrderRepository; import org.hso.ecommerce.repos.user.UserRepository; import org.springframework.beans.factory.annotation.Autowired; - import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.util.List; import java.util.Optional; @Controller @@ -104,17 +101,17 @@ public class CustomersIndexController { ) { if (!password.equals(password2)) { request.setAttribute("error", "Passwörter stimmen nicht überein!"); - return "/intern/customers/id"; + return "intern/customers/id"; } User user = userRepository.findById(id).get(); if (!user.validatePassword(password)) { request.setAttribute("error", "Die Passwörter stimmen nicht mit dem Original überein!"); - return "/intern/customers/id"; + return "intern/customers/id"; } user.setPassword("12345"); userRepository.save(user); request.setAttribute("info", "Passwort wurde auf 12345 geändert!"); - return "/intern/customers/id"; + return "intern/customers/id"; } } diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopSearchController.java b/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopSearchController.java index 47b8acf..8e8980c 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopSearchController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopSearchController.java @@ -7,7 +7,9 @@ import org.hso.ecommerce.repos.shop.CategoryRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -45,6 +47,6 @@ public class ShopSearchController { return "error/404"; } - return "/shop/search"; + return "shop/search"; } } \ No newline at end of file From 44df9e4b4ff9bed33d0c0fd9be555dabaf66ed41 Mon Sep 17 00:00:00 2001 From: CodeSteak Date: Wed, 17 Jun 2020 00:11:55 +0200 Subject: [PATCH 14/25] Secretly add Favicon --- prototype/src/main/resources/static/favicon.ico | Bin 0 -> 3471 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 prototype/src/main/resources/static/favicon.ico diff --git a/prototype/src/main/resources/static/favicon.ico b/prototype/src/main/resources/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..327529b6a5ca1d8d5cdac7b9da3ae8f54bf77fda GIT binary patch literal 3471 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 Date: Wed, 17 Jun 2020 00:17:50 +0200 Subject: [PATCH 15/25] Secretly fix searchbar not showing term when searching --- .../hso/ecommerce/controller/shop/ShopSearchController.java | 3 +++ prototype/src/main/resources/templates/fragments/header.html | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopSearchController.java b/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopSearchController.java index 8e8980c..53d03fb 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopSearchController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopSearchController.java @@ -47,6 +47,9 @@ public class ShopSearchController { return "error/404"; } + // Show term in search box + model.addAttribute("searchterm", term != null ? term : ""); + return "shop/search"; } } \ No newline at end of file diff --git a/prototype/src/main/resources/templates/fragments/header.html b/prototype/src/main/resources/templates/fragments/header.html index 349f72c..9984032 100644 --- a/prototype/src/main/resources/templates/fragments/header.html +++ b/prototype/src/main/resources/templates/fragments/header.html @@ -11,7 +11,8 @@
    - +
    Login From e6c068e71a25a99d155fde4950ce2734c93fd3b6 Mon Sep 17 00:00:00 2001 From: CodeSteak Date: Wed, 17 Jun 2020 00:23:05 +0200 Subject: [PATCH 16/25] Secretly fix number 0 showing on 'Warenkorb' --- prototype/src/main/resources/templates/fragments/header.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/prototype/src/main/resources/templates/fragments/header.html b/prototype/src/main/resources/templates/fragments/header.html index 9984032..1b0b75c 100644 --- a/prototype/src/main/resources/templates/fragments/header.html +++ b/prototype/src/main/resources/templates/fragments/header.html @@ -26,7 +26,10 @@
    - Warenkorb () + Warenkorb + () + +
    From 2442a477c8c7bf206a4db99a5c7eebab5b8c7177 Mon Sep 17 00:00:00 2001 From: Seil0 Date: Wed, 17 Jun 2020 18:43:06 +0200 Subject: [PATCH 17/25] add missing "|" --- prototype/src/main/resources/templates/intern/customers/id.html | 2 +- prototype/src/main/resources/templates/user/orders/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/prototype/src/main/resources/templates/intern/customers/id.html b/prototype/src/main/resources/templates/intern/customers/id.html index 30962fc..57263dc 100644 --- a/prototype/src/main/resources/templates/intern/customers/id.html +++ b/prototype/src/main/resources/templates/intern/customers/id.html @@ -23,7 +23,7 @@