From 7ebd6a2587573f94331f924313e9170817192149 Mon Sep 17 00:00:00 2001 From: "Max W." <66736561+Walzen665@users.noreply.github.com> Date: Thu, 16 Jan 2025 23:24:42 +0100 Subject: [PATCH] zwischenstand --- build.gradle | 2 +- .../biblenotes/config/SecurityConfig.java | 1 + .../w665/biblenotes/db/RethinkDBService.java | 47 ++++--------------- .../java/de/w665/biblenotes/model/User.java | 2 + .../rest/AuthenticationController.java | 47 +++++++++++++++++++ .../rest/SecureApiRestController.java | 9 ++++ .../rest/ro/AuthenticationRequest.java | 15 ++++++ .../security/JwtAuthenticationFilter.java | 2 + .../service/AuthenticationService.java | 8 ++++ src/main/resources/application.properties | 13 +++++ 10 files changed, 106 insertions(+), 40 deletions(-) create mode 100644 src/main/java/de/w665/biblenotes/rest/AuthenticationController.java create mode 100644 src/main/java/de/w665/biblenotes/rest/SecureApiRestController.java create mode 100644 src/main/java/de/w665/biblenotes/rest/ro/AuthenticationRequest.java diff --git a/build.gradle b/build.gradle index 1898dc7..5ab377b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.3.3' + id 'org.springframework.boot' version '3.4.1' id 'io.spring.dependency-management' version '1.1.6' } diff --git a/src/main/java/de/w665/biblenotes/config/SecurityConfig.java b/src/main/java/de/w665/biblenotes/config/SecurityConfig.java index 04f9544..566efca 100644 --- a/src/main/java/de/w665/biblenotes/config/SecurityConfig.java +++ b/src/main/java/de/w665/biblenotes/config/SecurityConfig.java @@ -1,5 +1,6 @@ package de.w665.biblenotes.config; +import de.w665.biblenotes.rest.security.JwtAuthenticationFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.Customizer; diff --git a/src/main/java/de/w665/biblenotes/db/RethinkDBService.java b/src/main/java/de/w665/biblenotes/db/RethinkDBService.java index 67686fc..ab788a8 100644 --- a/src/main/java/de/w665/biblenotes/db/RethinkDBService.java +++ b/src/main/java/de/w665/biblenotes/db/RethinkDBService.java @@ -10,9 +10,14 @@ import jakarta.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.cglib.core.Local; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; import java.util.Optional; @Slf4j @@ -54,45 +59,6 @@ public class RethinkDBService { log.debug("Database " + config.getDatabase() + " already exists. Error: " + e.getClass().getSimpleName()); } - // rethinkdb check if table file_uploads exists - try { - r.db(config.getDatabase()).tableCreate("file_uploads").run(connection).stream(); - log.debug("Table 'file_uploads' created successfully."); - } catch (ReqlOpFailedError e) { - log.debug("Table 'file_uploads' already exists."); - if(autoResetOnStartup) { - log.debug("Clearing content..."); - r.db(config.getDatabase()).table("file_uploads").delete().run(connection); - log.debug("Table 'file_uploads' cleared successfully."); - } - } - - // rethinkdb check if table id_store exists - try { - r.db(config.getDatabase()).tableCreate("id_store").run(connection).stream(); - log.debug("Table 'id_store' created successfully."); - } catch (ReqlOpFailedError e) { - log.debug("Table 'id_store' already exists."); - if(autoResetOnStartup) { - log.debug("Clearing content..."); - r.db(config.getDatabase()).table("id_store").delete().run(connection); - log.debug("Table 'id_store' cleared successfully."); - } - } - - // rethinkdb check if table expired_file_uploads exists - try { - r.db(config.getDatabase()).tableCreate("expired_file_uploads").run(connection).stream(); - log.debug("Table 'expired_file_uploads' created successfully."); - } catch (ReqlOpFailedError e) { - log.debug("Table 'expired_file_uploads' already exists."); - if(autoResetOnStartup) { - log.debug("Clearing content..."); - r.db(config.getDatabase()).table("expired_file_uploads").delete().run(connection); - log.debug("Table 'expired_file_uploads' cleared successfully."); - } - } - // rethinkdb check if table users exists try { r.db(config.getDatabase()).tableCreate("users").run(connection).stream(); @@ -136,6 +102,9 @@ public class RethinkDBService { private void initializeAdminUser() { Optional adminUser = userRepository.retrieveUserByUsername("admin"); if(adminUser.isEmpty()) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss.SSSXXX"); + ZonedDateTime now = ZonedDateTime.now(); + User user = new User(); user.setUsername(defaultUsername); user.setPassword(passwordEncoder.encode(defaultPassword)); diff --git a/src/main/java/de/w665/biblenotes/model/User.java b/src/main/java/de/w665/biblenotes/model/User.java index 412dfd0..5613610 100644 --- a/src/main/java/de/w665/biblenotes/model/User.java +++ b/src/main/java/de/w665/biblenotes/model/User.java @@ -2,6 +2,8 @@ package de.w665.biblenotes.model; import lombok.*; +import java.time.LocalDateTime; + @Getter @Setter @ToString diff --git a/src/main/java/de/w665/biblenotes/rest/AuthenticationController.java b/src/main/java/de/w665/biblenotes/rest/AuthenticationController.java new file mode 100644 index 0000000..f9e518a --- /dev/null +++ b/src/main/java/de/w665/biblenotes/rest/AuthenticationController.java @@ -0,0 +1,47 @@ +package de.w665.biblenotes.rest; + +import de.w665.biblenotes.rest.ro.AuthenticationRequest; +import de.w665.biblenotes.service.AuthenticationService; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@RestController +@RequestMapping("/api/v1/auth") +public class AuthenticationController { + private final AuthenticationService authenticationService; + + public AuthenticationController(AuthenticationService authenticationService) { + this.authenticationService = authenticationService; + } + + @PostMapping("/login") + public ResponseEntity createAuthenticationToken(@RequestBody AuthenticationRequest authenticationRequest, HttpServletRequest request) { + log.debug("Received AuthenticationRequest for username: " + authenticationRequest.getUsername()); + String token = authenticationService.authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword(), request.getRemoteAddr()); + + if(token == null) { + log.debug("Authentication failed for username: " + authenticationRequest.getUsername()); + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } + + Map response = new HashMap<>(); + response.put("token", token); + + if(token == null) { + log.debug("Authentication failed for username: " + authenticationRequest.getUsername()); + return new ResponseEntity<>(response, HttpStatus.UNAUTHORIZED); + } + + return new ResponseEntity<>(response, HttpStatus.OK); + } +} diff --git a/src/main/java/de/w665/biblenotes/rest/SecureApiRestController.java b/src/main/java/de/w665/biblenotes/rest/SecureApiRestController.java new file mode 100644 index 0000000..6380970 --- /dev/null +++ b/src/main/java/de/w665/biblenotes/rest/SecureApiRestController.java @@ -0,0 +1,9 @@ +package de.w665.biblenotes.rest; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1/secure") +public abstract class SecureApiRestController { +} diff --git a/src/main/java/de/w665/biblenotes/rest/ro/AuthenticationRequest.java b/src/main/java/de/w665/biblenotes/rest/ro/AuthenticationRequest.java new file mode 100644 index 0000000..312d9f5 --- /dev/null +++ b/src/main/java/de/w665/biblenotes/rest/ro/AuthenticationRequest.java @@ -0,0 +1,15 @@ +package de.w665.biblenotes.rest.ro; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@NoArgsConstructor +@Getter +@Setter +@ToString +public class AuthenticationRequest { + private String username; + private String password; +} diff --git a/src/main/java/de/w665/biblenotes/rest/security/JwtAuthenticationFilter.java b/src/main/java/de/w665/biblenotes/rest/security/JwtAuthenticationFilter.java index a46d6b5..d36c2a4 100644 --- a/src/main/java/de/w665/biblenotes/rest/security/JwtAuthenticationFilter.java +++ b/src/main/java/de/w665/biblenotes/rest/security/JwtAuthenticationFilter.java @@ -1,11 +1,13 @@ package de.w665.biblenotes.rest.security; +import de.w665.biblenotes.service.AuthenticationService; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; diff --git a/src/main/java/de/w665/biblenotes/service/AuthenticationService.java b/src/main/java/de/w665/biblenotes/service/AuthenticationService.java index f90e127..a42d960 100644 --- a/src/main/java/de/w665/biblenotes/service/AuthenticationService.java +++ b/src/main/java/de/w665/biblenotes/service/AuthenticationService.java @@ -1,5 +1,13 @@ package de.w665.biblenotes.service; +import de.w665.biblenotes.db.repo.UserLoginRepository; +import de.w665.biblenotes.db.repo.UserRepository; +import de.w665.biblenotes.model.User; +import de.w665.biblenotes.model.UserLogin; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwt; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e541221..958f992 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,14 @@ spring.application.name=biblenotes +server.port=665 + +biblenotes.auto-reset-on-startup=true +biblenotes.management.user.username=admin +biblenotes.management.user.password=admin + +rethinkdb.host=localhost +rethinkdb.port=28015 +rethinkdb.database=biblenotes + +secureapi.jwt.secret=someSecretChangeMeInProduction +secureapi.jwt.expiration=86400000 +