diff --git a/00-backend/README.md b/00-backend/README.md
index 1adf6d8..bf577ba 100644
--- a/00-backend/README.md
+++ b/00-backend/README.md
@@ -22,6 +22,12 @@
```shell
mvn clean package
```
+
+## Interesting Knowledge
+- `controller/` includes all REST-Endpoints
+- `model/` includes all REST-Responses
+- `service/` includes all Business Logic
+- `repository/entities` includes all DB-Objects
# Contributors
- Laura Katharina Dolibois
diff --git a/00-backend/pom.xml b/00-backend/pom.xml
index 1acb389..357de3e 100644
--- a/00-backend/pom.xml
+++ b/00-backend/pom.xml
@@ -58,6 +58,11 @@
spring-boot-starter-validation3.4.1
+
+ org.springframework.security
+ spring-security-crypto
+ 6.4.4
+ org.xerialsqlite-jdbc
diff --git a/00-backend/src/main/java/de/htwsaar/webshop/config/ControllerPathConfig.java b/00-backend/src/main/java/de/htwsaar/webshop/config/ControllerPathConfig.java
index 9fd86de..5e8b9e4 100644
--- a/00-backend/src/main/java/de/htwsaar/webshop/config/ControllerPathConfig.java
+++ b/00-backend/src/main/java/de/htwsaar/webshop/config/ControllerPathConfig.java
@@ -15,4 +15,9 @@ public class ControllerPathConfig {
//ImageController
public static final String IMAGE_BASE = "/image";
public static final String IMAGE_GET_ALL = IMAGE_BASE + "/all";
+
+ //AccountController
+ public static final String ACCOUNT_BASE = "/account";
+ public static final String EMAIL_BASE = "/email";
+
}
\ No newline at end of file
diff --git a/00-backend/src/main/java/de/htwsaar/webshop/config/ParameterConfig.java b/00-backend/src/main/java/de/htwsaar/webshop/config/ParameterConfig.java
index 62836f3..ce6c394 100644
--- a/00-backend/src/main/java/de/htwsaar/webshop/config/ParameterConfig.java
+++ b/00-backend/src/main/java/de/htwsaar/webshop/config/ParameterConfig.java
@@ -7,5 +7,6 @@ public class ParameterConfig {
public static final String PARAM_UUID = "uuid";
public static final String PARAM_ARTICLE_ID = "articleId";
public static final String PARAM_IMAGE_ID = "imageId";
+ public static final String PARAM_EMAIL = "email";
}
diff --git a/00-backend/src/main/java/de/htwsaar/webshop/controller/AccountController.java b/00-backend/src/main/java/de/htwsaar/webshop/controller/AccountController.java
new file mode 100644
index 0000000..dce295e
--- /dev/null
+++ b/00-backend/src/main/java/de/htwsaar/webshop/controller/AccountController.java
@@ -0,0 +1,74 @@
+package de.htwsaar.webshop.controller;
+
+import de.htwsaar.webshop.repository.entities.Account;
+import de.htwsaar.webshop.service.AccountService;
+import de.htwsaar.webshop.service.ValidatorService;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import static de.htwsaar.webshop.config.ControllerPathConfig.ACCOUNT_BASE;
+import static de.htwsaar.webshop.config.ControllerPathConfig.EMAIL_BASE;
+import static de.htwsaar.webshop.config.ParameterConfig.PARAM_EMAIL;
+import static de.htwsaar.webshop.util.LoggerUtil.logRequest;
+
+@RestController
+@Slf4j
+public class AccountController {
+
+ private final AccountService accountService;
+ private final ValidatorService validatorService;
+
+ @Autowired
+ public AccountController(AccountService accountService, ValidatorService validatorService) {
+ this.accountService = accountService;
+ this.validatorService = validatorService;
+ }
+
+ @RequestMapping(path = EMAIL_BASE, method = RequestMethod.GET, produces = "application/json")
+ public ResponseEntity isEmailValid(HttpServletRequest request,
+ @RequestParam(PARAM_EMAIL) String email) {
+ logRequest(request);
+ return accountService.existsWithEmail(email) ?
+ ResponseEntity.ok(true) :
+ ResponseEntity.notFound().build();
+ }
+
+ @RequestMapping(path = ACCOUNT_BASE, method = RequestMethod.POST, produces = "application/json")
+ public ResponseEntity createAccount(HttpServletRequest request,
+ @RequestBody Account account) {
+ logRequest(request);
+ if (validatorService.isInvalid(account)) {
+ log.warn("[{}] failed Validation, sending bad request", request.getRequestURI());
+ return ResponseEntity.badRequest().build();
+ }
+ if(accountService.existsWithEmail(account.getEmail())) {
+ log.warn("[{}] Account cant be created, Email is already in use", request.getRequestURI());
+ return ResponseEntity.unprocessableEntity().build();
+ }
+ if(accountService.saveNew(account).getId() == null) {
+ return ResponseEntity.internalServerError().build();
+ }
+ return ResponseEntity.ok().build();
+ }
+
+ @RequestMapping(path = ACCOUNT_BASE, method = RequestMethod.DELETE, produces = "application/json")
+ public ResponseEntity deleteAccount(HttpServletRequest request,
+ @RequestBody Account account) {
+ logRequest(request);
+ if (validatorService.isInvalid(account)) {
+ log.warn("[{}] failed Validation, sending bad request", request.getRequestURI());
+ return ResponseEntity.badRequest().build();
+ }
+ if(accountService.existsWithEmail(account.getEmail())) {
+ return ResponseEntity.badRequest().build();
+ }
+ if(!accountService.deleteIfExists(account)) {
+ return ResponseEntity.badRequest().build();
+ }
+ return ResponseEntity.ok().build();
+ }
+
+}
diff --git a/00-backend/src/main/java/de/htwsaar/webshop/repository/AccountRepository.java b/00-backend/src/main/java/de/htwsaar/webshop/repository/AccountRepository.java
index 65109d4..8dedd67 100644
--- a/00-backend/src/main/java/de/htwsaar/webshop/repository/AccountRepository.java
+++ b/00-backend/src/main/java/de/htwsaar/webshop/repository/AccountRepository.java
@@ -6,5 +6,7 @@ import org.springframework.stereotype.Repository;
@Repository
public interface AccountRepository extends JpaRepository {
+ Account getAccountByEmail(String email);
+ boolean existsAccountByEmail(String email);
}
diff --git a/00-backend/src/main/java/de/htwsaar/webshop/service/AccountService.java b/00-backend/src/main/java/de/htwsaar/webshop/service/AccountService.java
new file mode 100644
index 0000000..5e4b700
--- /dev/null
+++ b/00-backend/src/main/java/de/htwsaar/webshop/service/AccountService.java
@@ -0,0 +1,12 @@
+package de.htwsaar.webshop.service;
+
+import de.htwsaar.webshop.repository.entities.Account;
+
+public interface AccountService {
+ Account saveNew(Account account);
+ Account save(Account account);
+ boolean deleteIfExists(Account account);
+ Account getAccountByEmail(String email);
+ boolean isValidLogin(String email, String password);
+ boolean existsWithEmail(String email);
+}
\ No newline at end of file
diff --git a/00-backend/src/main/java/de/htwsaar/webshop/service/PasswordService.java b/00-backend/src/main/java/de/htwsaar/webshop/service/PasswordService.java
new file mode 100644
index 0000000..5dbc1e0
--- /dev/null
+++ b/00-backend/src/main/java/de/htwsaar/webshop/service/PasswordService.java
@@ -0,0 +1,6 @@
+package de.htwsaar.webshop.service;
+
+public interface PasswordService {
+ String hashPassword(String password);
+ boolean verifyPassword(String password, String hashedPassword);
+}
\ No newline at end of file
diff --git a/00-backend/src/main/java/de/htwsaar/webshop/service/impl/AccountServiceImpl.java b/00-backend/src/main/java/de/htwsaar/webshop/service/impl/AccountServiceImpl.java
new file mode 100644
index 0000000..9ab6e97
--- /dev/null
+++ b/00-backend/src/main/java/de/htwsaar/webshop/service/impl/AccountServiceImpl.java
@@ -0,0 +1,60 @@
+package de.htwsaar.webshop.service.impl;
+
+import de.htwsaar.webshop.repository.AccountRepository;
+import de.htwsaar.webshop.repository.entities.Account;
+import de.htwsaar.webshop.service.AccountService;
+import de.htwsaar.webshop.service.PasswordService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AccountServiceImpl implements AccountService {
+ private final AccountRepository accountRepository;
+ private final PasswordService passwordService;
+
+ @Autowired
+ public AccountServiceImpl(AccountRepository accountRepository, PasswordService passwordService) {
+ this.accountRepository = accountRepository;
+ this.passwordService = passwordService;
+ }
+
+ @Override
+ public Account save(Account account) {
+ return accountRepository.save(account);
+ }
+
+ @Override
+ public Account saveNew(Account account) {
+ account.setPassword(passwordService.hashPassword(account.getPassword()));
+ return this.save(account);
+ }
+
+ @Override
+ public boolean deleteIfExists(Account account) {
+ Account tbd = accountRepository.getAccountByEmail(account.getEmail());
+ if(tbd == null) {
+ return false;
+ }
+ accountRepository.delete(tbd);
+ return true;
+ }
+
+ @Override
+ public Account getAccountByEmail(String email) {
+ return accountRepository.getAccountByEmail(email);
+ }
+
+ @Override
+ public boolean isValidLogin(String email, String password) {
+ Account acc = accountRepository.getAccountByEmail(email);
+ if(acc == null) {
+ return false;
+ }
+ return passwordService.verifyPassword(password, acc.getPassword());
+ }
+
+ @Override
+ public boolean existsWithEmail(String email) {
+ return accountRepository.existsAccountByEmail(email);
+ }
+}
diff --git a/00-backend/src/main/java/de/htwsaar/webshop/service/impl/PasswordServiceImpl.java b/00-backend/src/main/java/de/htwsaar/webshop/service/impl/PasswordServiceImpl.java
new file mode 100644
index 0000000..70e9de9
--- /dev/null
+++ b/00-backend/src/main/java/de/htwsaar/webshop/service/impl/PasswordServiceImpl.java
@@ -0,0 +1,33 @@
+package de.htwsaar.webshop.service.impl;
+
+import de.htwsaar.webshop.service.PasswordService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.crypto.bcrypt.BCrypt;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * Implementation of {@link PasswordService} responsible for creating the salt string.
+ *
+ * This service generates the salt.
+ *
+ */
+@Service
+@Slf4j
+public class PasswordServiceImpl implements PasswordService {
+ /**
+ * A way to generate Password aafterBCrypt Standard
+ * This is computationally expensive
+ *
+ * @return a non-deterministic Salt for BCrypt.
+ */
+ @Override
+ public String hashPassword(String password) {
+ return BCrypt.hashpw(password, BCrypt.gensalt(12));
+ }
+
+ @Override
+ public boolean verifyPassword(String password, String hashedPassword) {
+ return BCrypt.checkpw(password, hashedPassword);
+ }
+}
\ No newline at end of file