Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SECRET_ACCESS_TOKEN_KEY=AuthSecretKey
SECRET_REFRESH_TOKEN_KEY=RefreshTokenKey
RATE_LIMIT_PER_SECOND=10
RESOURCE_LIMIT_PER_DAY=60
8 changes: 8 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 0 additions & 14 deletions .vscode/README.md

This file was deleted.

2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<module>use-core</module>
<module>use-gui</module>
<module>use-assembly</module>
<module>use-api</module>
<module>secure-use-api</module>
</modules>

<properties>
Expand Down
Binary file added secure-use-api/.DS_Store
Binary file not shown.
File renamed without changes.
File renamed without changes.
99 changes: 92 additions & 7 deletions use-api/pom.xml → secure-use-api/pom.xml
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>use</artifactId>
<groupId>org.tzi.use</groupId>
<version>7.1.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>use-api</artifactId>

<artifactId>secure-use-api</artifactId>

<properties>
<maven.compiler.source>21</maven.compiler.source>
Expand All @@ -23,7 +22,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.1.5</version>
<version>3.5.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down Expand Up @@ -84,7 +83,7 @@
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version> <!-- or the latest version -->
<version>2.8.14</version> <!-- or the latest version -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down Expand Up @@ -131,11 +130,93 @@
<version>7.1.1</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>


<!-- ######## -->
<!-- Security -->
<!-- ######## -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>de.mkammerer</groupId>
<artifactId>argon2-jvm</artifactId>
<version>2.7</version>
</dependency>

<!-- H2 Database Dependency (In memory for testing) -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.1.0</version>
</dependency>

<!-- RateLimiter -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>

<!-- JWT Library -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.2.1</version>
</dependency>

<!-- .env Library -->
<dependency>
<groupId>io.github.cdimascio</groupId>
<artifactId>dotenv-java</artifactId>
<version>2.0.0</version>
</dependency>

<!-- json Library -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.13.2</version>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -181,6 +262,9 @@
<compilerArg>
-Amapstruct.defaultComponentModel=spring
</compilerArg>
<compilerArg>
-parameters
</compilerArg>
</compilerArgs>
</configuration>
</plugin>
Expand Down Expand Up @@ -251,4 +335,5 @@
<!-- </plugin>-->
</plugins>
</build>

</project>
Binary file added secure-use-api/src/.DS_Store
Binary file not shown.
Binary file added secure-use-api/src/main/.DS_Store
Binary file not shown.
Binary file added secure-use-api/src/main/java/.DS_Store
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class UseWebAPIApplication {
public static void main(String[] args) {
SpringApplication.run(UseWebAPIApplication.class, args);
}
}
public class SecureUseApi {
public static void main(String[] args) {
SpringApplication.run(SecureUseApi.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.tzi.use.api_security.exceptions;

import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {

ExceptionResponse exceptionResponse = new ExceptionResponse(HttpStatus.UNAUTHORIZED, null, "");

exceptionResponse.writeToResponse(response, request);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.tzi.use.api_security.exceptions;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {

@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
HttpHeaders headers, HttpStatusCode status, WebRequest request) {

Map<String, String> errors = new HashMap<>();

ex.getBindingResult().getFieldErrors()
.forEach(error -> errors.put(error.getField(), error.getDefaultMessage()));

ExceptionResponse exceptionResponse = new ExceptionResponse(HttpStatus.BAD_REQUEST, errors,
request.getDescription(false));

// Headers for the response
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add("content-type", "application/problem+json");

// Using ExceptionResponseRecord here because else the whole stack trace of
// parent class RuntimeError is included which would give a tone of server
// information to the client
return ResponseEntity
.status(exceptionResponse.getHttpStatus())
.headers(responseHeaders)
.body(exceptionResponse.toExceptionResponseRecord());
}

public ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
WebRequest request) {

Map<String, String> errors = new HashMap<>();

ex.getBindingResult().getFieldErrors()
.forEach(error -> errors.put(error.getField(), error.getDefaultMessage()));

ExceptionResponse exceptionResponse = new ExceptionResponse(HttpStatus.BAD_REQUEST, errors,
request.getDescription(false));

System.out.println(exceptionResponse);

// Using ExceptionResponseRecord here because else the whole stack trace of
// parent class RuntimeError is included which would give a tone of server
// information to the client
return new ResponseEntity<>(exceptionResponse.toExceptionResponseRecord(),
exceptionResponse.getHttpStatus());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.tzi.use.api_security.exceptions;

import java.io.IOException;
import java.time.Instant;
import org.springframework.http.HttpStatus;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class ExceptionResponse extends RuntimeException {

public record ExceptionResponseRecord(Instant timestamp, String title, int code, Object message, String details) {
}

private final Instant timestamp;
private final String title;
private final int code;
private final Object message;
private final String details;

public ExceptionResponse(Instant timestamp, String title, int code, Object message, String details) {
this.timestamp = timestamp;
this.title = title;
this.code = code;
this.message = message;
this.details = details;
}

public ExceptionResponse(HttpStatus httpStatus, Object message, String details) {
this.timestamp = Instant.now();
this.title = httpStatus.getReasonPhrase();
this.code = httpStatus.value();
this.message = message;
this.details = details;
}

public HttpStatus getHttpStatus() {
return HttpStatus.valueOf(this.code);
}

public void writeToResponse(HttpServletResponse response, HttpServletRequest request) throws IOException {
response.setStatus(this.code);

response.setHeader("content-type", "application/problem+json");

response.getWriter().write(String.format(
"{\"timestamp\": \"%s\", \"title\": \"%s\", \"code\": %d, \"message\":\"%s\", \"details\": \"%s\"}",
this.timestamp, this.title, this.code,
this.message, this.details));

response.getWriter().flush();
}

public ExceptionResponseRecord toExceptionResponseRecord() {
return new ExceptionResponseRecord(this.timestamp, this.title, this.code, this.message, this.details);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.tzi.use.api_security.exceptions;

public class Exceptions {
public static class UserAlreadyExists extends RuntimeException {
public UserAlreadyExists(String message) {
super(message);
}
}

public static class InvalidException extends RuntimeException {
public InvalidException(String message) {
super(message);
}
}

public static class ExpiredException extends RuntimeException {
public ExpiredException(String message) {
super(message);
}
}
}
Loading