Переименовал package, порефакторил юзеров

This commit is contained in:
kirillius 2025-12-26 06:12:03 +03:00
parent e29286cce3
commit 8e2412f36a
46 changed files with 212 additions and 168 deletions

View File

@ -1,4 +1,4 @@
package ru.kirillius.XCP.api.Commons;
package ru.kirillius.XCP.Commons;
import java.io.File;

View File

@ -1,4 +1,4 @@
package ru.kirillius.XCP.api.Commons;
package ru.kirillius.XCP.Commons;
import java.io.IOException;

View File

@ -1,4 +1,6 @@
package ru.kirillius.XCP.api.Commons;
package ru.kirillius.XCP.Commons;
import ru.kirillius.XCP.Security.HashUtility;
public interface Context {
Config getConfig();
@ -8,4 +10,6 @@ public interface Context {
<S extends Service> S getService(Class<S> serviceClass);
void shutdown();
HashUtility getHashUtility();
}

View File

@ -1,4 +1,4 @@
package ru.kirillius.XCP.api.Commons;
package ru.kirillius.XCP.Commons;
import java.io.Closeable;

View File

@ -1,4 +1,4 @@
package ru.kirillius.XCP.api.Commons;
package ru.kirillius.XCP.Commons;
import java.io.Closeable;

View File

@ -1,4 +1,4 @@
package ru.kirillius.XCP.api.Commons;
package ru.kirillius.XCP.Commons;
import java.util.stream.Stream;

View File

@ -1,4 +1,4 @@
package ru.kirillius.XCP.api.Data;
package ru.kirillius.XCP.Data;
@Deprecated
public interface DataTransferProtocol {

View File

@ -1,4 +1,4 @@
package ru.kirillius.XCP.api.Data;
package ru.kirillius.XCP.Data;
public interface PollSettings {
int getMaxValueCount();

View File

@ -1,4 +1,4 @@
package ru.kirillius.XCP.api.Data;
package ru.kirillius.XCP.Data;
@Deprecated
public interface ValueModifier {

View File

@ -1,4 +1,4 @@
package ru.kirillius.XCP.api.Data;
package ru.kirillius.XCP.Data;
import tools.jackson.databind.node.ObjectNode;

View File

@ -0,0 +1,8 @@
package ru.kirillius.XCP.Persistence.Entities;
import ru.kirillius.XCP.Persistence.NodeEntity;
public interface Group extends NodeEntity {
String getIcon();
void setIcon(String icon);
}

View File

@ -0,0 +1,13 @@
package ru.kirillius.XCP.Persistence.Entities;
import ru.kirillius.XCP.Data.PollSettings;
import ru.kirillius.XCP.Persistence.IOEntity;
import ru.kirillius.XCP.Persistence.NodeEntity;
public interface Input extends IOEntity, NodeEntity {
PollSettings getPollSettings();
void setPollSettings(PollSettings pollSettings);
}

View File

@ -0,0 +1,7 @@
package ru.kirillius.XCP.Persistence.Entities;
import ru.kirillius.XCP.Persistence.IOEntity;
import ru.kirillius.XCP.Persistence.NodeEntity;
public interface Output extends IOEntity, NodeEntity {
}

View File

@ -1,11 +1,13 @@
package ru.kirillius.XCP.api.Persistence.Entities;
package ru.kirillius.XCP.Persistence.Entities;
import ru.kirillius.XCP.api.Persistence.PersistenceEntity;
import ru.kirillius.XCP.api.Security.UserRole;
import ru.kirillius.XCP.Persistence.PersistenceEntity;
import ru.kirillius.XCP.Security.UserRole;
import tools.jackson.databind.node.ObjectNode;
public interface User extends PersistenceEntity {
void changePassword(String newPass);
void setPassword(String password);
boolean verifyPassword(String password);
String getLogin();

View File

@ -1,7 +1,7 @@
package ru.kirillius.XCP.api.Persistence;
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.api.Data.DataTransferProtocol;
import ru.kirillius.XCP.api.Data.ValueModifierSettings;
import ru.kirillius.XCP.Data.DataTransferProtocol;
import ru.kirillius.XCP.Data.ValueModifierSettings;
import java.util.List;

View File

@ -1,6 +1,6 @@
package ru.kirillius.XCP.api.Persistence;
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.api.Persistence.Entities.Group;
import ru.kirillius.XCP.Persistence.Entities.Group;
import tools.jackson.databind.node.ObjectNode;
import java.util.Set;

View File

@ -1,7 +1,7 @@
package ru.kirillius.XCP.api.Persistence;
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.api.Commons.StreamHandler;
import ru.kirillius.XCP.api.Persistence.Entities.Group;
import ru.kirillius.XCP.Commons.StreamHandler;
import ru.kirillius.XCP.Persistence.Entities.Group;
import java.util.Collection;

View File

@ -1,4 +1,4 @@
package ru.kirillius.XCP.api.Persistence;
package ru.kirillius.XCP.Persistence;
import java.util.UUID;

View File

@ -0,0 +1,14 @@
package ru.kirillius.XCP.Persistence.Repositories;
import ru.kirillius.XCP.Commons.StreamHandler;
import ru.kirillius.XCP.Persistence.Entities.Group;
import ru.kirillius.XCP.Persistence.Entities.Input;
import ru.kirillius.XCP.Persistence.NodeRepository;
public interface GroupRepository extends NodeRepository<Input> {
StreamHandler<Group> getChildrenOf(Group dataGroup);
StreamHandler<Group> getChildrenRecursiveOf(Group dataGroup);
Group getRoot();
}

View File

@ -0,0 +1,8 @@
package ru.kirillius.XCP.Persistence.Repositories;
import ru.kirillius.XCP.Persistence.Entities.Input;
import ru.kirillius.XCP.Persistence.NodeRepository;
public interface InputRepository extends NodeRepository<Input> {
}

View File

@ -0,0 +1,8 @@
package ru.kirillius.XCP.Persistence.Repositories;
import ru.kirillius.XCP.Persistence.Entities.Input;
import ru.kirillius.XCP.Persistence.NodeRepository;
public interface OutputRepository extends NodeRepository<Input> {
}

View File

@ -0,0 +1,9 @@
package ru.kirillius.XCP.Persistence.Repositories;
import ru.kirillius.XCP.Persistence.Entities.User;
import ru.kirillius.XCP.Persistence.Repository;
public interface UserRepository extends Repository<User> {
User getByLogin(String login);
}

View File

@ -1,6 +1,6 @@
package ru.kirillius.XCP.api.Persistence;
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.api.Commons.StreamHandler;
import ru.kirillius.XCP.Commons.StreamHandler;
import ru.kirillius.java.utils.events.EventHandler;
import tools.jackson.databind.node.ArrayNode;
import tools.jackson.databind.node.ObjectNode;

View File

@ -1,6 +1,6 @@
package ru.kirillius.XCP.api.Persistence;
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.api.Commons.Service;
import ru.kirillius.XCP.Commons.Service;
public interface RepositoryService extends Service {
<E extends PersistenceEntity> Repository<E> getRepositoryForEntity(Class<E> entityType);

View File

@ -0,0 +1,9 @@
package ru.kirillius.XCP.Security;
public interface HashUtility {
String hash(String password);
default boolean validate(String password, String hash) {
return hash(password).equals(hash);
}
}

View File

@ -1,4 +1,4 @@
package ru.kirillius.XCP.api.Security;
package ru.kirillius.XCP.Security;
import lombok.Getter;

View File

@ -1,8 +0,0 @@
package ru.kirillius.XCP.api.Persistence.Entities;
import ru.kirillius.XCP.api.Persistence.NodeEntity;
public interface Group extends NodeEntity {
String getIcon();
void setIcon(String icon);
}

View File

@ -1,13 +0,0 @@
package ru.kirillius.XCP.api.Persistence.Entities;
import ru.kirillius.XCP.api.Data.PollSettings;
import ru.kirillius.XCP.api.Persistence.IOEntity;
import ru.kirillius.XCP.api.Persistence.NodeEntity;
public interface Input extends IOEntity, NodeEntity {
PollSettings getPollSettings();
void setPollSettings(PollSettings pollSettings);
}

View File

@ -1,7 +0,0 @@
package ru.kirillius.XCP.api.Persistence.Entities;
import ru.kirillius.XCP.api.Persistence.IOEntity;
import ru.kirillius.XCP.api.Persistence.NodeEntity;
public interface Output extends IOEntity, NodeEntity {
}

View File

@ -1,14 +0,0 @@
package ru.kirillius.XCP.api.Persistence.Repositories;
import ru.kirillius.XCP.api.Commons.StreamHandler;
import ru.kirillius.XCP.api.Persistence.Entities.Group;
import ru.kirillius.XCP.api.Persistence.Entities.Input;
import ru.kirillius.XCP.api.Persistence.NodeRepository;
public interface GroupRepository extends NodeRepository<Input> {
StreamHandler<Group> getChildrenOf(Group dataGroup);
StreamHandler<Group> getChildrenRecursiveOf(Group dataGroup);
Group getRoot();
}

View File

@ -1,8 +0,0 @@
package ru.kirillius.XCP.api.Persistence.Repositories;
import ru.kirillius.XCP.api.Persistence.Entities.Input;
import ru.kirillius.XCP.api.Persistence.NodeRepository;
public interface InputRepository extends NodeRepository<Input> {
}

View File

@ -1,8 +0,0 @@
package ru.kirillius.XCP.api.Persistence.Repositories;
import ru.kirillius.XCP.api.Persistence.Entities.Input;
import ru.kirillius.XCP.api.Persistence.NodeRepository;
public interface OutputRepository extends NodeRepository<Input> {
}

View File

@ -1,10 +0,0 @@
package ru.kirillius.XCP.api.Persistence.Repositories;
import ru.kirillius.XCP.api.Persistence.Entities.User;
import ru.kirillius.XCP.api.Persistence.Repository;
public interface UserRepository extends Repository<User> {
User getByLoginAndPassword(String login, String password);
User getByLogin(String login);
}

28
core/pom.xml Normal file
View File

@ -0,0 +1,28 @@
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ru.kirillius</groupId>
<artifactId>XCP</artifactId>
<version>1.0.0.0</version>
</parent>
<artifactId>core</artifactId>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>ru.kirillius</groupId>
<artifactId>api</artifactId>
<version>1.0.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,35 @@
package ru.kirillius.XCP.Security;
import de.mkammerer.argon2.Argon2;
import de.mkammerer.argon2.Argon2Factory;
import lombok.Getter;
public class Argon2HashUtility implements HashUtility {
@Getter
private final static HashUtility instance = new Argon2HashUtility();
private final Argon2 argon2;
public Argon2HashUtility() {
this.argon2 = Argon2Factory.create(
Argon2Factory.Argon2Types.ARGON2id,
16,
32
);
}
@Override
public String hash(String password) {
try {
return argon2.hash(3, 65536, 1, password.toCharArray());
} finally {
argon2.wipeArray(password.toCharArray());
}
}
@Override
public boolean validate(String password, String hash) {
return argon2.verify(hash, password.toCharArray());
}
}

View File

@ -41,6 +41,12 @@
<version>1.0.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ru.kirillius</groupId>
<artifactId>core</artifactId>
<version>1.0.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -5,9 +5,7 @@ import lombok.Getter;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.query.Query;
import ru.kirillius.XCP.api.Commons.StreamHandler;
import ru.kirillius.XCP.api.Persistence.PersistenceEntity;
import ru.kirillius.XCP.api.Persistence.Repository;
import ru.kirillius.XCP.Commons.StreamHandler;
import ru.kirillius.java.utils.events.ConcurrentEventHandler;
import ru.kirillius.java.utils.events.EventHandler;
import tools.jackson.databind.node.ArrayNode;

View File

@ -1,7 +1,5 @@
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.api.Persistence.PersistenceEntity;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

View File

@ -1,6 +1,5 @@
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.api.Persistence.PersistenceEntity;
import tools.jackson.core.JacksonException;
import tools.jackson.core.JsonParser;
import tools.jackson.databind.DeserializationContext;

View File

@ -1,6 +1,5 @@
package ru.kirillius.XCP.Persistence;
import ru.kirillius.XCP.api.Persistence.PersistenceEntity;
import tools.jackson.core.JacksonException;
import tools.jackson.core.JsonGenerator;
import tools.jackson.databind.SerializationContext;

View File

@ -1,7 +1,6 @@
package ru.kirillius.XCP.Persistence;
import lombok.Getter;
import ru.kirillius.XCP.api.Persistence.PersistenceEntity;
import tools.jackson.core.Version;
import tools.jackson.databind.JacksonModule;
import tools.jackson.databind.module.SimpleDeserializers;

View File

@ -1,24 +1,17 @@
package ru.kirillius.XCP.Persistence.Services;
package ru.kirillius.XCP.Persistence.Repositories;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.UuidGenerator;
import ru.kirillius.XCP.Persistence.AbstractRepository;
import ru.kirillius.XCP.Persistence.EntityImplementation;
import ru.kirillius.XCP.Persistence.RepositoryServiceImpl;
import ru.kirillius.XCP.Persistence.*;
import ru.kirillius.XCP.Persistence.Entities.User;
import ru.kirillius.XCP.Security.Argon2HashUtility;
import ru.kirillius.XCP.Security.UserRole;
import ru.kirillius.XCP.Serialization.SerializationUtils;
import ru.kirillius.XCP.api.Persistence.Entities.User;
import ru.kirillius.XCP.api.Persistence.PersistenceEntity;
import ru.kirillius.XCP.api.Persistence.Repositories.UserRepository;
import ru.kirillius.XCP.api.Persistence.Repository;
import ru.kirillius.XCP.api.Security.UserRole;
import tools.jackson.databind.node.ObjectNode;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
@EntityImplementation(UserRepositoryImpl.UserEntity.class)
@ -33,18 +26,6 @@ public class UserRepositoryImpl extends AbstractRepository<User> implements User
return UserRepository.class;
}
@Override
public User getByLoginAndPassword(String login, String password) {
var user = (UserEntity) getByLogin(login);
if (user == null) {
return null;
}
if (user.getPasswordHash().equals(UserEntity.hash(password, user.getPasswordHashSalt()))) {
return user;
}
return null;
}
@Override
public User getByLogin(String login) {
try (var request = buildQueryParametrized("WHERE login = ?1", login)) {
@ -55,7 +36,7 @@ public class UserRepositoryImpl extends AbstractRepository<User> implements User
}
@Entity
@Table(name = "UserEntity")
@Table(name = "Users")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ -84,10 +65,6 @@ public class UserRepositoryImpl extends AbstractRepository<User> implements User
@JsonProperty
private String passwordHash;
@Column(nullable = false)
@JsonProperty
private String passwordHashSalt;
@Column(nullable = false)
@JsonProperty
@Enumerated(EnumType.STRING)
@ -99,32 +76,19 @@ public class UserRepositoryImpl extends AbstractRepository<User> implements User
@JsonProperty
private ObjectNode values = SerializationUtils.EmptyObject();
public static String hash(String data, String salt) {
String generatedPassword;
MessageDigest md;
try {
md = MessageDigest.getInstance("SHA-512");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
md.update(salt.getBytes(StandardCharsets.UTF_8));
var bytes = md.digest(data.getBytes(StandardCharsets.UTF_8));
var sb = new StringBuilder();
for (byte aByte : bytes) {
sb.append(Integer.toString((aByte & 0xff) + 0x100, 16).substring(1));
}
generatedPassword = sb.toString();
return generatedPassword;
}
public void changePassword(String newPass) {
passwordHashSalt = java.util.UUID.randomUUID().toString();
passwordHash = hash(newPass, passwordHashSalt);
}
@Override
public Class<? extends PersistenceEntity> getBaseType() {
return User.class;
}
@Override
public void setPassword(String password) {
passwordHash = Argon2HashUtility.getInstance().hash(password);
}
@Override
public boolean verifyPassword(String password) {
return Argon2HashUtility.getInstance().validate(password, passwordHash);
}
}
}

View File

@ -4,10 +4,7 @@ import lombok.Getter;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import ru.kirillius.XCP.api.Commons.Context;
import ru.kirillius.XCP.api.Persistence.PersistenceEntity;
import ru.kirillius.XCP.api.Persistence.Repository;
import ru.kirillius.XCP.api.Persistence.RepositoryService;
import ru.kirillius.XCP.Commons.Context;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.json.JsonMapper;
@ -24,8 +21,8 @@ public final class RepositoryServiceImpl implements RepositoryService {
private DatabaseConfiguration databaseConfiguration;
private final Map<Class<? extends Repository<?>>, Repository<?>> repositoryBindings = new ConcurrentHashMap<>();
private final Map<Class<? extends PersistenceEntity>, Class<? extends Repository<?>>> entityBindings = new ConcurrentHashMap<>();
private final Collection<Class<? extends AbstractRepository<?>>> managedRepositoryClasses;
private Context context;
public RepositoryServiceImpl(DatabaseConfiguration databaseConfiguration, Collection<Class<? extends AbstractRepository<?>>> repositoryImplClasses) {
managedRepositoryClasses = repositoryImplClasses;
@ -88,6 +85,7 @@ public final class RepositoryServiceImpl implements RepositoryService {
throw new IllegalStateException("Initialized already");
}
initialized = true;
this.context = context;
if (databaseConfiguration == null) {
loadDatabaseConfig(new H2DatabaseInFileConfiguration(context.getConfig().getDatabaseFile()));
}

View File

@ -1,7 +1,7 @@
import ru.kirillius.XCP.api.Commons.Config;
import ru.kirillius.XCP.api.Commons.ConfigManager;
import ru.kirillius.XCP.api.Commons.Context;
import ru.kirillius.XCP.api.Commons.Service;
import ru.kirillius.XCP.Commons.Config;
import ru.kirillius.XCP.Commons.ConfigManager;
import ru.kirillius.XCP.Commons.Context;
import ru.kirillius.XCP.Commons.Service;
public class TestContext implements Context {
@Override

View File

@ -6,9 +6,7 @@ import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.UuidGenerator;
import org.junit.jupiter.api.Test;
import ru.kirillius.XCP.api.Commons.Context;
import ru.kirillius.XCP.api.Persistence.PersistenceEntity;
import ru.kirillius.XCP.api.Persistence.Repository;
import ru.kirillius.XCP.Commons.Context;
import java.io.IOException;
import java.util.*;

View File

@ -11,6 +11,7 @@
<modules>
<module>api</module>
<module>database</module>
<module>core</module>
</modules>
<properties>
@ -79,6 +80,13 @@
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/de.mkammerer/argon2-jvm -->
<dependency>
<groupId>de.mkammerer</groupId>
<artifactId>argon2-jvm</artifactId>
<version>2.12</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.assertj/assertj-core -->
<dependency>
<groupId>org.assertj</groupId>