zwischenstand

This commit is contained in:
Max W. 2025-01-16 23:24:42 +01:00
parent 4e75e25d62
commit 7ebd6a2587
10 changed files with 106 additions and 40 deletions

View File

@ -1,6 +1,6 @@
plugins { plugins {
id 'java' 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' id 'io.spring.dependency-management' version '1.1.6'
} }

View File

@ -1,5 +1,6 @@
package de.w665.biblenotes.config; package de.w665.biblenotes.config;
import de.w665.biblenotes.rest.security.JwtAuthenticationFilter;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer; import org.springframework.security.config.Customizer;

View File

@ -10,9 +10,14 @@ import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.cglib.core.Local;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service; 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; import java.util.Optional;
@Slf4j @Slf4j
@ -54,45 +59,6 @@ public class RethinkDBService {
log.debug("Database " + config.getDatabase() + " already exists. Error: " + e.getClass().getSimpleName()); 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 // rethinkdb check if table users exists
try { try {
r.db(config.getDatabase()).tableCreate("users").run(connection).stream(); r.db(config.getDatabase()).tableCreate("users").run(connection).stream();
@ -136,6 +102,9 @@ public class RethinkDBService {
private void initializeAdminUser() { private void initializeAdminUser() {
Optional<User> adminUser = userRepository.retrieveUserByUsername("admin"); Optional<User> adminUser = userRepository.retrieveUserByUsername("admin");
if(adminUser.isEmpty()) { if(adminUser.isEmpty()) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss.SSSXXX");
ZonedDateTime now = ZonedDateTime.now();
User user = new User(); User user = new User();
user.setUsername(defaultUsername); user.setUsername(defaultUsername);
user.setPassword(passwordEncoder.encode(defaultPassword)); user.setPassword(passwordEncoder.encode(defaultPassword));

View File

@ -2,6 +2,8 @@ package de.w665.biblenotes.model;
import lombok.*; import lombok.*;
import java.time.LocalDateTime;
@Getter @Getter
@Setter @Setter
@ToString @ToString

View File

@ -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<Object> 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<String, Object> 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);
}
}

View File

@ -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 {
}

View File

@ -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;
}

View File

@ -1,11 +1,13 @@
package de.w665.biblenotes.rest.security; package de.w665.biblenotes.rest.security;
import de.w665.biblenotes.service.AuthenticationService;
import jakarta.servlet.FilterChain; import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;

View File

@ -1,5 +1,13 @@
package de.w665.biblenotes.service; 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 jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;

View File

@ -1 +1,14 @@
spring.application.name=biblenotes 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