Add: all of Huertos but controllers (jwt verification, MSR model, etc). Add: RS256 to global JWT handling
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.apt.aptEnabled=false
|
||||
@@ -1,9 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
|
||||
org.eclipse.jdt.core.compiler.processAnnotations=disabled
|
||||
org.eclipse.jdt.core.compiler.release=disabled
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
@@ -1,4 +0,0 @@
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
||||
@@ -9,11 +9,74 @@
|
||||
</parent>
|
||||
<artifactId>backlib</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>25</maven.compiler.source>
|
||||
<maven.compiler.target>25</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring Boot -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mariadb.jdbc</groupId>
|
||||
<artifactId>mariadb-java-client</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.validation</groupId>
|
||||
<artifactId>jakarta.validation-api</artifactId>
|
||||
<version>3.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>8.0.0.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.42</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- JWT -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-api</artifactId>
|
||||
<version>0.11.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-impl</artifactId>
|
||||
<version>0.11.5</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-jackson</artifactId>
|
||||
<version>0.11.5</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.miarma</groupId>
|
||||
<artifactId>backlib</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.miarma.backlib.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
@Configuration
|
||||
public class SecurityCommonConfig {
|
||||
@Bean
|
||||
public AuthenticationManager authManager(HttpSecurity http) throws Exception {
|
||||
return http.getSharedObject(AuthenticationManagerBuilder.class)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder(12);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package net.miarma.backlib.dto;
|
||||
|
||||
public record ChangeAvatarRequest(String avatar) {}
|
||||
@@ -4,42 +4,7 @@ import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
public class ChangePasswordRequest {
|
||||
|
||||
@NotBlank
|
||||
private String oldPassword;
|
||||
|
||||
@NotBlank
|
||||
private String newPassword;
|
||||
|
||||
@NotNull
|
||||
@Min(0)
|
||||
private Byte serviceId;
|
||||
|
||||
public String getOldPassword() {
|
||||
return oldPassword;
|
||||
}
|
||||
|
||||
public void setOldPassword(String oldPassword) {
|
||||
this.oldPassword = oldPassword;
|
||||
}
|
||||
|
||||
public String getNewPassword() {
|
||||
return newPassword;
|
||||
}
|
||||
|
||||
public void setNewPassword(String newPassword) {
|
||||
this.newPassword = newPassword;
|
||||
}
|
||||
|
||||
public Byte getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
|
||||
public void setServiceId(Byte serviceId) {
|
||||
this.serviceId = serviceId;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public record ChangePasswordRequest(@NotBlank String oldPassword,
|
||||
@NotBlank String newPassword,
|
||||
@NotBlank Byte serviceId) {}
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package net.miarma.backlib.dto;
|
||||
|
||||
public record ChangeRoleRequest(Byte role) {
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package net.miarma.backlib.dto;
|
||||
|
||||
public record ChangeStatusRequest(Byte status) {}
|
||||
@@ -2,36 +2,6 @@ package net.miarma.backlib.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class LoginRequest {
|
||||
@NotBlank
|
||||
private String username;
|
||||
|
||||
@NotBlank
|
||||
private String password;
|
||||
|
||||
private Byte serviceId;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public Byte getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
|
||||
public void setServiceId(Byte serviceId) {
|
||||
this.serviceId = serviceId;
|
||||
}
|
||||
}
|
||||
public record LoginRequest(@NotBlank String username,
|
||||
@NotBlank String password,
|
||||
Byte serviceId) {}
|
||||
|
||||
@@ -1,37 +1,5 @@
|
||||
package net.miarma.backlib.dto;
|
||||
|
||||
public class LoginResponse {
|
||||
private String token;
|
||||
private UserDto user;
|
||||
private CredentialDto account;
|
||||
|
||||
public LoginResponse(String token, UserDto user, CredentialDto account) {
|
||||
this.token = token;
|
||||
this.user = user;
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public UserDto getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(UserDto user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public CredentialDto getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
public void setAccount(CredentialDto account) {
|
||||
this.account = account;
|
||||
}
|
||||
}
|
||||
public record LoginResponse(String token,
|
||||
UserDto user,
|
||||
CredentialDto account) {}
|
||||
@@ -1,41 +1,9 @@
|
||||
package net.miarma.backlib.dto;
|
||||
|
||||
public class RegisterRequest {
|
||||
private String username;
|
||||
private String email;
|
||||
private String password;
|
||||
private String displayName;
|
||||
private Byte serviceId;
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
public Byte getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
public void setServiceId(Byte serviceId) {
|
||||
this.serviceId = serviceId;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public record RegisterRequest(@NotBlank String username,
|
||||
String email,
|
||||
@NotBlank String password,
|
||||
@NotBlank String displayName,
|
||||
Byte serviceId) {}
|
||||
@@ -0,0 +1,4 @@
|
||||
package net.miarma.backlib.dto;
|
||||
|
||||
public record UserExistsResponse(boolean exists) {
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package net.miarma.backlib.security;
|
||||
|
||||
import io.jsonwebtoken.*;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
public class JwtService {
|
||||
|
||||
@Value("${jwt.private-key-path}")
|
||||
private String privateKeyPath;
|
||||
|
||||
@Value("${jwt.public-key-path}")
|
||||
private String publicKeyPath;
|
||||
|
||||
@Value("${jwt.expiration-ms}")
|
||||
private long expiration;
|
||||
|
||||
private PrivateKey privateKey;
|
||||
private PublicKey publicKey;
|
||||
|
||||
@PostConstruct
|
||||
public void init() throws Exception {
|
||||
System.out.println("user.name = " + System.getProperty("user.name"));
|
||||
System.out.println("user.home = " + System.getProperty("user.home"));
|
||||
System.out.println("privateKeyPath = " + privateKeyPath);
|
||||
|
||||
this.privateKey = loadPrivateKey(privateKeyPath);
|
||||
this.publicKey = loadPublicKey(publicKeyPath);
|
||||
}
|
||||
|
||||
private PrivateKey loadPrivateKey(String path) throws Exception {
|
||||
String pem = Files.readString(Path.of(path));
|
||||
pem = pem.replace("-----BEGIN PRIVATE KEY-----", "")
|
||||
.replace("-----END PRIVATE KEY-----", "")
|
||||
.replaceAll("\\s", "");
|
||||
|
||||
byte[] decoded = Base64.getDecoder().decode(pem);
|
||||
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded);
|
||||
KeyFactory kf = KeyFactory.getInstance("RSA");
|
||||
return kf.generatePrivate(spec);
|
||||
}
|
||||
|
||||
private PublicKey loadPublicKey(String path) throws Exception {
|
||||
String pem = Files.readString(Path.of(path));
|
||||
pem = pem.replace("-----BEGIN PUBLIC KEY-----", "")
|
||||
.replace("-----END PUBLIC KEY-----", "")
|
||||
.replaceAll("\\s", "");
|
||||
|
||||
byte[] decoded = Base64.getDecoder().decode(pem);
|
||||
X509EncodedKeySpec spec = new X509EncodedKeySpec(decoded);
|
||||
KeyFactory kf = KeyFactory.getInstance("RSA");
|
||||
return kf.generatePublic(spec);
|
||||
}
|
||||
|
||||
public String generateToken(UUID userId, Byte serviceId) {
|
||||
Date now = new Date();
|
||||
Date exp = new Date(now.getTime() + expiration);
|
||||
|
||||
return Jwts.builder()
|
||||
.setSubject(userId.toString())
|
||||
.claim("service", serviceId)
|
||||
.setIssuedAt(now)
|
||||
.setExpiration(exp)
|
||||
.signWith(privateKey, SignatureAlgorithm.RS256)
|
||||
.compact();
|
||||
}
|
||||
|
||||
public boolean validateToken(String token) {
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(publicKey).build().parseClaimsJws(token);
|
||||
return true;
|
||||
} catch (JwtException | IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public UUID getUserId(String token) {
|
||||
Claims claims = Jwts.parserBuilder().setSigningKey(publicKey).build().parseClaimsJws(token).getBody();
|
||||
return UUID.fromString(claims.getSubject());
|
||||
}
|
||||
|
||||
public Byte getServiceId(String token) {
|
||||
Claims claims = Jwts.parserBuilder().setSigningKey(publicKey).build().parseClaimsJws(token).getBody();
|
||||
return ((Number) claims.get("service")).byteValue();
|
||||
}
|
||||
|
||||
public Date getExpiration(String token) {
|
||||
Claims claims = Jwts.parserBuilder().setSigningKey(publicKey).build().parseClaimsJws(token).getBody();
|
||||
return claims.getExpiration();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
Manifest-Version: 1.0
|
||||
Build-Jdk-Spec: 21
|
||||
Created-By: Maven Integration for Eclipse
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#Generated by Maven Integration for Eclipse
|
||||
#Sun Jan 18 04:49:28 CET 2026
|
||||
artifactId=backlib
|
||||
groupId=net.miarma
|
||||
m2e.projectLocation=/home/jomaa/git/miarma-backend/backlib
|
||||
m2e.projectName=backlib
|
||||
version=1.0.0
|
||||
@@ -1,19 +0,0 @@
|
||||
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>net.miarma</groupId>
|
||||
<artifactId>backend</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<artifactId>backlib</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>jakarta.validation</groupId>
|
||||
<artifactId>jakarta.validation-api</artifactId>
|
||||
<version>3.1.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
Reference in New Issue
Block a user